summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVTables.cpp
diff options
context:
space:
mode:
authorWolfgang Pieb <Wolfgang.Pieb@sony.com>2017-10-31 22:49:48 +0000
committerWolfgang Pieb <Wolfgang.Pieb@sony.com>2017-10-31 22:49:48 +0000
commita9fba7b0ec1b2384f171950089021fadec7da08b (patch)
tree4ec246a192bb619f8b8b615ea2b28e054f6e0830 /lib/CodeGen/CGVTables.cpp
parent746fd88cc65883572b7602dc7b1f9e74462fd451 (diff)
downloadclang-a9fba7b0ec1b2384f171950089021fadec7da08b.tar.gz
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@317047 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVTables.cpp')
-rw-r--r--lib/CodeGen/CGVTables.cpp34
1 files changed, 33 insertions, 1 deletions
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 64b6d0d3fe..67388ee208 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/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);