r180866 - PR15884: In the 'taking the address of a temporary' extension, materialize the
Richard Smith
richard-llvm at metafoo.co.uk
Wed May 1 12:00:39 PDT 2013
Author: rsmith
Date: Wed May 1 14:00:39 2013
New Revision: 180866
URL: http://llvm.org/viewvc/llvm-project?rev=180866&view=rev
Log:
PR15884: In the 'taking the address of a temporary' extension, materialize the
temporary to an lvalue before taking its address. This removes a weird special
case from the AST representation, and allows the constant expression evaluator
to deal with it without (broken) hacks.
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=180866&r1=180865&r2=180866&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed May 1 14:00:39 2013
@@ -3215,14 +3215,12 @@ public:
} // end anonymous namespace
/// Evaluate an expression as an lvalue. This can be legitimately called on
-/// expressions which are not glvalues, in a few cases:
-/// * function designators in C,
-/// * "extern void" objects,
-/// * temporaries, if building with -Wno-address-of-temporary.
-static bool EvaluateLValue(const Expr* E, LValue& Result, EvalInfo &Info) {
- assert((E->isGLValue() || E->getType()->isFunctionType() ||
- E->getType()->isVoidType() || isa<CXXTemporaryObjectExpr>(E)) &&
- "can't evaluate expression as an lvalue");
+/// expressions which are not glvalues, in two cases:
+/// * function designators in C, and
+/// * "extern void" objects
+static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) {
+ assert(E->isGLValue() || E->getType()->isFunctionType() ||
+ E->getType()->isVoidType());
return LValueExprEvaluator(Info, Result).Visit(E);
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=180866&r1=180865&r2=180866&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed May 1 14:00:39 2013
@@ -8306,6 +8306,9 @@ static QualType CheckAddressOfOperand(Se
<< op->getType() << op->getSourceRange();
if (sfinae)
return QualType();
+ // Materialize the temporary as an lvalue so that we can take its address.
+ OrigOp = op = new (S.Context)
+ MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true);
} else if (isa<ObjCSelectorExpr>(op)) {
return S.Context.getPointerType(op->getType());
} else if (lval == Expr::LV_MemberFunction) {
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=180866&r1=180865&r2=180866&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed May 1 14:00:39 2013
@@ -1480,3 +1480,13 @@ namespace ArrayEltInit {
static_assert(b[0].p != &b[9].p, "");
static_assert(b[9].p != &b[0].p, "");
}
+
+namespace PR15884 {
+ struct S {};
+ constexpr S f() { return {}; }
+ constexpr S *p = &f();
+ // expected-error at -1 {{taking the address of a temporary}}
+ // expected-error at -2 {{constexpr variable 'p' must be initialized by a constant expression}}
+ // expected-note at -3 {{pointer to temporary is not a constant expression}}
+ // expected-note at -4 {{temporary created here}}
+}
More information about the cfe-commits
mailing list