Skip to content

Commit 4cc1abe

Browse files
authored
Fix typo of register -> registers crashes DXC with segfault (#7729)
Fix crash when parsing mistyped HLSL semantics (e.g. `registers()`). Add diagnostic for unexpected '(' in semantic annotation and skip safely. Add tests for common misspellings/macros that previously caused a segfault. Fixes #6599
1 parent 85f7653 commit 4cc1abe

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

tools/clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,8 @@ def warn_hlsl_effect_technique : Warning <
10251025
def warn_hlsl_semantic_identifier_collision : Warning <
10261026
"'%0' interpreted as semantic; previous definition(s) ignored">,
10271027
InGroup< HLSLSemanticIdentifierCollision >;
1028+
def err_hlsl_expected_hlsl_attribute : Error <
1029+
"Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?">;
10281030
def err_hlsl_enum : Error<
10291031
"enum is unsupported in HLSL before 2017">;
10301032
def warn_hlsl_new_feature : Warning <

tools/clang/lib/Parse/ParseDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,16 @@ bool Parser::MaybeParseHLSLAttributes(std::vector<hlsl::UnusualAnnotation *> &ta
633633
Actions.DiagnoseSemanticDecl(pUA);
634634
ConsumeToken(); // consume semantic
635635

636+
// Likely a misspell of register(), packoffset() or a mismatching macro:
637+
// both registr() and packofset() would cause a crash without this fix.
638+
639+
if (Tok.is(tok::l_paren)) {
640+
Diag(Tok.getLocation(), diag::err_hlsl_expected_hlsl_attribute);
641+
ConsumeParen();
642+
SkipUntil(tok::r_paren, StopAtSemi); // skip through )
643+
return true;
644+
}
645+
636646
target.push_back(pUA);
637647
}
638648
else {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %dxc -T lib_6_3 -verify %s
2+
3+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
4+
RWStructuredBuffer<float4> uav1 : registers(u3);
5+
6+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
7+
RWStructuredBuffer<float4> uav2 : registers(outer_space);
8+
9+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
10+
RWStructuredBuffer<float4> uav3 : UNDEFINED_MACRO1(u3);
11+
12+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
13+
RWStructuredBuffer<float4> uav4 : UNDEFINED_MACRO(something, more, complex);
14+
15+
cbuffer buf {
16+
17+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
18+
float4 v0 : packoffsets(c0);
19+
20+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
21+
float4 v1 : packoffsets(invalid_syntax);
22+
23+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
24+
float v2 : UNDEFINED_MACRO2(c0.w);
25+
26+
// expected-error@+1 {{Unexpected '(' in semantic annotation. Did you mean 'packoffset()' or 'register()'?}}
27+
float v3 : UNDEFINED_MACRO(something, more, complex);
28+
};
29+
30+
[shader("pixel")]
31+
float4 main(): SV_Target
32+
{
33+
uav1[0] = v0;
34+
uav2[0] = v1;
35+
uav3[0] = v2;
36+
uav4[0] = v3;
37+
return 0.xxxx;
38+
}

0 commit comments

Comments
 (0)