diff options
author | John McCall <rjmccall@apple.com> | 2011-08-27 01:09:30 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-08-27 01:09:30 +0000 |
commit | 5f8d604246976a93a73549b07bbc8ee0b2061b50 (patch) | |
tree | 77e085a2358201b9007429ba7cec2b156f556a3a /lib/Sema/SemaExpr.cpp | |
parent | 6748ae15b3eed61b3b61f9b77470a802a1643fbb (diff) |
The lvalue-to-rvalue on structs in C++ is actually part
of default argument promotion and needs to happen unconditionally.
This is particularly semantically important in C++0x.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138691 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 28ec97f652..65c9cccaf1 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -443,6 +443,18 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { if (Ty->isSpecificBuiltinType(BuiltinType::Float)) E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take(); + // C++ includes lvalue-to-rvalue conversion as a default argument + // promotion. If we have a gl-value, initialize a temporary. + if (getLangOptions().CPlusPlus && E->isGLValue()) { + ExprResult Temp = PerformCopyInitialization( + InitializedEntity::InitializeTemporary(E->getType()), + E->getExprLoc(), + Owned(E)); + if (Temp.isInvalid()) + return ExprError(); + E = Temp.get(); + } + return Owned(E); } @@ -460,19 +472,13 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, return ExprError(); E = ExprRes.take(); - // __builtin_va_start takes the second argument as a "varargs" argument, but - // it doesn't actually do anything with it. It doesn't need to be non-pod - // etc. - 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)) return ExprError(); - + if (!E->getType().isPODType(Context)) { // C++0x [expr.call]p7: // Passing a potentially-evaluated argument of class type (Clause 9) @@ -519,16 +525,6 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, if (Comma.isInvalid()) return ExprError(); E = Comma.get(); - - // Use that to initialize a temporary, or else we might get an - // l-value in a varargs position. - ExprResult Temp = PerformCopyInitialization( - InitializedEntity::InitializeTemporary(E->getType()), - E->getLocStart(), - Owned(E)); - if (Temp.isInvalid()) - return ExprError(); - E = Temp.get(); } } |