summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.h2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp25
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp8
-rw-r--r--clang/lib/Sema/SemaOverload.cpp14
4 files changed, 30 insertions, 19 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 8138379af7c..5018833267d 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -2210,7 +2210,7 @@ public:
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
// will warn if the resulting type is not a POD type.
- void DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
+ bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
// operands and then handles various conversions that are common to binary
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f2820df93e8..e380f78ad05 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -154,16 +154,25 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
UsualUnaryConversions(Expr);
}
-// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
-// will warn if the resulting type is not a POD type.
-void Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
+/// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
+/// will warn if the resulting type is not a POD type, and rejects ObjC
+/// interfaces passed by value. This returns true if the argument type is
+/// completely illegal.
+bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
DefaultArgumentPromotion(Expr);
- if (!Expr->getType()->isPODType()) {
- Diag(Expr->getLocStart(),
- diag::warn_cannot_pass_non_pod_arg_to_vararg) <<
- Expr->getType() << CT;
+ if (Expr->getType()->isObjCInterfaceType()) {
+ Diag(Expr->getLocStart(),
+ diag::err_cannot_pass_objc_interface_to_vararg)
+ << Expr->getType() << CT;
+ return true;
}
+
+ if (!Expr->getType()->isPODType())
+ Diag(Expr->getLocStart(), diag::warn_cannot_pass_non_pod_arg_to_vararg)
+ << Expr->getType() << CT;
+
+ return false;
}
@@ -2223,7 +2232,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
// Promote the arguments (C99 6.5.2.2p7).
for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
Expr *Arg = Args[i];
- DefaultVariadicArgumentPromotion(Arg, CallType);
+ Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
Call->setArg(i, Arg);
}
}
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 54a18ac832a..8d8fae035a1 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -164,7 +164,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
unsigned NumNamedArgs = Sel.getNumArgs();
assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
- bool anyIncompatibleArgs = false;
+ bool IsError = false;
for (unsigned i = 0; i < NumNamedArgs; i++) {
Expr *argExpr = Args[i];
assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
@@ -183,7 +183,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
if (Args[i] != argExpr) // The expression was converted.
Args[i] = argExpr; // Make sure we store the converted expression.
- anyIncompatibleArgs |=
+ IsError |=
DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
argExpr, "sending");
}
@@ -191,7 +191,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
// Promote additional arguments to variadic methods.
if (Method->isVariadic()) {
for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
- DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
+ IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
} else {
// Check for extra arguments to non-variadic methods.
if (NumArgs != NumNamedArgs) {
@@ -203,7 +203,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
}
}
- return anyIncompatibleArgs;
+ return IsError;
}
bool Sema::isSelfExpr(Expr *RExpr) {
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 0a12a71bb74..875a38253da 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -4178,11 +4178,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
else if (NumArgs > NumArgsInProto)
NumArgsToCheck = NumArgsInProto;
+ bool IsError = false;
+
// Initialize the implicit object parameter.
- if (PerformObjectArgumentInitialization(Object, Method))
- return true;
+ IsError |= PerformObjectArgumentInitialization(Object, Method);
TheCall->setArg(0, Object);
+
// Check the argument types.
for (unsigned i = 0; i != NumArgsToCheck; i++) {
Expr *Arg;
@@ -4191,8 +4193,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Pass the argument.
QualType ProtoArgType = Proto->getArgType(i);
- if (PerformCopyInitialization(Arg, ProtoArgType, "passing"))
- return true;
+ IsError |= PerformCopyInitialization(Arg, ProtoArgType, "passing");
} else {
Arg = new (Context) CXXDefaultArgExpr(Method->getParamDecl(i));
}
@@ -4205,12 +4206,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Promote the arguments (C99 6.5.2.2p7).
for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
Expr *Arg = Args[i];
-
- DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
+ IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
TheCall->setArg(i + 1, Arg);
}
}
+ if (IsError) return true;
+
return CheckFunctionCall(Method, TheCall.take()).release();
}
OpenPOWER on IntegriCloud