Open Gordon-F opened 3 years ago
Stull repros: https://godbolt.org/z/e9afnMKh3
In triage today we were unable to figure out why this shader is invalid.
FXC compiles this fine: https://shader-playground.timjones.io/2948b7c0adb063dc3ffe0da392078058
This is a problem likely caused by some custom assignment handling in SemaHLSL circumventing the usual path in clang that would update the incomplete decl type.
It causes this assert during clang CodeGen:
assert(!isIncompleteType() && "This doesn't make sense for incomplete types");
under Ty->isConstantSizeType()
called from CodeGenFunction::EmitAutoVarAlloca
for float _expr13[]
, where the type is incomplete, since it hasn't been set properly from the assignment initialization.
BTW: the shader is invalid because only the gl_Position
field of perVertexStruct
is initialized, and the other uninitialized fields are used. FXC just outputs zero for these uninitialized values, with no warning. Initializing these fields does not make the assert go away.
Note: C++ wouldn't actually support this syntax, requiring {}
for aggregate initializer. HLSL supports array assignment initialization, unlike C++, but breaks in the case where the assignee decl is an incomplete array type. A much more minimal case can be constructed that causes the assert to fire, but does not cause a crash on release (resulting in bad codegen instead).
It is somewhat important to be aware of this case so we can more tightly define what HLSL does for new implementation. Here are some options:
We should also decide whether we would like to deprecate this kind of array assignment in a future language version (since it's unsupported in C++). This assignment makes sense in HLSL because arrays are always by-value aggregates instead of decaying to a pointer.
Apparently, FXC allows and handles this kind of initialization properly, so we could say that the HLSL language can and should support it. Then we could leave this in DXC's backlog as something that could be fixed maybe one day by someone who cares about this scenario.
Here is a minimal repro that:
int array1[1];
int main() : OUT {
int error_expr[] = array1;
return error_expr[0];
}
Reproduces on latest release.
The shader is not valid, generated by work in progress
hlsl-out
backend in naga, butdxc
should be able to parse it without any ICE.