aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-07-01 06:20:47 +0000
committerChris Lattner <sabre@nondot.org>2010-07-01 06:20:47 +0000
commita9fa85841102e81daaa23650d89b120fe9dacedc (patch)
treeb304a3a717edbf0a419ce980150dbce8b2f89522 /lib/CodeGen
parentd92ec474faeb6133e0d41f0de4526b22778476f2 (diff)
fix rdar://8147692 - yet another crash due to my abi work.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107387 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGCall.cpp23
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp27
-rw-r--r--lib/CodeGen/CodeGenTypes.h6
3 files changed, 41 insertions, 15 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 29104424ac..c0c2a47207 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -251,18 +251,27 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy,
// If this is being called from the guts of the ConvertType loop, make sure
// to call ConvertTypeRecursive so we don't get into issues with cyclic
// pointer type structures.
- const llvm::Type *ArgType;
- if (IsRecursive)
- ArgType = ConvertTypeRecursive(*I);
- else
- ArgType = ConvertType(*I);
- PreferredArgTypes.push_back(ArgType);
+ PreferredArgTypes.push_back(ConvertTypeRecursive(*I));
}
-
+
// Compute ABI information.
getABIInfo().computeInfo(*FI, getContext(), TheModule.getContext(),
PreferredArgTypes.data(), PreferredArgTypes.size());
+ // If this is a top-level call and ConvertTypeRecursive hit unresolved pointer
+ // types, resolve them now. These pointers may point to this function, which
+ // we *just* filled in the FunctionInfo for.
+ if (!IsRecursive && !PointersToResolve.empty()) {
+ // Use PATypeHolder's so that our preferred types don't dangle under
+ // refinement.
+ llvm::SmallVector<llvm::PATypeHolder, 8> Handles(PreferredArgTypes.begin(),
+ PreferredArgTypes.end());
+ HandleLateResolvedPointers();
+ PreferredArgTypes.clear();
+ PreferredArgTypes.append(Handles.begin(), Handles.end());
+ }
+
+
return *FI;
}
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 7876e5aefc..d469b906fc 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -42,14 +42,11 @@ CodeGenTypes::~CodeGenTypes() {
delete &*I++;
}
-/// ConvertType - Convert the specified type to its LLVM form.
-const llvm::Type *CodeGenTypes::ConvertType(QualType T, bool IsRecursive) {
- const llvm::Type *RawResult = ConvertTypeRecursive(T);
-
- if (IsRecursive || PointersToResolve.empty())
- return RawResult;
-
- llvm::PATypeHolder Result = RawResult;
+/// HandleLateResolvedPointers - For top-level ConvertType calls, this handles
+/// pointers that are referenced but have not been converted yet. This is used
+/// to handle cyclic structures properly.
+void CodeGenTypes::HandleLateResolvedPointers() {
+ assert(!PointersToResolve.empty() && "No pointers to resolve!");
// Any pointers that were converted deferred evaluation of their pointee type,
// creating an opaque type instead. This is in order to avoid problems with
@@ -64,7 +61,21 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T, bool IsRecursive) {
const llvm::Type *NT = ConvertTypeForMemRecursive(P.first);
P.second->refineAbstractTypeTo(NT);
}
+}
+
+/// ConvertType - Convert the specified type to its LLVM form.
+const llvm::Type *CodeGenTypes::ConvertType(QualType T, bool IsRecursive) {
+ const llvm::Type *Result = ConvertTypeRecursive(T);
+
+ // If this is a top-level call to ConvertType and sub-conversions caused
+ // pointers to get lazily built as opaque types, resolve the pointers, which
+ // might cause Result to be merged away.
+ if (!IsRecursive && !PointersToResolve.empty()) {
+ llvm::PATypeHolder ResultHandle = Result;
+ HandleLateResolvedPointers();
+ Result = ResultHandle;
+ }
return Result;
}
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index bf55fc5369..c7f48e6c9d 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -94,6 +94,12 @@ private:
/// is available only for ConvertType(). CovertType() is preferred
/// interface to convert type T into a llvm::Type.
const llvm::Type *ConvertNewType(QualType T);
+
+ /// HandleLateResolvedPointers - For top-level ConvertType calls, this handles
+ /// pointers that are referenced but have not been converted yet. This is
+ /// used to handle cyclic structures properly.
+ void HandleLateResolvedPointers();
+
public:
CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD,
const ABIInfo &Info);