LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 48048 - no_unique_address makes clang::ASTContext::getObjCEncodingForStructureImpl fail with Assertion `CurOffs <= CurLayObj->first' failed.
Summary: no_unique_address makes clang::ASTContext::getObjCEncodingForStructureImpl fa...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: LLVM Codegen (show other bugs)
Version: unspecified
Hardware: PC Linux
: P enhancement
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-11-02 06:49 PST by Nico Weber
Modified: 2020-11-13 08:42 PST (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nico Weber 2020-11-02 06:49:00 PST
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)
Comment 1 Nico Weber 2020-11-02 08:19:06 PST
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 :)