Skip to content

Commit 211850a

Browse files
committed
review: add constraint on magnitude of signed integer
1 parent c3f4604 commit 211850a

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

clang/lib/Parse/ParseHLSLRootSignature.cpp

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

879-
llvm::APSInt Val = llvm::APSInt(32, false);
879+
llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true);
880880
if (Literal.GetIntegerValue(Val)) {
881881
// Report that the value has overflowed
882882
PP.getDiagnostics().Report(CurToken.TokLoc,
@@ -899,8 +899,13 @@ std::optional<int32_t> RootSignatureParser::handleIntLiteral(bool Negated) {
899899
assert(Literal.isIntegerLiteral() &&
900900
"NumSpelling can only consist of digits");
901901

902-
llvm::APSInt Val = llvm::APSInt(32, true);
903-
if (Literal.GetIntegerValue(Val)) {
902+
llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true);
903+
// GetIntegerValue will overwrite Val from the parsed Literal and return
904+
// true if it overflows as a 32-bit unsigned int. Then check that it also
905+
// doesn't overflow as a signed 32-bit int.
906+
int64_t MaxMagnitude =
907+
-static_cast<int64_t>(std::numeric_limits<int32_t>::min());
908+
if (Literal.GetIntegerValue(Val) || MaxMagnitude < Val.getExtValue()) {
904909
// Report that the value has overflowed
905910
PP.getDiagnostics().Report(CurToken.TokLoc,
906911
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
@@ -803,6 +803,28 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidLexOverflowedNumberTest) {
803803
ASSERT_TRUE(Consumer->isSatisfied());
804804
}
805805

806+
TEST_F(ParseHLSLRootSignatureTest, InvalidParseOverflowedNegativeNumberTest) {
807+
// This test will check that parsing fails due to a unsigned integer having
808+
// too large of a magnitude to be interpreted as its negative
809+
const llvm::StringLiteral Source = R"cc(
810+
StaticSampler(s0, mipLODBias = -4294967295)
811+
)cc";
812+
813+
TrivialModuleLoader ModLoader;
814+
auto PP = createPP(Source, ModLoader);
815+
auto TokLoc = SourceLocation();
816+
817+
hlsl::RootSignatureLexer Lexer(Source, TokLoc);
818+
SmallVector<RootElement> Elements;
819+
hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
820+
821+
// Test correct diagnostic produced
822+
Consumer->setExpected(diag::err_hlsl_number_literal_overflow);
823+
ASSERT_TRUE(Parser.parse());
824+
825+
ASSERT_TRUE(Consumer->isSatisfied());
826+
}
827+
806828
TEST_F(ParseHLSLRootSignatureTest, InvalidLexOverflowedFloatTest) {
807829
// This test will check that the lexing fails due to a float overflow
808830
const llvm::StringLiteral Source = R"cc(

0 commit comments

Comments
 (0)