Skip to content

Commit d2f9d80

Browse files
authored
[SPIRV] Add diagnostic for boolean bitfields (#7822)
Adds a diagnostic to flag the use of boolean bitfields in structs when targeting SPIR-V. This is not supported for variables that are not externally visible. This change introduces a new error message in SemaHLSL to detect and report this unsupported usage for: - Local variables - Function parameters - Static global variables A new test file is added to verify the diagnostic is triggered in these cases and not for externally visible global variables. Avoid the segfault reported in #7790.
1 parent 3056ae2 commit d2f9d80

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

tools/clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,10 @@ def err_not_integral_type_bitfield : Error<
13031303
"bit-field %0 has non-integral type %1">;
13041304
def err_not_integral_type_anon_bitfield : Error<
13051305
"anonymous bit-field has non-integral type %0">;
1306+
def err_spirv_boolean_bitfield_in_type
1307+
: Error<"type %0 contains a boolean bitfield which is not supported for "
1308+
"variables that are not externally visible when "
1309+
"targeting SPIR-V">;
13061310
def err_member_function_initialization : Error<
13071311
"initializer on function does not look like a pure-specifier">;
13081312
def err_non_virtual_pure : Error<

tools/clang/lib/Sema/SemaHLSL.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16072,6 +16072,33 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth,
1607216072
result = false;
1607316073
}
1607416074
}
16075+
if (getLangOpts().SPIRV) {
16076+
// See https://github.com/microsoft/DirectXShaderCompiler/issues/7790.
16077+
// Booleans are an abstract type in SPIR-V and cannot be used as a
16078+
// bitfield container. In variables that are externally visible, the
16079+
// boolean is turned into an integer, so this is not a problem.
16080+
if (isLocalVar || isParameter || (isGlobal && isStatic)) {
16081+
QualType T = qt;
16082+
if (!T->isDependentType()) {
16083+
if (const auto *AT = T->getAsArrayTypeUnsafe())
16084+
T = AT->getElementType();
16085+
16086+
if (const RecordType *RT = T->getAs<RecordType>()) {
16087+
const RecordDecl *RD = RT->getDecl();
16088+
for (const FieldDecl *FD : RD->fields()) {
16089+
if (FD->isBitField() && FD->getType()->isBooleanType()) {
16090+
Diag(D.getIdentifierLoc(),
16091+
diag::err_spirv_boolean_bitfield_in_type)
16092+
<< T;
16093+
D.setInvalidType();
16094+
return false;
16095+
}
16096+
}
16097+
}
16098+
}
16099+
}
16100+
}
16101+
1607516102
#endif // ENABLE_SPIRV_CODEGEN
1607616103
// SPIRV change ends
1607716104

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %dxc -T cs_6_0 -E main -spirv -verify %s
2+
3+
struct Test {
4+
bool a: 1;
5+
int b;
6+
};
7+
8+
// This should not have an error because it is externally visible.
9+
RWStructuredBuffer<Test> buffer;
10+
Test g_non_static_global;
11+
12+
// Global static variable
13+
static Test g_t; // expected-error {{type 'Test' contains a boolean bitfield which is not supported for variables that are not externally visible when targeting SPIR-V}}
14+
15+
// Global static array
16+
static Test g_t_arr[2]; // expected-error {{type 'Test' contains a boolean bitfield which is not supported for variables that are not externally visible when targeting SPIR-V}}
17+
18+
void foo(Test p) {} // expected-error {{type 'Test' contains a boolean bitfield which is not supported for variables that are not externally visible when targeting SPIR-V}}
19+
20+
void bar(Test p[2]) {} // expected-error {{type 'Test' contains a boolean bitfield which is not supported for variables that are not externally visible when targeting SPIR-V}}
21+
22+
[numthreads(1, 1, 1)]
23+
void main() {
24+
// Local variable
25+
Test t; // expected-error {{type 'Test' contains a boolean bitfield which is not supported for variables that are not externally visible when targeting SPIR-V}}
26+
27+
// Local array
28+
Test t_arr[2]; // expected-error {{type 'Test' contains a boolean bitfield which is not supported for variables that are not externally visible when targeting SPIR-V}}
29+
}

0 commit comments

Comments
 (0)