DirectXShaderCompiler
DirectXShaderCompiler copied to clipboard
[SPIR-V] Out-of-line initialization of `static const` member arrays of templated types SIGSEGVs
Description
When compiling with -HV 202x -T ps_6_7 -E PSMain it works and produces DXIL, when adding -spirv it SIGSEGVs the compiler.
Steps to Reproduce https://godbolt.org/z/WasWzsq4E
If you strip all my C++ compat code then you have https://godbolt.org/z/dWMfjxza1
Actual Behavior SIGSEGV of the compiler.
I think this is because static outside of the class makes no sense in C++ (and for LLVM), but I cannot use const on its own because I get a different problem.
Environment
- DXC version Latest trunk according to Godbolt
- Host Operating System Linux I guess
Thanks for reporting. Assigning to @cassiebeckley to take a look.
I think this might actually be a parser or Sema bug. The AST I get for this code using -ast-dump is
TranslationUnitDecl 0x561d24809980 <<invalid sloc>> <invalid sloc>
|-ClassTemplateDecl 0x561d248380b0 <<source>:4:1, line:5:8> col:8 GaussLegendreValues
| |-NonTypeTemplateParmDecl 0x561d24837ee0 <line:4:11, col:15> col:15 'int' Order
| |-TemplateTypeParmDecl 0x561d24837f58 <col:22, col:39> col:31 typename float_t
| | `-TemplateArgument type 'float'
| `-CXXRecordDecl 0x561d24837ff8 <line:5:1, col:8> col:8 struct GaussLegendreValues
|-ClassTemplatePartialSpecializationDecl 0x561d248414f0 <line:8:1, line:13:1> line:9:8 struct GaussLegendreValues definition
| |-TemplateArgument integral 2
| |-TemplateArgument type 'type-parameter-0-0'
| |-TemplateTypeParmDecl 0x561d24838338 <line:8:11, col:20> col:20 referenced typename float_t
| |-CXXRecordDecl 0x561d24841778 <line:9:1, col:8> col:8 implicit struct GaussLegendreValues
| |-VarDecl 0x561d248418e8 <line:11:5, col:30> col:26 wi 'const float_t [2]' static
| `-VarDecl 0x561d24841998 <line:12:5, col:30> col:26 xi 'const float_t [2]' static
|-VarDecl 0x561d24841e38 parent 0x561d248414f0 prev 0x561d248418e8 <line:14:1, col:98> col:81 wi 'const float_t [2]' static cinit
| `-InitListExpr 0x561d24841f28 <col:89, col:98> 'void'
| |-FloatingLiteral 0x561d24841ee8 <col:90> 'literal float' 1.000000e+00
| `-FloatingLiteral 0x561d24841f08 <col:95> 'literal float' 1.000000e+00
|-CXXRecordDecl 0x561d24841f78 <line:18:1, line:22:1> line:18:8 referenced struct PSInput definition
| |-CXXRecordDecl 0x561d248420b0 <col:1, col:8> col:8 implicit struct PSInput
| |-FieldDecl 0x561d24842268 <line:20:5, col:12> col:12 position 'float4':'vector<float, 4>'
| | `-SemanticDecl 0x561d248422c0 <col:23> "SV_Position"
| `-FieldDecl 0x561d24842308 <line:21:5, col:12> col:12 referenced color 'float4':'vector<float, 4>'
| `-SemanticDecl 0x561d24842360 <col:23> "COLOR0"
`-FunctionDecl 0x561d248476d8 <line:24:1, line:27:1> line:24:8 PSMain 'float4 (PSInput)'
|-ParmVarDecl 0x561d24847588 <col:15, col:23> col:23 used input 'PSInput'
|-CompoundStmt 0x561d248478b8 <line:25:1, line:27:1>
| `-ReturnStmt 0x561d248478a0 <line:26:5, col:18>
| `-ImplicitCastExpr 0x561d24847888 <col:12, col:18> 'float4':'vector<float, 4>' <LValueToRValue>
| `-MemberExpr 0x561d24847838 <col:12, col:18> 'float4':'vector<float, 4>' lvalue .color 0x561d24842308
| `-DeclRefExpr 0x561d24847810 <col:12> 'PSInput' lvalue ParmVar 0x561d24847588 'input' 'PSInput'
`-SemanticDecl 0x561d248477d8 <line:24:32> "SV_Target0"
The relevant portion is
InitListExpr 0x561d24841f28 <col:89, col:98> 'void'
|-FloatingLiteral 0x561d24841ee8 <col:90> 'literal float' 1.000000e+00
`-FloatingLiteral 0x561d24841f08 <col:95> 'literal float' 1.000000e+00
where the InitListExpr is being marked as being of type 'void'. This tracks with the error message that I get from my local build:
error: casting to type 'void' unimplemented
@llvm-beanz is this AST correct for the given code? Do you know if it would be better to change the AST or to change the SPIR-V backend to use the type that the InitListExpr is being assigned to?
I can't say that I understand it, but clang gives InitListExpr type void for C++ too:
https://godbolt.org/z/oKrhbYGrn
-VarDecl 0xd8337f8 parent 0xd832f98 prev 0xd833460 <line:12:1, col:122> col:74 xi 'const float_t[2]' cinit
`-InitListExpr 0xd8518b8 <col:82, col:122> 'void'
|-UnaryOperator 0xd851880 <col:83, col:84> 'double' prefix '-'
| `-FloatingLiteral 0xd851860 <col:84> 'double' 5.773503e-01
`-FloatingLiteral 0xd851898 <col:104> 'double' 5.773503e-01
So I think that bit is right.
Huh, interesting. Thanks for pointing that out, I'll update the backend then.
Btw it works for non-array types https://godbolt.org/z/9G7vnhesr and on this simple repro https://godbolt.org/z/ze8jaoM3z
But this is a full explicit specialization out of line initialization, not a partial.