aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp10
-rw-r--r--lib/CodeGen/CGCall.cpp10
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaExpr.cpp8
4 files changed, 24 insertions, 10 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7fee560534..26c2941804 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -6486,14 +6486,14 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult())
return QualType();
- // functypes which return are preferred over those that do not.
- if (lbaseInfo.getNoReturn() && !rbaseInfo.getNoReturn())
- allLTypes = false;
- else if (!lbaseInfo.getNoReturn() && rbaseInfo.getNoReturn())
- allRTypes = false;
// FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
+ if (lbaseInfo.getNoReturn() != NoReturn)
+ allLTypes = false;
+ if (rbaseInfo.getNoReturn() != NoReturn)
+ allRTypes = false;
+
FunctionType::ExtInfo einfo = lbaseInfo.withNoReturn(NoReturn);
if (lproto && rproto) { // two C99 style function prototypes
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 54ccb86a03..3b39d2e616 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1232,7 +1232,15 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (isPromoted)
V = emitArgumentDemotion(*this, Arg, V);
-
+
+ // Because of merging of function types from multiple decls it is
+ // possible for the type of an argument to not match the corresponding
+ // type in the function type. Since we are codegening the callee
+ // in here, add a cast to the argument type.
+ llvm::Type *LTy = ConvertType(Arg->getType());
+ if (V->getType() != LTy)
+ V = Builder.CreateBitCast(V, LTy);
+
EmitParmDecl(*Arg, V, ArgNo);
break;
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index eb75329461..001a6ac61d 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2402,6 +2402,12 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
if (getLangOpts().CPlusPlus)
return MergeCXXFunctionDecl(New, Old, S);
+ // Merge the function types so the we get the composite types for the return
+ // and argument types.
+ QualType Merged = Context.mergeTypes(Old->getType(), New->getType());
+ if (!Merged.isNull())
+ New->setType(Merged);
+
return false;
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index dd1bc0b657..f6defdaf9f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3730,10 +3730,10 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
(!Param || !Param->hasAttr<CFConsumedAttr>()))
Arg = stripARCUnbridgedCast(Arg);
- InitializedEntity Entity =
- Param? InitializedEntity::InitializeParameter(Context, Param)
- : InitializedEntity::InitializeParameter(Context, ProtoArgType,
- Proto->isArgConsumed(i));
+ InitializedEntity Entity = Param ?
+ InitializedEntity::InitializeParameter(Context, Param, ProtoArgType)
+ : InitializedEntity::InitializeParameter(Context, ProtoArgType,
+ Proto->isArgConsumed(i));
ExprResult ArgE = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(Arg),