diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5afd263ea1..6bccdaeb24 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -455,12 +455,32 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, << E->getType() << CT)) return ExprError(); - if (!E->getType()->isPODType() && - DiagRuntimeBehavior(E->getLocStart(), 0, + // 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) + // 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. + bool TrivialEnough = false; + if (getLangOptions().CPlusPlus0x && !E->getType()->isDependentType()) { + if (CXXRecordDecl *Record = E->getType()->getAsCXXRecordDecl()) { + if (Record->hasTrivialCopyConstructor() && + Record->hasTrivialMoveConstructor() && + Record->hasTrivialDestructor()) + TrivialEnough = true; + } + } + + if (TrivialEnough) { + // Nothing to diagnose. This is okay. + } else if (DiagRuntimeBehavior(E->getLocStart(), 0, PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) - << E->getType() << CT)) - return ExprError(); - + << getLangOptions().CPlusPlus0x << E->getType() + << CT)) + return ExprError(); + } + return Owned(E); } |