microsoft / microsoft/DirectXShaderCompiler

[SPIR-V] Compiler crash when passing empty ConstantBuffer to a function

Open
#8,340 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage spirv
Dominant language
C++
Stars
3.7k
Forks
900
Avg merge
2d 11h
Merged PRs (30d)
44

Description

Description
Compiler crashes on null pointer access when using empty struct.

Steps to Reproduce
command line:

dxc /nologo /Od /Zi -spirv -fspv-flatten-resource-arrays -Ecrash -Tvs_6_0 -Fo crash.spv crash.hlsl

crash.hlsl:

struct L { float2 p0, p1; };
struct U {};

static inline L crashme(U u) {
    L o;

    o.p0 = float2(0, 0);
    o.p1 = float2(0, 1);

    return o;
}

[[ vk::binding(0, 0) ]] ConstantBuffer<U> us : register(b0, space0);

struct O {
    float4 p : SV_POSITION;
};

O crash() {

    // crash
    L pl = crashme(us);

    O o;
    o.p = float4(0,0,0,1);

    return o;
}

Actual Behavior
crash on null pointer:

libdxcompiler.dylib`clang::spirv::SpirvEmitter::generateFromScalars:
->  0x1029c90b8 <+76>: ldr    x8, [x8]
    0x1029c90bc <+80>: ldr    w8, [x8, #0x1c]
    0x1029c90c0 <+84>: str    x8, [sp, #0x28]
    0x1029c90c4 <+88>: mov    x0, x1
Target 0: (dxc) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00000001029c90b8 libdxcompiler.dylib`clang::spirv::SpirvEmitter::generateFromScalars(clang::QualType, std::__1::vector<clang::spirv::SpirvInstruction*, std::__1::allocator<clang::spirv::SpirvInstruction*>>&, clang::spirv::SpirvLayoutRule) + 76
    frame #1: 0x00000001029c873c libdxcompiler.dylib`clang::spirv::SpirvEmitter::processFlatConversion(clang::QualType, clang::spirv::SpirvInstruction*, clang::SourceLocation, clang::SourceRange) + 228
    frame #2: 0x00000001029b83bc libdxcompiler.dylib`clang::spirv::SpirvEmitter::doCastExpr(clang::CastExpr const*, clang::SourceRange) + 3384
    frame #3: 0x00000001029c37cc libdxcompiler.dylib`clang::spirv::SpirvEmitter::processCall(clang::CallExpr const*) + 1416
    frame #4: 0x00000001029bb2e8 libdxcompiler.dylib`clang::spirv::SpirvEmitter::loadIfGLValue(clang::Expr const*, clang::SourceRange) + 72
    frame #5: 0x00000001029b2624 libdxcompiler.dylib`clang::spirv::SpirvEmitter::doVarDecl(clang::VarDecl const*) + 2104
    frame #6: 0x00000001029b4830 libdxcompiler.dylib`clang::spirv::SpirvEmitter::doStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) + 1496
    frame #7: 0x00000001029b43c0 libdxcompiler.dylib`clang::spirv::SpirvEmitter::doStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) + 360
    frame #8: 0x00000001029b37f4 libdxcompiler.dylib`clang::spirv::SpirvEmitter::doFunctionDecl(clang::FunctionDecl const*) + 3932
    frame #9: 0x00000001029ae8c8 libdxcompiler.dylib`clang::spirv::SpirvEmitter::HandleTranslationUnit(clang::ASTContext&) + 964
    frame #10: 0x0000000102a2b2a0 libdxcompiler.dylib`clang::ParseAST(clang::Sema&, bool, bool) + 496
    frame #11: 0x0000000102348208 libdxcompiler.dylib`clang::FrontendAction::Execute() + 100
    frame #12: 0x0000000101c440bc libdxcompiler.dylib`DxcCompiler::Compile(DxcBuffer const*, wchar_t const**, unsigned int, IDxcIncludeHandler*, GUID const&, void**) + 7060
    frame #13: 0x0000000101c4004c libdxcompiler.dylib`hlsl::DxcCompilerAdapter::WrapCompile(bool, IDxcBlob*, wchar_t const*, wchar_t const*, wchar_t const*, wchar_t const**, unsigned int, DxcDefine const*, unsigned int, IDxcIncludeHandler*, IDxcOperationResult**, wchar_t**, IDxcBlob**) + 1252
    frame #14: 0x0000000101c41000 libdxcompiler.dylib`hlsl::DxcCompilerAdapter::CompileWithDebug(IDxcBlob*, wchar_t const*, wchar_t const*, wchar_t const*, wchar_t const**, unsigned int, DxcDefine const*, unsigned int, IDxcIncludeHandler*, IDxcOperationResult**, wchar_t**, IDxcBlob**) + 156
    frame #15: 0x0000000101c418e8 libdxcompiler.dylib`hlsl::DxcCompilerAdapter::Compile(IDxcBlob*, wchar_t const*, wchar_t const*, wchar_t const*, wchar_t const**, unsigned int, DxcDefine const*, unsigned int, IDxcIncludeHandler*, IDxcOperationResult**) + 44
    frame #16: 0x00000001000204d0 dxc`DxcContext::Compile() + 2352
    frame #17: 0x000000010002429c dxc`dxc::main(int, char const**) + 2208
    frame #18: 0x0000000189593da4 dyld`start + 6992

Environment

  • DXC version [(libdxcompiler.dylib: 1.10(5304-0131a626)(1.9.0.15304))]
  • Host Operating System osx 26.4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided crash.hlsl reproduction and the SPIR-V emitter stack trace, especially SpirvEmitter::generateFromScalars and its caller processFlatConversion. Run the listed dxc command to confirm the null-pointer crash, then verify that compiling the empty ConstantBuffer case completes and emits SPIR-V without crashing.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.