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 | 29ad95b2321746f8266c0bcbd4af82618a7df5db (patch) | |
| tree | 8a7d9f57e670192b46e69df3949c81be2f9223ea /clang/lib/Sema/SemaExpr.cpp | |
| parent | 79cfba180a27abea2d250bebce42abdfafc0baf6 (diff) | |
| download | bcm5719-llvm-29ad95b2321746f8266c0bcbd4af82618a7df5db.tar.gz bcm5719-llvm-29ad95b2321746f8266c0bcbd4af82618a7df5db.zip | |
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.
llvm-svn: 138691
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 28ec97f6522..65c9cccaf11 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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(); } } |

