diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 36addddcc5cf97efc19eb962099177698a8d8267..9df53cd5bf0d3803b7d0b81a5887904a8f13fcb0 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -832,7 +832,8 @@ static bool IsGlobalLValue(APValue::LValueBase B) { /// Check that this reference or pointer core constant expression is a valid /// value for an address or reference constant expression. Type T should be -/// either LValue or CCValue. +/// either LValue or CCValue. Return true if we can fold this expression, +/// whether or not it's a constant expression. template<typename T> static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E, const T &LVal, APValue &Value, @@ -854,19 +855,15 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E, } else { Info.Diag(E->getExprLoc()); } + // Don't allow references to temporaries to escape. return false; } bool IsReferenceType = E->isGLValue(); if (Designator.Invalid) { - // This is not a core constant expression. A diagnostic will have already - // been produced. - if (IsReferenceType) - return false; - - // Allow this for pointers, so we can fold things like integers cast to - // pointers. + // This is not a core constant expression. An appropriate diagnostic will + // have already been produced. Value = APValue(LVal.getLValueBase(), LVal.getLValueOffset(), APValue::NoLValuePath()); return true; @@ -884,7 +881,7 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E, if (!Base) { // FIXME: diagnostic Info.CCEDiag(E->getExprLoc()); - return false; + return true; } // Does this refer one past the end of some object? @@ -897,7 +894,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, const Expr *E, else Info.Note(Base.dyn_cast<const Expr*>()->getExprLoc(), diag::note_constexpr_temporary_here); - return false; } return true; diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp index 78d78b64c7aeeabd92a9d09f1311dd0cef8a05e9..cece22d9b2388514c15e4daa5cadca59e16f0036 100644 --- a/test/CXX/expr/expr.const/p2-0x.cpp +++ b/test/CXX/expr/expr.const/p2-0x.cpp @@ -134,8 +134,9 @@ namespace UndefinedBehavior { constexpr const int &f(const int *q) { return q[0]; // expected-note {{dereferenced pointer past the end of subobject of 's' is not a constant expression}} } + constexpr int n = (f(p), 0); // expected-error {{constant expression}} expected-note {{in call to 'f(&s.m + 1)'}} struct T { - int n : f(p); // expected-error {{not an integer constant expression}} expected-note {{in call to 'f(&s.m + 1)'}} + int n : f(p); // expected-error {{not an integer constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} }; namespace Ptr { diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp index 1cfcdba22f898eb4e9cb22be4a1f3602ef6606f8..201ce8f0c64cbe0537f1cb95ba606012949e9f54 100644 --- a/test/CodeGenCXX/const-init.cpp +++ b/test/CodeGenCXX/const-init.cpp @@ -69,3 +69,10 @@ void UnfoldableAddrLabelDiff() { static __int128_t x = (long)&&a-(long)&&b; a:b: // But make sure we do fold this. // CHECK: @_ZZ21FoldableAddrLabelDiffvE1x = internal global i64 sub (i64 ptrtoint (i8* blockaddress(@_Z21FoldableAddrLabelDiffv void FoldableAddrLabelDiff() { static long x = (long)&&a-(long)&&b; a:b:return;} + +// CHECK: @i = constant i32* bitcast (float* @PR9558 to i32*) +int &i = reinterpret_cast<int&>(PR9558); + +int arr[2]; +// CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) +int &pastEnd = arr[2]; diff --git a/www/cxx_status.html b/www/cxx_status.html index 0dc1b86712a59e3a75171b4f5f9f99137f467497..742d54e3ff018198a6c528c0c6dca5b078f4bf51 100644 --- a/www/cxx_status.html +++ b/www/cxx_status.html @@ -8,7 +8,7 @@ <link type="text/css" rel="stylesheet" href="content.css"> <style type="text/css"> .none { background-color: #FFCCCC } - .partial { background-color: #FFFF99 } + .svn { background-color: #FFFF99 } .full { background-color: #CCFF99 } th { background-color: #FFDDAA } </style> @@ -156,7 +156,7 @@ with clang; other versions have not been tested.</p> <td> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf">N2764 </a></td> - <td class="none" align="center">No</td> + <td class="svn" align="center">SVN</td> </tr> <tr> <td>Generalized attributes</td> @@ -238,7 +238,7 @@ with clang; other versions have not been tested.</p> <tr> <td>Extending <code>sizeof</code></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html">N2253</a></td> - <td class="none" align="center">No</td> + <td class="svn" align="center">SVN</td> </tr> <tr> <td>Inline namespaces</td>