summaryrefslogtreecommitdiff
path: root/tools/llvm-upgrade/UpgradeParser.y
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-01-29 19:07:18 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-01-29 19:07:18 +0000
commitf049c6712d77be98c9b448cf8b696b7bfffee85f (patch)
treef20724e5a680300e77cebfd1647ad1d22bcd0a5c /tools/llvm-upgrade/UpgradeParser.y
parent072200c36dd96b94e772029fd72edf9fa120c467 (diff)
downloadllvm-f049c6712d77be98c9b448cf8b696b7bfffee85f.tar.gz
llvm-f049c6712d77be98c9b448cf8b696b7bfffee85f.tar.bz2
llvm-f049c6712d77be98c9b448cf8b696b7bfffee85f.tar.xz
For PR1142:
When an unresolved definition is found, check to see if it is only unresolved because the csretcc was upgraded to the sret param attribute. Such changes change the function type and lead to unresolved definitions. In such cases, just cast the function to the type expected by the CallInst. That is, cast to the version of the function that has the sret param attribute. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33623 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-upgrade/UpgradeParser.y')
-rw-r--r--tools/llvm-upgrade/UpgradeParser.y43
1 files changed, 39 insertions, 4 deletions
diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y
index 64a20d167c..a5079d43e1 100644
--- a/tools/llvm-upgrade/UpgradeParser.y
+++ b/tools/llvm-upgrade/UpgradeParser.y
@@ -505,6 +505,25 @@ static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) {
// and back patchs after we are done.
//
+/// This function determines if two function types differ only in their use of
+/// the sret parameter attribute in the first argument. If they are identical
+/// in all other respects, it returns true. Otherwise, it returns false.
+bool FuncTysDifferOnlyBySRet(const FunctionType *F1,
+ const FunctionType *F2) {
+ if (F1->getReturnType() != F2->getReturnType() ||
+ F1->getNumParams() != F2->getNumParams() ||
+ F1->getParamAttrs(0) != F2->getParamAttrs(0))
+ return false;
+ unsigned SRetMask = ~unsigned(FunctionType::StructRetAttribute);
+ for (unsigned i = 0; i < F1->getNumParams(); ++i) {
+ if (F1->getParamType(i) != F2->getParamType(i) ||
+ unsigned(F1->getParamAttrs(i+1)) & SRetMask !=
+ unsigned(F2->getParamAttrs(i+1)) & SRetMask)
+ return false;
+ }
+ return true;
+}
+
// ResolveDefinitions - If we could not resolve some defs at parsing
// time (forward branches, phi functions for loops, etc...) resolve the
// defs now...
@@ -537,10 +556,26 @@ ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers,
InsertValue(V, *FutureLateResolvers);
} else {
if (DID.Type == ValID::NameVal) {
- error("Reference to an invalid definition: '" +DID.getName()+
- "' of type '" + V->getType()->getDescription() + "'",
- PHI->second.second);
- return;
+ // The upgrade of csretcc to sret param attribute may have caused a
+ // function to not be found because the param attribute changed the
+ // type of the called function. Detect this situation and insert a
+ // cast as necessary.
+ bool fixed = false;
+ if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
+ if (const FunctionType *FTy =
+ dyn_cast<FunctionType>(PTy->getElementType()))
+ if (Function *OtherF =
+ CurModule.CurrentModule->getNamedFunction(DID.getName()))
+ if (FuncTysDifferOnlyBySRet(FTy,OtherF->getFunctionType())) {
+ V->replaceAllUsesWith(ConstantExpr::getBitCast(OtherF, PTy));
+ fixed = true;
+ }
+ if (!fixed) {
+ error("Reference to an invalid definition: '" +DID.getName()+
+ "' of type '" + V->getType()->getDescription() + "'",
+ PHI->second.second);
+ return;
+ }
} else {
error("Reference to an invalid definition: #" +
itostr(DID.Num) + " of type '" +