diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-05-21 16:27:21 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-05-21 16:27:21 +0000 |
commit | 0fd228d48bbf05d08d9b408023d7c8ddb681bc91 (patch) | |
tree | a671da0c91fc60831d0f15488f6c49786a364a3c /lib/Sema/SemaExpr.cpp | |
parent | e26224e61c8a3b607c73c52f2cd0344065d7b412 (diff) |
Implement C++0x semantics for passing non-POD classes through varargs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131792 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-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); } |