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 /clang/lib/CodeGen/CGVTables.cpp | |
parent | aedb4bf37f74bede581951e91d1e205ccaac1408 (diff) | |
download | llvm-a347c47f5df33c4d5d38b6ec1790ad429e817e15.zip llvm-a347c47f5df33c4d5d38b6ec1790ad429e817e15.tar.gz llvm-a347c47f5df33c4d5d38b6ec1790ad429e817e15.tar.bz2 |
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
Diffstat (limited to 'clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 64b6d0d..67388ee 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); |