thakis@thakis:~/src/llvm-project$ cat crw_js_navigation_handler-66a6fd-ae8518.reduced.mm struct f {}; class i { int m; [[no_unique_address]] f n; }; @interface v @end @implementation v - (i)message { return i(); } @end thakis@thakis:~/src/llvm-project$ out/gn/bin/clang -cc1 -emit-llvm crw_js_navigation_handler-66a6fd-ae8518.reduced.mm crw_js_navigation_handler-66a6fd-ae8518.reduced.mm:6:12: warning: class 'v' defined without specifying a base class [-Wobjc-root-class] @interface v @end ^ crw_js_navigation_handler-66a6fd-ae8518.reduced.mm:6:13: note: add a super class to fix this problem @interface v @end ^ clang: ../../clang/lib/AST/ASTContext.cpp:7718: void clang::ASTContext::getObjCEncodingForStructureImpl(clang::RecordDecl *, std::string &, const clang::FieldDecl *, bool, clang::QualType *) const: Assertion `CurOffs <= CurLayObj->first' failed. Stack dump: 0. Program arguments: out/gn/bin/clang -cc1 -emit-llvm crw_js_navigation_handler-66a6fd-ae8518.reduced.mm 1. <eof> parser at end of file 2. crw_js_navigation_handler-66a6fd-ae8518.reduced.mm:8:1: LLVM IR generation of declaration 'v::message' #0 0x0000000002e6260c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (out/gn/bin/clang+0x2e6260c) #1 0x0000000002e6036e llvm::sys::RunSignalHandlers() (out/gn/bin/clang+0x2e6036e) #2 0x0000000002e62955 SignalHandler(int) (out/gn/bin/clang+0x2e62955) #3 0x00007f2baf4e0140 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14140) #4 0x00007f2baeff8db1 raise ./signal/../sysdeps/unix/sysv/linux/raise.c:51:1 #5 0x00007f2baefe2537 abort ./stdlib/abort.c:81:7 #6 0x00007f2baefe240f get_sysdep_segment_value ./intl/loadmsgcat.c:509:8 #7 0x00007f2baefe240f _nl_load_domain ./intl/loadmsgcat.c:970:34 #8 0x00007f2baeff15b2 (/lib/x86_64-linux-gnu/libc.so.6+0x345b2) #9 0x0000000003638d9d clang::ASTContext::getObjCEncodingForStructureImpl(clang::RecordDecl*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, clang::FieldDecl const*, bool, clang::QualType*) const (out/gn/bin/clang+0x3638d9d) #10 0x00000000036369ac clang::ASTContext::getObjCEncodingForTypeImpl(clang::QualType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, clang::ASTContext::ObjCEncOptions, clang::FieldDecl const*, clang::QualType*) const (out/gn/bin/clang+0x36369ac) #11 0x000000000363710f clang::ASTContext::getObjCEncodingForMethodDecl[abi:cxx11](clang::ObjCMethodDecl const*, bool) const (out/gn/bin/clang+0x363710f) #12 0x000000000218df26 (anonymous namespace)::CGObjCCommonMac::GetMethodVarType(clang::ObjCMethodDecl const*, bool) (out/gn/bin/clang+0x218df26) #13 0x000000000219df85 (anonymous namespace)::CGObjCNonFragileABIMac::emitMethodList(llvm::Twine, (anonymous namespace)::(anonymous namespace)::MethodListType, llvm::ArrayRef<clang::ObjCMethodDecl const*>) (out/gn/bin/clang+0x219df85) #14 0x000000000219f16e (anonymous namespace)::CGObjCNonFragileABIMac::BuildClassRoTInitializer(unsigned int, unsigned int, unsigned int, clang::ObjCImplementationDecl const*) (out/gn/bin/clang+0x219f16e) #15 0x000000000219844c (anonymous namespace)::CGObjCNonFragileABIMac::GenerateClass(clang::ObjCImplementationDecl const*) (out/gn/bin/clang+0x219844c) #16 0x0000000001e8e5f2 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (out/gn/bin/clang+0x1e8e5f2) #17 0x00000000024d925f (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) (out/gn/bin/clang+0x24d925f) #18 0x00000000024d76fd clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (out/gn/bin/clang+0x24d76fd) #19 0x0000000003b487f8 clang::ParseAST(clang::Sema&, bool, bool) (out/gn/bin/clang+0x3b487f8) #20 0x0000000002424db3 clang::FrontendAction::Execute() (out/gn/bin/clang+0x2424db3) #21 0x000000000238004a clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (out/gn/bin/clang+0x238004a) #22 0x00000000024d1022 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (out/gn/bin/clang+0x24d1022) #23 0x0000000001d8c530 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (out/gn/bin/clang+0x1d8c530) #24 0x0000000001d9ab78 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) (out/gn/bin/clang+0x1d9ab78) getObjCEncodingForStructureImpl presumably handles the empty base class optimization somehow, so we need to do something similar for no_unique_address (reduced from https://crbug.com/1144431)
FieldDecl::isZeroSize() also mentions zero-length bitfields, check if those currently cause asserts. Hm, apparently they don't, I wonder why. isEmptyField() in TargetInfo.cpp duplicates some of FieldDecl::isZeroSize(), and mentions arrays of zero-sized things. This seems to fix the assert at least: thakis@thakis:~/src/llvm-project$ git diff diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 48a0bebc545..22fca032296 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -7658,7 +7658,10 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, } unsigned i = 0; - for (auto *Field : RDecl->fields()) { + for (FieldDecl *Field : RDecl->fields()) { + if (Field->isZeroSize(*this)) + continue; uint64_t offs = layout.getFieldOffset(i); FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), std::make_pair(offs, Field)); ...and it's similar to the continues in the loops over bases above and below this loop. So this is maybe the right fix. I'll write a test and send it out and see what rjmccall says, I suppose :)
https://reviews.llvm.org/D90622
https://reviews.llvm.org/rG46ca880fcae24693d381ca05c16c704675545433