diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 6bccdaeb24..ce929d58ee 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -449,13 +449,13 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, if (FDecl && FDecl->getBuiltinID() == Builtin::BI__builtin_va_start) return Owned(E); + // Don't allow one to pass an Objective-C interface to a vararg. if (E->getType()->isObjCObjectType() && - DiagRuntimeBehavior(E->getLocStart(), 0, - PDiag(diag::err_cannot_pass_objc_interface_to_vararg) - << E->getType() << CT)) + DiagRuntimeBehavior(E->getLocStart(), 0, + PDiag(diag::err_cannot_pass_objc_interface_to_vararg) + << E->getType() << CT)) return ExprError(); - - // C++ [expr.call]p7 prohibits non-POD types. + if (!E->getType()->isPODType()) { // C++0x [expr.call]p7: // Passing a potentially-evaluated argument of class type (Clause 9) @@ -477,8 +477,28 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, } else if (DiagRuntimeBehavior(E->getLocStart(), 0, PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) << getLangOptions().CPlusPlus0x << E->getType() - << CT)) - return ExprError(); + << CT)) { + // Turn this into a trap. + CXXScopeSpec SS; + UnqualifiedId Name; + Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"), + E->getLocStart()); + ExprResult TrapFn = ActOnIdExpression(TUScope, SS, Name, true, false); + if (TrapFn.isInvalid()) + return ExprError(); + + ExprResult Call = ActOnCallExpr(TUScope, TrapFn.get(), E->getLocStart(), + MultiExprArg(), E->getLocEnd()); + if (Call.isInvalid()) + return ExprError(); + + ExprResult Comma = ActOnBinOp(TUScope, E->getLocStart(), tok::comma, + Call.get(), E); + if (Comma.isInvalid()) + return ExprError(); + + E = Comma.get(); + } } return Owned(E); |