Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0.0, 2022-11-02 ToT] Assertion `Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"' failed. #58800

Closed
hctim opened this issue Nov 3, 2022 · 8 comments
Labels
clang:codegen confirmed Verified by a second party crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@hctim
Copy link
Collaborator

hctim commented Nov 3, 2022

Obviously only reproduces on a build with asserts (-DLLVM_ENABLE_ASSERTIONS=On)

This is at HEAD from yesterday (40e9947), but given that this assertion has been sitting around for a while (2009! 5169570), maybe not a recent regression. I don't have older assert-enabled builds of clang to debug against.

Simple reproducer:

struct Foo {
  union {
    struct {
      float red = 0.0f;
    };
  };
};

Foo GetFoo() {
  Foo result{};
  return result;
}
$ /tmp/aarch64-toolchain/bin/clang++ /tmp/out.cpp -S -o /tmp/out.s -emit-llvm
clang++: /usr/local/google/home/mitchp/llvm/clang/lib/CodeGen/CGExprAgg.cpp:1688: void (anonymous namespace)::AggExprEmitter::VisitInitListExpr(clang::InitListExpr *): Assertion `Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /tmp/aarch64-toolchain/bin/clang++ /tmp/out.cpp -S -o /tmp/out.s -emit-llvm
1.	<eof> parser at end of file
2.	/tmp/out.cpp:9:5: LLVM IR generation of declaration 'GetFoo'
3.	/tmp/out.cpp:9:5: Generating code for declaration 'GetFoo'
 #0 0x000055c231315433 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/tmp/aarch64-toolchain/bin/clang+++0x7315433)
 #1 0x000055c23131342e llvm::sys::RunSignalHandlers() (/tmp/aarch64-toolchain/bin/clang+++0x731342e)
 #2 0x000055c23127c68e (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) CrashRecoveryContext.cpp:0:0
 #3 0x000055c23127c8e0 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #4 0x00007fb5eec3daa0 (/lib/x86_64-linux-gnu/libc.so.6+0x3daa0)
 #5 0x00007fb5eec8957c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #6 0x00007fb5eec3da02 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #7 0x00007fb5eec28469 abort ./stdlib/abort.c:81:7
 #8 0x00007fb5eec28395 _nl_load_domain ./intl/loadmsgcat.c:1177:9
 #9 0x00007fb5eec36ab2 (/lib/x86_64-linux-gnu/libc.so.6+0x36ab2)
