Skip to content

Commit 603aeac

Browse files
committed
add basic integer range validations
1 parent 1228e74 commit 603aeac

File tree

3 files changed

+95
-1
lines changed

3 files changed

+95
-1
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13077,6 +13077,8 @@ def err_invalid_hlsl_resource_type: Error<
1307713077
def err_hlsl_spirv_only: Error<"%0 is only available for the SPIR-V target">;
1307813078
def err_hlsl_vk_literal_must_contain_constant: Error<"the argument to vk::Literal must be a vk::integral_constant">;
1307913079

13080+
def err_hlsl_invalid_rootsig_value : Error<"value must be in the range [%0, %1]">;
13081+
1308013082
def subst_hlsl_format_ranges: TextSubstitution<
1308113083
"%select{t|u|b|s}0[%1;%select{%3]|unbounded)}2">;
1308213084

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "llvm/Support/DXILABI.h"
4545
#include "llvm/Support/ErrorHandling.h"
4646
#include "llvm/TargetParser/Triple.h"
47+
#include <cmath>
4748
#include <cstddef>
4849
#include <iterator>
4950
#include <utility>
@@ -1083,6 +1084,63 @@ void SemaHLSL::ActOnFinishRootSignatureDecl(
10831084

10841085
bool SemaHLSL::handleRootSignatureElements(
10851086
ArrayRef<hlsl::RootSignatureElement> Elements) {
1087+
// Define some common error handling functions
1088+
bool HadError = false;
1089+
auto ReportError = [this, &HadError](SourceLocation Loc, uint32_t LowerBound,
1090+
uint32_t UpperBound) {
1091+
HadError = true;
1092+
this->Diag(Loc, diag::err_hlsl_invalid_rootsig_value)
1093+
<< LowerBound << UpperBound;
1094+
};
1095+
1096+
auto VerifyRegister = [ReportError](SourceLocation Loc, uint32_t Register) {
1097+
if (!llvm::hlsl::rootsig::verifyRegisterValue(Register))
1098+
ReportError(Loc, 0, 0xfffffffe);
1099+
};
1100+
1101+
auto VerifySpace = [ReportError](SourceLocation Loc, uint32_t Space) {
1102+
if (!llvm::hlsl::rootsig::verifyRegisterSpace(Space))
1103+
ReportError(Loc, 0, 0xffffffef);
1104+
};
1105+
1106+
// Iterate through the elements and do basic validations
1107+
for (const hlsl::RootSignatureElement &RootSigElem : Elements) {
1108+
SourceLocation Loc = RootSigElem.getLocation();
1109+
const llvm::hlsl::rootsig::RootElement &Elem = RootSigElem.getElement();
1110+
if (const auto *Descriptor =
1111+
std::get_if<llvm::hlsl::rootsig::RootDescriptor>(&Elem)) {
1112+
VerifyRegister(Loc, Descriptor->Reg.Number);
1113+
VerifySpace(Loc, Descriptor->Space);
1114+
} else if (const auto *Constants =
1115+
std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
1116+
VerifyRegister(Loc, Constants->Reg.Number);
1117+
VerifySpace(Loc, Constants->Space);
1118+
} else if (const auto *Sampler =
1119+
std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) {
1120+
VerifyRegister(Loc, Sampler->Reg.Number);
1121+
VerifySpace(Loc, Sampler->Space);
1122+
1123+
assert(!std::isnan(Sampler->MaxLOD) && !std::isnan(Sampler->MinLOD) &&
1124+
"By construction, parseFloatParam can't produce a NaN from a "
1125+
"float_literal token");
1126+
1127+
if (16 < Sampler->MaxAnisotropy)
1128+
ReportError(Loc, 0, 16);
1129+
} else if (const auto *Clause =
1130+
std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>(
1131+
&Elem)) {
1132+
VerifyRegister(Loc, Clause->Reg.Number);
1133+
VerifySpace(Loc, Clause->Space);
1134+
1135+
if (!llvm::hlsl::rootsig::verifyNumDescriptors(Clause->NumDescriptors)) {
1136+
// NumDescriptor could techincally be ~0u but that is reserved for
1137+
// unbounded, so the diagnostic will not report that as a valid int
1138+
// value
1139+
ReportError(Loc, 1, 0xfffffffe);
1140+
}
1141+
}
1142+
}
1143+
10861144
using RangeInfo = llvm::hlsl::rootsig::RangeInfo;
10871145
using OverlappingRanges = llvm::hlsl::rootsig::OverlappingRanges;
10881146

@@ -1136,7 +1194,10 @@ bool SemaHLSL::handleRootSignatureElements(
11361194
&Elem)) {
11371195
RangeInfo Info;
11381196
Info.LowerBound = Clause->Reg.Number;
1139-
assert(0 < Clause->NumDescriptors && "Verified as part of TODO(#129940)");
1197+
// Relevant error will have already been reported above and needs to be
1198+
// fixed before we can conduct range analysis, so shortcut error return
1199+
if (Clause->NumDescriptors == 0)
1200+
return true;
11401201
Info.UpperBound = Clause->NumDescriptors == RangeInfo::Unbounded
11411202
? RangeInfo::Unbounded
11421203
: Info.LowerBound + Clause->NumDescriptors -

clang/test/SemaHLSL/RootSignature-err.hlsl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,34 @@ void bad_root_signature_6() {}
3838
// expected-error@+1 {{expected end of stream to denote end of parameters, or, another valid parameter of RootSignature}}
3939
[RootSignature("RootFlags() RootConstants(b0, num32BitConstants = 1))")]
4040
void bad_root_signature_7() {}
41+
42+
// Basic validation of register value and space
43+
44+
// expected-error@+2 {{value must be in the range [0, 4294967294]}}
45+
// expected-error@+1 {{value must be in the range [0, 4294967279]}}
46+
[RootSignature("CBV(b4294967295, space = 4294967280)")]
47+
void basic_validation_0() {}
48+
49+
// expected-error@+2 {{value must be in the range [0, 4294967294]}}
50+
// expected-error@+1 {{value must be in the range [0, 4294967279]}}
51+
[RootSignature("RootConstants(b4294967295, space = 4294967280, num32BitConstants = 1)")]
52+
void basic_validation_1() {}
53+
54+
// expected-error@+2 {{value must be in the range [0, 4294967294]}}
55+
// expected-error@+1 {{value must be in the range [0, 4294967279]}}
56+
[RootSignature("StaticSampler(s4294967295, space = 4294967280)")]
57+
void basic_validation_2() {}
58+
59+
// expected-error@+2 {{value must be in the range [0, 4294967294]}}
60+
// expected-error@+1 {{value must be in the range [0, 4294967279]}}
61+
[RootSignature("DescriptorTable(SRV(t4294967295, space = 4294967280))")]
62+
void basic_validation_3() {}
63+
64+
// expected-error@+2 {{value must be in the range [1, 4294967294]}}
65+
// expected-error@+1 {{value must be in the range [1, 4294967294]}}
66+
[RootSignature("DescriptorTable(UAV(u0, numDescriptors = 0), Sampler(s0, numDescriptors = 0))")]
67+
void basic_validation_4() {}
68+
69+
// expected-error@+1 {{value must be in the range [0, 16]}}
70+
[RootSignature("StaticSampler(s0, maxAnisotropy = 17, mipLODBias = -16.000001)")]
71+
void basic_validation_5() {}

0 commit comments

Comments
 (0)