DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

DXC crashes if a type is defined within a namespace with the same name as a built-in type and is later instantiated

Open 2aecfff4 opened this issue 2 years ago • 1 comments

Description

DXC crashes if a type is defined within a namespace with the same name as a built-in type and is later instantiated.

Steps to Reproduce

This crashes with both SPIR-V and DXIL.

namespace test {

class Texture2D { };

}

[numthreads(16, 1, 1)]
void main() {
    test::Texture2D texture; // <- crash
}

https://godbolt.org/z/dhWdGr9ad

The second one only crashes during SPIR-V generation and only when resource binding is used.

#define CRASH 1

namespace test {

[[vk::binding(0, 1)]] Texture2D<float2> g_textures2D_float2[] : register(t0, space5);

template <typename T>
class Texture2D;

template <>                                                                          
class Texture2D<float2> {                          
    uint m_texture_index;                                                            
                                                                                        
    float2 read(const int2 pos, const int mip_level ) {                            
        const int3 loc = int3(pos.x, pos.y, mip_level);
#if CRASH
        return g_textures2D_float2[this.m_texture_index].Load(loc);
#else
        return (float2)0.f;
#endif
    }                                                                                
};

}

[numthreads(16, 1, 1)]
void main() {
    test::Texture2D<float2> t;
    t.read(int2(0, 0), 0); // <- crash
}

https://godbolt.org/z/GGdhbqs7d

Actual Behavior

Program terminated with signal: SIGSEGV

Environment As of today, DXC on Godbolt returns ibdxcompiler.so: 1.7(dev;1-549030f9).

2aecfff4 avatar Sep 17 '23 11:09 2aecfff4