#10 0x000055c2319347fc (anonymous namespace)::AggExprEmitter::VisitInitListExpr(clang::InitListExpr*) CGExprAgg.cpp:0:0
#11 0x000055c23192c1d9 clang::CodeGen::CodeGenFunction::EmitAggExpr(clang::Expr const*, clang::CodeGen::AggValueSlot) (/tmp/aarch64-toolchain/bin/clang+++0x792c1d9)
#12 0x000055c2319371d0 (anonymous namespace)::AggExprEmitter::EmitInitializationToLValue(clang::Expr*, clang::CodeGen::LValue) CGExprAgg.cpp:0:0
#13 0x000055c231933495 (anonymous namespace)::AggExprEmitter::VisitInitListExpr(clang::InitListExpr*) CGExprAgg.cpp:0:0
#14 0x000055c23192c1d9 clang::CodeGen::CodeGenFunction::EmitAggExpr(clang::Expr const*, clang::CodeGen::AggValueSlot) (/tmp/aarch64-toolchain/bin/clang+++0x792c1d9)
#15 0x000055c23182c737 clang::CodeGen::CodeGenFunction::EmitExprAsInit(clang::Expr const*, clang::ValueDecl const*, clang::CodeGen::LValue, bool) (/tmp/aarch64-toolchain/bin/clang+++0x782c737)
#16 0x000055c231829b2b clang::CodeGen::CodeGenFunction::EmitAutoVarInit(clang::CodeGen::CodeGenFunction::AutoVarEmission const&) (/tmp/aarch64-toolchain/bin/clang+++0x7829b2b)
#17 0x000055c231824981 clang::CodeGen::CodeGenFunction::EmitVarDecl(clang::VarDecl const&) (/tmp/aarch64-toolchain/bin/clang+++0x7824981)
#18 0x000055c2318244ae clang::CodeGen::CodeGenFunction::EmitDecl(clang::Decl const&) (/tmp/aarch64-toolchain/bin/clang+++0x78244ae)
#19 0x000055c231734d9c clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) (/tmp/aarch64-toolchain/bin/clang+++0x7734d9c)
#20 0x000055c231729091 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/tmp/aarch64-toolchain/bin/clang+++0x7729091)
#21 0x000055c231728308 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/tmp/aarch64-toolchain/bin/clang+++0x7728308)
#22 0x000055c231735ea0 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/tmp/aarch64-toolchain/bin/clang+++0x7735ea0)
#23 0x000055c2317185d4 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) (/tmp/aarch64-toolchain/bin/clang+++0x77185d4)
#24 0x000055c2317191f5 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/tmp/aarch64-toolchain/bin/clang+++0x77191f5)
#25 0x000055c2316527c8 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/tmp/aarch64-toolchain/bin/clang+++0x76527c8)
#26 0x000055c23164ad0c clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/tmp/aarch64-toolchain/bin/clang+++0x764ad0c)
#27 0x000055c23164f2cb clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/tmp/aarch64-toolchain/bin/clang+++0x764f2cb)
#28 0x000055c2316498d5 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (/tmp/aarch64-toolchain/bin/clang+++0x76498d5)
#29 0x000055c23201d82f (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
#30 0x000055c23201ae86 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) CodeGenAction.cpp:0:0
#31 0x000055c2332b5e89 clang::ParseAST(clang::Sema&, bool, bool) (/tmp/aarch64-toolchain/bin/clang+++0x92b5e89)
#32 0x000055c231f39380 clang::FrontendAction::Execute() (/tmp/aarch64-toolchain/bin/clang+++0x7f39380)
#33 0x000055c231ea8adf clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/tmp/aarch64-toolchain/bin/clang+++0x7ea8adf)
#34 0x000055c2320145c2 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/tmp/aarch64-toolchain/bin/clang+++0x80145c2)
#35 0x000055c22ee8b281 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/tmp/aarch64-toolchain/bin/clang+++0x4e8b281)
#36 0x000055c22ee8798a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#37 0x000055c231d20c02 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_1>(long) Job.cpp:0:0
#38 0x000055c23127c509 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/tmp/aarch64-toolchain/bin/clang+++0x727c509)
#39 0x000055c231d2043f clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/tmp/aarch64-toolchain/bin/clang+++0x7d2043f)
#40 0x000055c231ce01de clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/tmp/aarch64-toolchain/bin/clang+++0x7ce01de)
#41 0x000055c231ce048e clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/tmp/aarch64-toolchain/bin/clang+++0x7ce048e)
#42 0x000055c231cfdc60 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/tmp/aarch64-toolchain/bin/clang+++0x7cfdc60)
#43 0x000055c22ee86e94 clang_main(int, char**) (/tmp/aarch64-toolchain/bin/clang+++0x4e86e94)
#44 0x00007fb5eec2920a __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#45 0x00007fb5eec292bc call_init ./csu/../csu/libc-start.c:128:20
#46 0x00007fb5eec292bc __libc_start_main ./csu/../csu/libc-start.c:376:5
#47 0x000055c22ee84361 _start (/tmp/aarch64-toolchai
[out-29ed70.sh.txt](https://github.com/llvm/llvm-project/files/9933348/out-29ed70.sh.txt)
[out-29ed70.cpp.txt](https://github.com/llvm/llvm-project/files/9933349/out-29ed70.cpp.txt)
n/bin/clang+++0
[out-29ed70.sh.txt](https://github.com/llvm/llvm-project/files/9933347/out-29ed70.sh.txt)
x4e84361)
clang-16: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 16.0.0 (https://github.com/llvm/llvm-project.git 40e99473170f5045e0b5f2cafabd2a1be8c7ec26)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /tmp/aarch64-toolchain/bin
clang-16: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-16: note: diagnostic msg: /tmp/out-29ed70.cpp
clang-16: note: diagnostic msg: /tmp/out-29ed70.sh
clang-16: note: diagnostic msg: 

********************

Removing the brace-initializers reveals that the default constructor is implicitly deleted, which seems probably related.

Foo GetFoo() {
-  Foo result{};
+  Foo result;
  return result;
}
/tmp/out.cpp:10:7: error: call to implicitly-deleted default constructor of 'Foo'
  Foo result;
      ^
/tmp/out.cpp:3:5: note: default constructor of 'Foo' is implicitly deleted because variant field '' has a non-trivial default constructor
    struct {
    ^
1 error generated.

Easy fix for users, simply declare a default constructor for the object:

struct Foo {
+  Foo() {}
  union {
    struct {
      float red = 0.0f;
    };
  };
};
@hctim
Copy link
Collaborator Author

hctim commented Nov 3, 2022

And here's the files:

out-29ed70.sh.txt
out-29ed70.cpp.txt

@EugeneZelenko EugeneZelenko added clang:codegen crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Nov 3, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 3, 2022

@llvm/issue-subscribers-clang-codegen

@shafik
Copy link
Collaborator

shafik commented Nov 4, 2022

Confirmed godbolt: https://godbolt.org/z/vvGExj9Y7

@shafik shafik added the confirmed Verified by a second party label Nov 4, 2022
@shafik
Copy link
Collaborator

shafik commented Nov 4, 2022

I spent a little bit of time looking at this and I believe having in class member initialization changed the paths we can take to get here and make the assumptions not valid anymore. Salvaging it may require some heroics but not sure.

@shafik
Copy link
Collaborator

shafik commented Nov 5, 2022

It looks like we are ending up at AggExprEmitter::VisitInitListExpr(...) because in CodeGenFunction::EmitAutoVarInit(...) the local variable constant is a nullptr and it seems that b/c the anonymous struct is no a POD in CodeGenFunction::EmitAutoVarAlloca(...) we don' set emission.IsConstantAggregate to true.

So it looks like adjusting the assertion like this:

assert((Field->isUnnamedBitfield() || Field->isAnonymousStructOrUnion()) && "Only unnamed bitfields or anonymous struct allowed");

would fix this case. I was not able to hit this path through other means.

@shafik
Copy link
Collaborator

shafik commented Nov 16, 2022

@AaronBallman wdyt this is a GNU extension and gcc accepts the code: https://godbolt.org/z/KjM3o4hdK

so I think my analysis based on that is correct and extending the assert is the right thing.

@AaronBallman
Copy link
Collaborator

I think your analysis is reasonable; both GCC and ICC accept that code, and I think Clang should as well.

@shafik
Copy link
Collaborator

shafik commented Dec 21, 2022

@shafik shafik closed this as completed in 475cc44 Dec 21, 2022
CarlosAlbertoEnciso pushed a commit to SNSystems/llvm-debuginfo-analyzer that referenced this issue Dec 25, 2022
…pr to cover anonymous struct in a union GNU extension

AggExprEmitter::VisitInitListExpr sanity checks that an empty union is really
empty and not a semantic analysis failure. The assert is missing that we allow
anonymous structs as a GNU extension. I have updated the assert to take that into account.

This fixes: llvm/llvm-project#58800

Differential Revision: https://reviews.llvm.org/D139261
veselypeta pushed a commit to veselypeta/cherillvm that referenced this issue Jun 10, 2024
…pr to cover anonymous struct in a union GNU extension

AggExprEmitter::VisitInitListExpr sanity checks that an empty union is really
empty and not a semantic analysis failure. The assert is missing that we allow
anonymous structs as a GNU extension. I have updated the assert to take that into account.

This fixes: llvm/llvm-project#58800

Differential Revision: https://reviews.llvm.org/D139261
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen confirmed Verified by a second party crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
Development

No branches or pull requests

5 participants