r183388 - When a static storage duration temporary appears in a constant expression, it
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jun 6 01:19:17 PDT 2013
Author: rsmith
Date: Thu Jun 6 03:19:16 2013
New Revision: 183388
URL: http://llvm.org/viewvc/llvm-project?rev=183388&view=rev
Log:
When a static storage duration temporary appears in a constant expression, it
must be initialized by a constant expression (not just a core constant
expression), because we're going to emit it as a global. Core issue for this is
pending.
Modified:
cfe/trunk/lib/AST/ExprConstant.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=183388&r1=183387&r2=183388&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Jun 6 03:19:16 2013
@@ -4099,12 +4099,17 @@ bool LValueExprEvaluator::VisitMateriali
Result.set(E, Info.CurrentCall->Index);
}
+ QualType Type = Inner->getType();
+
// Materialize the temporary itself.
- if (!EvaluateInPlace(*Value, Info, Result, Inner))
+ if (!EvaluateInPlace(*Value, Info, Result, Inner) ||
+ (E->getStorageDuration() == SD_Static &&
+ !CheckConstantExpression(Info, E->getExprLoc(), Type, *Value))) {
+ *Value = APValue();
return false;
+ }
// Adjust our lvalue to refer to the desired subobject.
- QualType Type = Inner->getType();
for (unsigned I = Adjustments.size(); I != 0; /**/) {
--I;
switch (Adjustments[I].Kind) {
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=183388&r1=183387&r2=183388&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Thu Jun 6 03:19:16 2013
@@ -363,6 +363,16 @@ static_assert(&b4 != &b2, "");
// Proposed DR: copy-elision doesn't trigger lifetime extension.
constexpr B b5 = B{ {0}, {0} }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
+namespace NestedNonStatic {
+ // Proposed DR: for a reference constant expression to refer to a static
+ // storage duration temporary, that temporary must itself be initialized
+ // by a constant expression (a core constant expression is not enough).
+ struct A { int &&r; };
+ struct B { A &&a; };
+ constexpr B a = { A{0} }; // ok
+ constexpr B b = { A(A{0}) }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
+}
+
}
constexpr int strcmp_ce(const char *p, const char *q) {
More information about the cfe-commits
mailing list