Skip to content

Commit 6c48b1f

Browse files
committed
review: add constraint on magnitude of signed integer
1 parent 03aa01a commit 6c48b1f

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
878878
assert(Literal.isIntegerLiteral() &&
879879
"NumSpelling can only consist of digits");
880880

881-
llvm::APSInt Val = llvm::APSInt(32, false);
881+
llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true);
882882
if (Literal.GetIntegerValue(Val)) {
883883
// Report that the value has overflowed
884884
PP.getDiagnostics().Report(CurToken.TokLoc,
@@ -901,8 +901,12 @@ std::optional<int32_t> RootSignatureParser::handleIntLiteral(bool Negated) {
901901
assert(Literal.isIntegerLiteral() &&
902902
"NumSpelling can only consist of digits");
903903

904-
llvm::APSInt Val = llvm::APSInt(32, true);
905-
if (Literal.GetIntegerValue(Val)) {
904+
llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true);
905+
// GetIntegerValue will overwrite Val from the parsed Literal and return
906+
// true if it overflows as a 32-bit unsigned int. Then check that it also
907+
// doesn't overflow as a signed 32-bit int.
908+
int64_t MaxMagnitude = -static_cast<int64_t>(std::numeric_limits<int32_t>::min());
909+
if (Literal.GetIntegerValue(Val) || MaxMagnitude < Val.getExtValue()) {
906910
// Report that the value has overflowed
907911
PP.getDiagnostics().Report(CurToken.TokLoc,
908912
diag::err_hlsl_number_literal_overflow)

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,28 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidLexOverflowedNumberTest) {
774774
ASSERT_TRUE(Consumer->isSatisfied());
775775
}
776776

777+
TEST_F(ParseHLSLRootSignatureTest, InvalidParseOverflowedNegativeNumberTest) {
778+
// This test will check that parsing fails due to a unsigned integer having
779+
// too large of a magnitude to be interpreted as its negative
780+
const llvm::StringLiteral Source = R"cc(
781+
StaticSampler(s0, mipLODBias = -4294967295)
782+
)cc";
783+
784+
TrivialModuleLoader ModLoader;
785+
auto PP = createPP(Source, ModLoader);
786+
auto TokLoc = SourceLocation();
787+
788+
hlsl::RootSignatureLexer Lexer(Source, TokLoc);
789+
SmallVector<RootElement> Elements;
790+
hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
791+
792+
// Test correct diagnostic produced
793+
Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
794+
ASSERT_TRUE(Parser.parse());
795+
796+
ASSERT_TRUE(Consumer->isSatisfied());
797+
}
798+
777799
TEST_F(ParseHLSLRootSignatureTest, InvalidLexOverflowedFloatTest) {
778800
// This test will check that the lexing fails due to a float overflow
779801
const llvm::StringLiteral Source = R"cc(

0 commit comments

Comments
 (0)