llvm / llvm/llvm-project

clang++ crashes with constexpr address of label stuff

Open
#219,659 6 comments 0 reactions 0 assignees View on GitHub
clang:codegen constexpr crash
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

clang++ 23.1.0 https://mirrors.edge.kernel.org/pub/tools/llvm/files/llvm-23.1.0-x86_64.tar.xz

  1. save as /tmp/a.c++:
    static auto foo() {
    
    label1:
    constexpr void * label1addr = &&label1;
    struct dummy {
    constexpr static void * getlabel1addr() {
    return label1addr;
    }
    };
    return dummy{};
    }

    void * a = decltype(foo())::getlabel1addr();

  2. run clang++ /tmp/a.c++
and it crashes:
/tmp/a.c++:6:11: warning: returning address of label, which is local [-Wreturn-stack-address]

6 | return label1addr;
| ^~~~~~~~~~
/tmp/a.c++:3:19: note: via initialization of variable 'label1addr' here
3 | constexpr void * label1addr = &&label1;
| ^ ~~~~~~~~
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and dumped files.
Stack dump:
0. Program arguments: /tmp/llvm-23.1.0-x86_64/bin/llvm clang++ -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -dumpdir a- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name a.c++ -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/ -fcoverage-compilation-dir=/ -resource-dir /tmp/llvm-23.1.0-x86_64/lib/clang/23 -internal-isystem /usr/lib64/gcc/x86_64-suse-linux/16/../../../../include/c++/16 -internal-isystem /usr/lib64/gcc/x86_64-suse-linux/16/../../../../include/c++/16/x86_64-suse-linux -internal-isystem /usr/lib64/gcc/x86_64-suse-linux/16/../../../../include/c++/16/backward -internal-isystem /tmp/llvm-23.1.0-x86_64/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib64/gcc/x86_64-suse-linux/16/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -ferror-limit 19 -fmessage-length=251 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -faddrsig -fdwarf2-cfi-asm -o /tmp/a-34e002.o -x c++ /tmp/a.c++
1. <eof> parser at end of file
2. /tmp/a.c++:12:8: LLVM IR generation of declaration 'a'
3. /tmp/a.c++:12:8: Generating code for declaration 'a'
#0 0x0000564a81e625da llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) Signals.cpp:0:0
#1 0x0000564a81e62fef SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#2 0x00007fa3e4443190 __restore_rt (/lib64/libc.so.6+0x43190)
#3 0x0000564a82a09f1d clang::CodeGen::CodeGenFunction::GetAddrOfLabel(clang::LabelDecl const*) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x8609f1d)
#4 0x0000564a82fc21c2 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::ConstantLValueEmitter, (anonymous namespace)::ConstantLValue>::Visit(clang::Stmt const*) (.cold.0) CGExprConstant.cpp:0:0
#5 0x0000564a8254bba9 clang::CodeGen::ConstantEmitter::tryEmitPrivate(clang::APValue const&, clang::QualType, bool) CGExprConstant.cpp:0:0
#6 0x0000564a8254bf4c clang::CodeGen::ConstantEmitter::tryEmitPrivateForMemory(clang::APValue const&, clang::QualType) CGExprConstant.cpp:0:0
#7 0x0000564a8254bd95 clang::CodeGen::ConstantEmitter::tryEmitForInitializer(clang::VarDecl const&) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x814bd95)
#8 0x0000564a82478c49 clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(clang::VarDecl const*, bool) CodeGenModule.cpp:0:0
#9 0x0000564a82479cf5 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) CodeGenModule.cpp:0:0
#10 0x0000564a8247aefb clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x807aefb)
#11 0x0000564a8224195a clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x7e4195a)
#12 0x0000564a82204354 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
#13 0x0000564a82204275 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) CodeGenAction.cpp:0:0
#14 0x0000564a82228e19 clang::ParseAST(clang::Sema&, bool, bool) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x7e28e19)
#15 0x0000564a827b2179 clang::FrontendAction::Execute() (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x83b2179)
#16 0x0000564a827b20d9 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x83b20d9)
#17 0x0000564a827b1627 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x83b1627)
#18 0x0000564a827b14ba cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x83b14ba)
#19 0x0000564a827b0a73 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) driver.cpp:0:0
#20 0x0000564a828f4b74 clang_main(int, char**, llvm::ToolContext const&) (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x84f4b74)
#21 0x0000564a828f2335 findTool(int, char**, char const*) llvm-driver.cpp:0:0
#22 0x0000564a8320fb4d findTool(int, char**, char const*) (.cold.0) llvm-driver.cpp:0:0
#23 0x0000564a82871dc3 main (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x8471dc3)
#24 0x00007fa3e442b4fe __libc_start_call_main /usr/src/debug/glibc-2.43/csu/../sysdeps/nptl/libc_start_call_main.h:83:3
#25 0x00007fa3e442b62b call_init /usr/src/debug/glibc-2.43/csu/../csu/libc-start.c:128:20
#26 0x00007fa3e442b62b __libc_start_main@GLIBC_2.2.5 /usr/src/debug/glibc-2.43/csu/../csu/libc-start.c:347:5
#27 0x0000564a8258ba6a _start (/tmp/llvm-23.1.0-x86_64/bin/llvm+0x818ba6a)
clang++: error: unable to execute command: Segmentation fault (core dumped)
clang++: error: clang frontend command failed with exit code -2 (use -v to see invocation)
ClangBuiltLinux clang version 23.1.0 (https://github.com/llvm/llvm-project.git ea7d852a70e8bdfaf601d6626a760f9771b2c4b4)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /tmp/llvm-23.1.0-x86_64/bin
clang++: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING CRASH REPRODUCER FILES TO THE BUG REPORT:
clang++: note: diagnostic msg: /tmp/a-1e24ad.cpp
clang++: note: diagnostic msg: /tmp/a-1e24ad.sh
clang++: note: diagnostic msg:

********************
Aborted (core dumped) clang++ /tmp/a.c++


question: Is there a simpler than returning dummy struct way to expose address of label to outside scope for other functions to use?

Contributor guide

Open the contributing guide

Research direction

First reproduce the crash with clang++ /tmp/a.c++ and the supplied compiler build. Trace the stack from CodeGenFunction::GetAddrOfLabel into CGExprConstant.cpp, particularly ConstantLValueEmitter, and use the reported global initializer as the boundary for investigation. Done means this reproducer no longer causes a frontend segmentation fault, with the resulting compiler behavior captured in a regression test.

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
Active
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.