[PATCH] D54344: [Clang][CodeGen][CXX]: Workaround __attribute((no_destroy)) crash/incorrect code generation.

Kristina Brooks via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 9 12:14:44 PST 2018


kristina created this revision.
kristina added reviewers: rsmith, clang, JonasToth, EricWF, aaron.ballman.
Herald added subscribers: dexonsmith, mehdi_amini.
Herald added a reviewer: jfb.

Difficult to reproduce crash, attempted it in the test, it appears to not trigger it. I can consistently reproduce it when building a large project with this attribute added and can consistently crash it without the fix in place, however.

This avoids the codepath that should not be executed in the first place by rechecking `NoDestroyAttr` and bailing out instead of emitting incorrect code or causing an assert in assert enabled builds. This does not appear to cause any regressions for x86_64 test suite and my test is useless since it does not offer the needed coverage.

  clang-8: /SourceCache/llvm-trunk-8.0/include/llvm/Support/Casting.h:106: static bool llvm::isa_impl_cl<clang::CXXConstructorDecl, const clang::CXXMethodDecl *>::doit(const From *) [To = clang::CXXConstructorDecl, From = const clang::CXXMethodDecl *]: Assertion `Val && "isa<> used on a null pointer"' failed.
  
  -- asserts here, rest is signal handler/stack trace --
  
  #9 0x0000000000d5a35d toCXXCtorType /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CodeGenTypes.h:66:3
  #10 0x0000000000d5a35d clang::CodeGen::CodeGenModule::getAddrOfCXXStructor(clang::CXXMethodDecl const*, clang::CodeGen::StructorType, clang::CodeGen::CGFunctionInfo const*, llvm::FunctionType*, bool, clang::CodeGen::ForDefinition_t) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CGCXX.cpp:237:0
  #11 0x0000000000e05c9b Address /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/Address.h:31:5
  #12 0x0000000000e05c9b ConstantAddress /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/Address.h:78:0
  #13 0x0000000000e05c9b clang::CodeGen::CodeGenFunction::EmitCXXGlobalVarDeclInit(clang::VarDecl const&, llvm::Constant*, bool) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CGDeclCXX.cpp:179:0
  #14 0x0000000000e07b7a clang::CodeGen::CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function*, clang::VarDecl const*, llvm::GlobalVariable*, bool) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CGDeclCXX.cpp:608:3
  #15 0x0000000000e06fc8 clang::CodeGen::CodeGenModule::EmitCXXGlobalVarDeclInitFunc(clang::VarDecl const*, llvm::GlobalVariable*, bool) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CGDeclCXX.cpp:441:3
  #16 0x0000000000b6596f clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(clang::VarDecl const*, bool) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CodeGenModule.cpp:3650:5
  #17 0x0000000000b5c66b clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CodeGenModule.cpp:0:12
  #18 0x0000000000b67dfb getKind /SourceCache/llvm-trunk-8.0/tools/clang/include/clang/AST/DeclBase.h:421:51
  #19 0x0000000000b67dfb classof /SourceCache/llvm-trunk-8.0/tools/clang/include/clang/AST/DeclCXX.h:3875:0
  #20 0x0000000000b67dfb doit /SourceCache/llvm-trunk-8.0/include/llvm/Support/Casting.h:59:0
  #21 0x0000000000b67dfb doit /SourceCache/llvm-trunk-8.0/include/llvm/Support/Casting.h:107:0
  #22 0x0000000000b67dfb doit /SourceCache/llvm-trunk-8.0/include/llvm/Support/Casting.h:133:0
  #23 0x0000000000b67dfb doit /SourceCache/llvm-trunk-8.0/include/llvm/Support/Casting.h:123:0
  #24 0x0000000000b67dfb isa<clang::DecompositionDecl, clang::Decl *> /SourceCache/llvm-trunk-8.0/include/llvm/Support/Casting.h:143:0
  #25 0x0000000000b67dfb dyn_cast<clang::DecompositionDecl, clang::Decl> /SourceCache/llvm-trunk-8.0/include/llvm/Support/Casting.h:334:0
  #26 0x0000000000b67dfb clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CodeGenModule.cpp:4783:0
  #27 0x0000000000b6bf7b getPointer /SourceCache/llvm-trunk-8.0/include/llvm/ADT/PointerIntPair.h:56:58
  #28 0x0000000000b6bf7b getNextDeclInContext /SourceCache/llvm-trunk-8.0/tools/clang/include/clang/AST/DeclBase.h:424:0
  #29 0x0000000000b6bf7b operator++ /SourceCache/llvm-trunk-8.0/tools/clang/include/clang/AST/DeclBase.h:1973:0
  #30 0x0000000000b6bf7b clang::CodeGen::CodeGenModule::EmitDeclContext(clang::DeclContext const*) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CodeGenModule.cpp:4744:0
  #31 0x000000000115a470 _ZN12_GLOBAL__N_117CodeGeneratorImpl18HandleTopLevelDeclEN5clang12DeclGroupRefE$7cf5ba2c3e38da85712ae9dd9c2a6e32 /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/ModuleBuilder.cpp:159:73
  #32 0x000000000115833d clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /SourceCache/llvm-trunk-8.0/tools/clang/lib/CodeGen/CodeGenAction.cpp:171:11
  #33 0x00000000011642f4 clang::ParseAST(clang::Sema&, bool, bool) /SourceCache/llvm-trunk-8.0/tools/clang/lib/Parse/ParseAST.cpp:161:11
  #34 0x00000000010c9d83 shouldBuildGlobalModuleIndex /SourceCache/llvm-trunk-8.0/tools/clang/lib/Frontend/CompilerInstance.cpp:81:11
  #35 0x00000000010c9d83 clang::FrontendAction::Execute() /SourceCache/llvm-trunk-8.0/tools/clang/lib/Frontend/FrontendAction.cpp:920:0
  #36 0x0000000001028d21 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /SourceCache/llvm-trunk-8.0/tools/clang/lib/Frontend/CompilerInstance.cpp:968:11
  #37 0x00000000011536fa clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /SourceCache/llvm-trunk-8.0/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:266:25
  #38 0x0000000000b0e77a cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /SourceCache/llvm-trunk-8.0/tools/clang/tools/driver/cc1_main.cpp:218:13
  #39 0x0000000000b0c5c0 ExecuteCC1Tool /SourceCache/llvm-trunk-8.0/tools/clang/tools/driver/driver.cpp:310:12
  #40 0x0000000000b0c5c0 main /SourceCache/llvm-trunk-8.0/tools/clang/tools/driver/driver.cpp:382:0
  #41 0x00007f2e66060830 __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:325:0
  #42 0x0000000000b09029 _start (/usr/local/sdk/llvm-8.0.4141/bin/clang-8+0xb09029)
  clang-8: error: unable to execute command: Aborted (core dumped)
  clang-8: error: clang frontend command failed due to signal (use -v to see invocation)
  Kristina's toolchain (8.0.4141+Asserts+Modular+ThinLTO+Tests+Debug) clang version 8.0.4141 (https://llvm.googlesource.com/clang acc4a4c5ae74512d3a5bed39b207aa536f2debbe) (https://llvm.googlesource.com/llvm 10ce7e317240f9a45f85317712dd0f8dbbc98fab) (based on LLVM 8.0.4141svn)
  Target: x86_64-unknown-linux-gnu
  Thread model: posix
  InstalledDir: /usr/local/sdk/nightly/bin

My test would be adding this to no_destroy.cpp except unfortunately that does not manage to trigger it and thus passes, so I'm unable to include a suitable test:

  namespace my_ns {
  	class with_nontrivial {
  	public:
  		with_nontrivial() { SomeValue[2] = 3; }
  		~with_nontrivial() { SomeValue[2] = 4; }
  	protected:
  		int SomeValue[10];
  	};
  	
  	class my_class : public with_nontrivial {
  	public:
  		my_class(const char* cstr) {}
  	};
  }
  
  namespace {
  	constexpr char ce_var[] = "string literal";
  	__attribute((no_destroy)) static my_ns::my_class s_var(ce_var);
  }




Repository:
  rC Clang

https://reviews.llvm.org/D54344

Files:
  lib/CodeGen/CGDeclCXX.cpp


Index: lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -68,6 +68,16 @@
 
   // FIXME:  __attribute__((cleanup)) ?
 
+  // Workaround for a bug that causes a reference to a nonexistent
+  // destructor under odd circumstances, when attribute no_destroy
+  // is used. This code should not be reachable under normal 
+  // circumstances, this workaround simply checks for the attribute
+  // again and bails if it's present instead of following a path
+  // that's either going to assert or emit incorrect code if reached.
+  if (D.hasAttr<NoDestroyAttr>()) {
+    return;
+  }
+
   QualType type = D.getType();
   QualType::DestructionKind dtorKind = type.isDestructedType();
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54344.173384.patch
Type: text/x-patch
Size: 786 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181109/bbbd980e/attachment-0001.bin>


More information about the cfe-commits mailing list