aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-07-19 18:10:23 +0000
committerJordan Rose <jordan_rose@apple.com>2012-07-19 18:10:23 +0000
commitddcfbc9ad1817f545610999d655ac6c28d4c0c12 (patch)
treed05af342f901642c4e1813eeb9c509a7c38372fb /lib/Sema/SemaExpr.cpp
parentb13291aa59c4c074e70f2d0181f9721e38b494d4 (diff)
For varargs, diagnose passing ObjC objects by value like other non-POD types.
While we still want to consider this a hard error (non-POD variadic args are normally a DefaultError warning), delaying the diagnostic allows us to give better error messages, which also match the usual non-POD errors more closely. In addition, this change improves the diagnostic messages for format string argument type mismatches by passing down the type of the callee, so we can say "variadic method" or "variadic function" appropriately. <rdar://problem/11825593> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160517 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp27
1 files changed, 16 insertions, 11 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 177165c79e..f2e50ba77b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -602,14 +602,20 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
/// Incomplete types are considered POD, since this check can be performed
/// when we're in an unevaluated context.
Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) {
- if (Ty->isIncompleteType() || Ty.isCXX98PODType(Context))
+ if (Ty->isIncompleteType()) {
+ if (Ty->isObjCObjectType())
+ return VAK_Invalid;
return VAK_Valid;
+ }
+
+ if (Ty.isCXX98PODType(Context))
+ return VAK_Valid;
+
// C++0x [expr.call]p7:
// Passing a potentially-evaluated argument of class type (Clause 9)
// having a non-trivial copy constructor, a non-trivial move constructor,
// or a non-trivial destructor, with no corresponding parameter,
// is conditionally-supported with implementation-defined semantics.
-
if (getLangOpts().CPlusPlus0x && !Ty->isDependentType())
if (CXXRecordDecl *Record = Ty->getAsCXXRecordDecl())
if (Record->hasTrivialCopyConstructor() &&
@@ -635,18 +641,23 @@ bool Sema::variadicArgumentPODCheck(const Expr *E, VariadicCallType CT) {
PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg)
<< E->getType() << CT);
break;
- case VAK_Invalid:
+ case VAK_Invalid: {
+ if (Ty->isObjCObjectType())
+ return DiagRuntimeBehavior(E->getLocStart(), 0,
+ PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
+ << Ty << CT);
+
return DiagRuntimeBehavior(E->getLocStart(), 0,
PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg)
<< getLangOpts().CPlusPlus0x << Ty << CT);
}
+ }
// c++ rules are enforced elsewhere.
return false;
}
/// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
-/// will warn if the resulting type is not a POD type, and rejects ObjC
-/// interfaces passed by value.
+/// will create a trap if the resulting type is not a POD type.
ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
FunctionDecl *FDecl) {
if (const BuiltinType *PlaceholderTy = E->getType()->getAsPlaceholderType()) {
@@ -670,12 +681,6 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
return ExprError();
E = ExprRes.take();
- if (E->getType()->isObjCObjectType() &&
- DiagRuntimeBehavior(E->getLocStart(), 0,
- PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
- << E->getType() << CT))
- return ExprError();
-
// Diagnostics regarding non-POD argument types are
// emitted along with format string checking in Sema::CheckFunctionCall().
if (isValidVarArgType(E->getType()) == VAK_Invalid) {