Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,10 @@ def err_not_integral_type_bitfield : Error<
"bit-field %0 has non-integral type %1">;
def err_not_integral_type_anon_bitfield : Error<
"anonymous bit-field has non-integral type %0">;
def err_spirv_boolean_bitfield_in_type
: Error<"type %0 contains a boolean bitfield which is not supported for "
"variables that are not externally visible when "
"targeting SPIR-V">;
def err_member_function_initialization : Error<
"initializer on function does not look like a pure-specifier">;
def err_non_virtual_pure : Error<
Expand Down
27 changes: 27 additions & 0 deletions tools/clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16072,6 +16072,33 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth,
result = false;
}
}
if (getLangOpts().SPIRV) {
// See https://github.com/microsoft/DirectXShaderCompiler/issues/7790.
// Booleans are an abstract type in SPIR-V and cannot be used as a
// bitfield container. In variables that are externally visible, the
// boolean is turned into an integer, so this is not a problem.
if (isLocalVar || isParameter || (isGlobal && isStatic)) {
QualType T = qt;
if (!T->isDependentType()) {
if (const auto *AT = T->getAsArrayTypeUnsafe())
T = AT->getElementType();

if (const RecordType *RT = T->getAs<RecordType>()) {
const RecordDecl *RD = RT->getDecl();
for (const FieldDecl *FD : RD->fields()) {
if (FD->isBitField() && FD->getType()->isBooleanType()) {
Diag(D.getIdentifierLoc(),
diag::err_spirv_boolean_bitfield_in_type)
<< T;
D.setInvalidType();
return false;
}
}
}
}
}
}

#endif // ENABLE_SPIRV_CODEGEN
// SPIRV change ends

Expand Down
29 changes: 29 additions & 0 deletions tools/clang/test/SemaHLSL/spirv-boolean-bitfield.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: %dxc -T cs_6_0 -E main -spirv -verify %s

struct Test {
bool a: 1;
int b;
};

// This should not have an error because it is externally visible.
RWStructuredBuffer<Test> buffer;
Test g_non_static_global;

// Global static variable
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}}

// Global static array
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}}

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}}

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}}

[numthreads(1, 1, 1)]
void main() {
// Local variable
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}}

// Local array
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}}
}