diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-19 18:10:23 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-19 18:10:23 +0000 |
commit | ddcfbc9ad1817f545610999d655ac6c28d4c0c12 (patch) | |
tree | d05af342f901642c4e1813eeb9c509a7c38372fb /lib/Sema/SemaExpr.cpp | |
parent | b13291aa59c4c074e70f2d0181f9721e38b494d4 (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.cpp | 27 |
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) { |