diff options
| author | Wolfgang Pieb <Wolfgang.Pieb@sony.com> | 2017-10-31 22:49:48 +0000 | 
|---|---|---|
| committer | Wolfgang Pieb <Wolfgang.Pieb@sony.com> | 2017-10-31 22:49:48 +0000 | 
| commit | a347c47f5df33c4d5d38b6ec1790ad429e817e15 (patch) | |
| tree | bf15878a409d3c6bd0f26db8c465cba631044edd | |
| parent | aedb4bf37f74bede581951e91d1e205ccaac1408 (diff) | |
| download | bcm5719-llvm-a347c47f5df33c4d5d38b6ec1790ad429e817e15.tar.gz bcm5719-llvm-a347c47f5df33c4d5d38b6ec1790ad429e817e15.zip | |
Fix for PR33930. Short-circuit metadata mapping when cloning a varargs thunk.
The cloning happens before all metadata nodes are resolved. Prevent the value
mapper from running into unresolved or temporary MD nodes.
Differential Revision: https://reviews.llvm.org/D39396
llvm-svn: 317047
| -rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 34 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/tmp-md-nodes1.cpp | 18 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/tmp-md-nodes2.cpp | 33 | 
3 files changed, 84 insertions, 1 deletions
| diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 64b6d0d3fe9..67388ee208d 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -14,11 +14,12 @@  #include "CGCXXABI.h"  #include "CodeGenFunction.h"  #include "CodeGenModule.h" -#include "clang/CodeGen/ConstantInitBuilder.h"  #include "clang/AST/CXXInheritance.h"  #include "clang/AST/RecordLayout.h"  #include "clang/CodeGen/CGFunctionInfo.h" +#include "clang/CodeGen/ConstantInitBuilder.h"  #include "clang/Frontend/CodeGenOptions.h" +#include "llvm/IR/IntrinsicInst.h"  #include "llvm/Support/Format.h"  #include "llvm/Transforms/Utils/Cloning.h"  #include <algorithm> @@ -122,6 +123,33 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF,    return RValue::get(ReturnValue);  } +/// This function clones a function's DISubprogram node and enters it into  +/// a value map with the intent that the map can be utilized by the cloner +/// to short-circuit Metadata node mapping. +/// Furthermore, the function resolves any DILocalVariable nodes referenced +/// by dbg.value intrinsics so they can be properly mapped during cloning. +static void resolveTopLevelMetadata(llvm::Function *Fn, +                                    llvm::ValueToValueMapTy &VMap) { +  // Clone the DISubprogram node and put it into the Value map. +  auto *DIS = Fn->getSubprogram(); +  if (!DIS) +    return; +  auto *NewDIS = DIS->replaceWithDistinct(DIS->clone()); +  VMap.MD()[DIS].reset(NewDIS); + +  // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes +  // they are referencing. +  for (auto &BB : Fn->getBasicBlockList()) { +    for (auto &I : BB) { +      if (auto *DII = dyn_cast<llvm::DbgInfoIntrinsic>(&I)) { +        auto *DILocal = DII->getVariable(); +        if (!DILocal->isResolved()) +          DILocal->resolve(); +      } +    } +  } +} +  // This function does roughly the same thing as GenerateThunk, but in a  // very different way, so that va_start and va_end work correctly.  // FIXME: This function assumes "this" is the first non-sret LLVM argument of @@ -154,6 +182,10 @@ CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn,    // Clone to thunk.    llvm::ValueToValueMapTy VMap; + +  // We are cloning a function while some Metadata nodes are still unresolved. +  // Ensure that the value mapper does not encounter any of them. +  resolveTopLevelMetadata(BaseFn, VMap);    llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);    Fn->replaceAllUsesWith(NewFn);    NewFn->takeName(Fn); diff --git a/clang/test/CodeGenCXX/tmp-md-nodes1.cpp b/clang/test/CodeGenCXX/tmp-md-nodes1.cpp new file mode 100644 index 00000000000..3957f60bc60 --- /dev/null +++ b/clang/test/CodeGenCXX/tmp-md-nodes1.cpp @@ -0,0 +1,18 @@ +// REQUIRES: asserts +// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s + +// This test simply checks that the varargs thunk is created. The failing test +// case asserts. + +struct Alpha { +  virtual void bravo(...); +}; +struct Charlie { +  virtual ~Charlie() {} +}; +struct CharlieImpl : Charlie, Alpha { +  void bravo(...) {} +} delta; + +// CHECK: define {{.*}} void @_ZThn8_N11CharlieImpl5bravoEz( diff --git a/clang/test/CodeGenCXX/tmp-md-nodes2.cpp b/clang/test/CodeGenCXX/tmp-md-nodes2.cpp new file mode 100644 index 00000000000..00827f59141 --- /dev/null +++ b/clang/test/CodeGenCXX/tmp-md-nodes2.cpp @@ -0,0 +1,33 @@ +// REQUIRES: asserts +// RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s + +// This test simply checks that the varargs thunk is created. The failing test +// case asserts. + +typedef signed char __int8_t; +typedef int BOOL; +class CMsgAgent; + +class CFs { +public: +  typedef enum {} CACHE_HINT; +  virtual BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) ; +}; + +typedef struct {} _Lldiv_t; + +class CBdVfs { +public: +  virtual ~CBdVfs( ) {} +}; + +class CBdVfsImpl : public CBdVfs, public CFs { +  BOOL ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ); +}; + +BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT hint, ... ) { +  return true; +} + +// CHECK: define {{.*}} @_ZThn8_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz( | 