The crash call stack is:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00000001ac2dc764 libsystem_kernel.dylib
    frame #1: 0x00000001ac313c28 libsystem_pthread.dylib pthread_kill:`pthread_kill + 288
    frame #2: 0x000000010e16706c libdxcompiler.dylib ::raise(int):`::raise(sig=6 0x00000006) + 28 at Signals.inc:532
    frame #3: 0x000000011024918c libdxcompiler.dylib ::abort():`::abort() + 16 at Signals.inc:549
    frame #4: 0x000000011024917c libdxcompiler.dylib ::__assert_rtn(const char *, const char *, int, const char *):`::__assert_rtn(func="doit", file="Casting.h", line=96 0x00000060, expr="Val && \"isa<> used on a null pointer\"") + 180 at Signals.inc:545
    frame #5: 0x000000010f618ab0 libdxcompiler.dylib llvm::isa_impl_cl<clang::FieldDecl, clang::Decl const*>::doit:`llvm::isa_impl_cl<clang::FieldDecl, clang::Decl const*>::doit(Val=0x0000000000000000) + 100 at Casting.h:96
    frame #6: 0x000000010f618a3c libdxcompiler.dylib llvm::isa_impl_wrap<clang::FieldDecl, clang::Decl const*, clang::Decl const*>::doit:`llvm::isa_impl_wrap<clang::FieldDecl, clang::Decl const*, clang::Decl const*>::doit(Val=0x000000016fdf8240) + 28 at Casting.h:123
    frame #7: 0x000000010f618a10 libdxcompiler.dylib llvm::isa_impl_wrap<clang::FieldDecl, clang::Decl* const, clang::Decl const*>::doit:`llvm::isa_impl_wrap<clang::FieldDecl, clang::Decl* const, clang::Decl const*>::doit(Val=0x000000016fdf8288) + 40 at Casting.h:113
    frame #8: 0x000000010f6189d8 libdxcompiler.dylib llvm::isa<clang::FieldDecl, clang::Decl*>:`bool llvm::isa<clang::FieldDecl, clang::Decl*>(Val=0x000000016fdf8288) + 24 at Casting.h:134
    frame #9: 0x000000010f618bb0 libdxcompiler.dylib llvm::cast<clang::FieldDecl, clang::Decl>:`llvm::cast_retty<clang::FieldDecl, clang::Decl*>::ret_type llvm::cast<clang::FieldDecl, clang::Decl>(Val=0x0000000000000000) + 28 at Casting.h:239
    frame #10: 0x000000010f6184c4 libdxcompiler.dylib clang::DeclContext::specific_decl_iterator<clang::FieldDecl>::operator*:`clang::DeclContext::specific_decl_iterator<clang::FieldDecl>::operator*(this=0x000000016fdf82e8) const + 32 at DeclBase.h:1487
    frame #11: 0x000000010f297268 libdxcompiler.dylib hlsl::GetHLSLResourceResultType:`hlsl::GetHLSLResourceResultType(type=QualType @ 0x000000016fdf8340) + 328 at HlslTypes.cpp:827
  * frame #12: 0x000000010e3722a4 libdxcompiler.dylib (anonymous namespace)::CGMSHLSLRuntime::AddTypeAnnotation:`(anonymous namespace)::CGMSHLSLRuntime::AddTypeAnnotation(this=0x000000010182ba00, Ty=QualType @ 0x000000016fdf8530, dxilTypeSys=0x0000000101717dd0, arrayEltSize=6171887020 0x000000016fdf85ac) + 784 at CGHLSLMS.cpp:1270
    frame #13: 0x000000010e36796c libdxcompiler.dylib (anonymous namespace)::CGMSHLSLRuntime::FinishAutoVar:`(anonymous namespace)::CGMSHLSLRuntime::FinishAutoVar(this=0x000000010182ba00, CGF=0x000000016fdf9288, D=0x0000000101852200, V=0x00000001017267e8) + 140 at CGHLSLMS.cpp:2592
    frame #14: 0x000000010e2d9ae0 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitAutoVarAlloca:`clang::CodeGen::CodeGenFunction::EmitAutoVarAlloca(this=0x000000016fdf9288, D=0x0000000101852200) + 2632 at CGDecl.cpp:1060
    frame #15: 0x000000010e2d74cc libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitAutoVarDecl:`clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(this=0x000000016fdf9288, D=0x0000000101852200) + 44 at CGDecl.cpp:864
    frame #16: 0x000000010e2d7060 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitVarDecl:`clang::CodeGen::CodeGenFunction::EmitVarDecl(this=0x000000016fdf9288, D=0x0000000101852200) + 496 at CGDecl.cpp:165
    frame #17: 0x000000010e2d6c08 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitDecl:`clang::CodeGen::CodeGenFunction::EmitDecl(this=0x000000016fdf9288, D=0x0000000101852200) + 424 at CGDecl.cpp:116
    frame #18: 0x000000010e3d9f90 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitDeclStmt:`clang::CodeGen::CodeGenFunction::EmitDeclStmt(this=0x000000016fdf9288, S=0x0000000101852270) + 156 at CGStmt.cpp:1208
    frame #19: 0x000000010e3d70ac libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitSimpleStmt:`clang::CodeGen::CodeGenFunction::EmitSimpleStmt(this=0x000000016fdf9288, S=0x0000000101852270) + 364 at CGStmt.cpp:264
    frame #20: 0x000000010e3d6934 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitStmt:`clang::CodeGen::CodeGenFunction::EmitStmt(this=0x000000016fdf9288, S=0x0000000101852270) + 144 at CGStmt.cpp:52
    frame #21: 0x000000010e3daed4 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope:`clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(this=0x000000016fdf9288, S=0x0000000101852288, GetLast=false, AggSlot=AggValueSlot @ 0x000000016fdf8c80) + 140 at CGStmt.cpp:305
    frame #22: 0x000000010e406698 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::EmitFunctionBody:`clang::CodeGen::CodeGenFunction::EmitFunctionBody(this=0x000000016fdf9288, Args=0x000000016fdf9000, Body=0x0000000101852288) + 128 at CodeGenFunction.cpp:811
    frame #23: 0x000000010e407020 libdxcompiler.dylib clang::CodeGen::CodeGenFunction::GenerateCode:`clang::CodeGen::CodeGenFunction::GenerateCode(this=0x000000016fdf9288, GD=GlobalDecl @ 0x000000016fdf8ff8, Fn=0x0000000101716958, FnInfo=0x0000000101725500) + 1988 at CodeGenFunction.cpp:932
    frame #24: 0x000000010e41ccc4 libdxcompiler.dylib clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition:`clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(this=0x0000000101829a00, GD=GlobalDecl @ 0x000000016fdf9280, GV=0x0000000101716958) + 1268 at CodeGenModule.cpp:2620
    frame #25: 0x000000010e4196b8 libdxcompiler.dylib clang::CodeGen::CodeGenModule::EmitGlobalDefinition:`clang::CodeGen::CodeGenModule::EmitGlobalDefinition(this=0x0000000101829a00, GD=GlobalDecl @ 0x000000016fdf9db8, GV=0x0000000000000000) + 816 at CodeGenModule.cpp:1603
    frame #26: 0x000000010e41bbb8 libdxcompiler.dylib clang::CodeGen::CodeGenModule::EmitGlobal:`clang::CodeGen::CodeGenModule::EmitGlobal(this=0x0000000101829a00, GD=GlobalDecl @ 0x000000016fdf9ee8) + 744 at CodeGenModule.cpp:1451
    frame #27: 0x000000010e41ef54 libdxcompiler.dylib clang::CodeGen::CodeGenModule::EmitTopLevelDecl:`clang::CodeGen::CodeGenModule::EmitTopLevelDecl(this=0x0000000101829a00, D=0x0000000101843608) + 216 at CodeGenModule.cpp:3392
    frame #28: 0x000000010e54756c libdxcompiler.dylib (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl:`(anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(this=0x0000000101825c00, DG=DeclGroupRef @ 0x000000016fdfa000) + 176 at ModuleBuilder.cpp:133
    frame #29: 0x000000010e3fbfa0 libdxcompiler.dylib clang::BackendConsumer::HandleTopLevelDecl:`clang::BackendConsumer::HandleTopLevelDecl(this=0x00000001017155f0, D=DeclGroupRef @ 0x000000016fdfa088) + 200 at CodeGenAction.cpp:120
    frame #30: 0x000000010f903fec libdxcompiler.dylib clang::ParseAST:`clang::ParseAST(S=0x0000000101826400, PrintStats=false, SkipFunctionBodies=false) + 788 at ParseAST.cpp:148
    frame #31: 0x000000010e65b014 libdxcompiler.dylib clang::ASTFrontendAction::ExecuteAction:`clang::ASTFrontendAction::ExecuteAction(this=0x000000016fdfb690) + 296 at FrontendAction.cpp:554
    frame #32: 0x000000010e3fb590 libdxcompiler.dylib clang::CodeGenAction::ExecuteAction:`clang::CodeGenAction::ExecuteAction(this=0x000000016fdfb690) + 1464 at CodeGenAction.cpp:807
    frame #33: 0x000000010e65a8f4 libdxcompiler.dylib clang::FrontendAction::Execute:`clang::FrontendAction::Execute(this=0x000000016fdfb690) + 140 at FrontendAction.cpp:455
    frame #34: 0x000000010d440ed4 libdxcompiler.dylib DxcCompiler::Compile:`DxcCompiler::Compile(this=0x000000010170c0d0, pSource=0x000000016fdfd0a0, pArguments=0x000000010170c7b0, argCount=5 0x00000005, pIncludeHandler=0x000000010170ba40, riid=0x00000001004066a0, ppResult=0x000000016fdfd020) + 12252 at dxcompilerobj.cpp:971
    frame #35: 0x000000010d437050 libdxcompiler.dylib hlsl::DxcCompilerAdapter::WrapCompile:`hlsl::DxcCompilerAdapter::WrapCompile(this=0x000000010170c418, bPreprocess=NO, pSource=0x000000010170c4a0, pSourceName=L"crashme.hlsl", pEntryPoint=L"main", pTargetProfile=L"cs_6_0", pArguments=0x000000010170c060, argCount=2 0x00000002, pDefines=0x000000016fdfe650, defineCount=0 0x00000000, pIncludeHandler=0x000000010170ba40, ppResult=0x000000016fdfe1e8, ppDebugBlobName=0x0000000000000000, ppDebugBlob=0x0000000000000000) + 2524 at dxcompilerobj.cpp:1810
    frame #36: 0x000000010d438404 libdxcompiler.dylib hlsl::DxcCompilerAdapter::CompileWithDebug:`hlsl::DxcCompilerAdapter::CompileWithDebug(this=0x000000010170c418, pSource=0x000000010170c4a0, pSourceName=L"crashme.hlsl", pEntryPoint=L"main", pTargetProfile=L"cs_6_0", pArguments=0x000000010170c060, argCount=2 0x00000002, pDefines=0x000000016fdfe650, defineCount=0 0x00000000, pIncludeHandler=0x000000010170ba40, ppResult=0x000000016fdfe1e8, ppDebugBlobName=0x0000000000000000, ppDebugBlob=0x0000000000000000) + 376 at dxcompilerobj.cpp:1713
    frame #37: 0x000000010d4393e8 libdxcompiler.dylib hlsl::DxcCompilerAdapter::Compile:`hlsl::DxcCompilerAdapter::Compile(this=0x000000010170c418, pSource=0x000000010170c4a0, pSourceName=L"crashme.hlsl", pEntryPoint=L"main", pTargetProfile=L"cs_6_0", pArguments=0x000000010170c060, argCount=2 0x00000002, pDefines=0x000000016fdfe650, defineCount=0 0x00000000, pIncludeHandler=0x000000010170ba40, ppResult=0x000000016fdfe1e8) + 148 at dxcompileradapter.h:75
    frame #38: 0x000000010009e7b8 dxc DxcContext::Compile:`DxcContext::Compile(this=0x000000016fdfe3f8) + 3000 at dxc.cpp:877
    frame #39: 0x00000001000a333c dxc dxc::main:`dxc::main(argc=4 0x00000004, argv_=0x000000016fdff198) + 1848 at dxc.cpp:1505
    frame #40: 0x000000010000536c dxc main:`main(argc=4 0x00000004, argv_=0x000000016fdff198) + 36 at dxcmain.cpp:19
    frame #41: 0x00000001abfbbf28 dyld start:`start + 2236

Because we use the string name of the type to identify it as a resource IsHLSLResourceType returns true here: https://github.com/microsoft/DirectXShaderCompiler/blob/main/tools/clang/lib/CodeGen/CGHLSLMS.cpp#L1268C1-L1268C1

This results in calling GetHLSLResourceResultType, which tries to access the handle field, which in turn explodes.

Amusingly accessing the handle only looks at the first field in the struct, so this could be even worse if your struct wasn't empty. In that case the compiler doesn't crash we just continue through codegen, annotate that object as a resource and strew mayhem along the way.

https://godbolt.org/z/cxj5n5sjx

llvm-beanz avatar Sep 21 '23 18:09 llvm-beanz

This issue is DXC's main now due to @pow2clk's work cleaning up resource types to be referred to by an AST annotation rather than string matching the name.

Woo!

llvm-beanz avatar Apr 29 '25 01:04 llvm-beanz