On Tue, Nov 19, 2013 at 10:18 PM, Karthik Bhat <[email protected]> wrote:
> Hi rsmith, > > Hi All,Richard, > I would like to get few inputs regarding the issue mentioned below. > Clang fails to compile gcc test case constexpr-initlist2.C with c++11 ( > http://searchcode.com/codesearch/view/8022759) > > lvalue-to-rvalue conversion seems to be failing. > > As per standard [expr.const] - > an lvalue-to-rvalue conversion [is not allowed unless it applies to] > [....] > — a non-volatile glvalue that refers to a non-volatile object defined with > constexpr, or that refers > to a non-mutable sub-object of such an object > This does not apply to your testcase. The testcase creates, and tries to read from, an array temporary (which is not a non-volatile object defined with 'constexpr' nor a subobject thereof). [....] > > Hence as per standard it seems clang should be able to compile the above > code(constexpr-initlist2.C) > > The problem seems we are not handling this case on ExprConstant > findCompleteObject function. Added a patch to fix the same. > I would like to get inputs from community if this is the right approach? > Will update/add the test case in case the approach is correct. > > Thanks > Karthik Bhat > > http://llvm-reviews.chandlerc.com/D2226 > > Files: > lib/AST/ExprConstant.cpp > > Index: lib/AST/ExprConstant.cpp > =================================================================== > --- lib/AST/ExprConstant.cpp > +++ lib/AST/ExprConstant.cpp > @@ -2503,6 +2503,9 @@ > // [...] > // - a [...] glvalue of literal type that refers to a > non-volatile > // object whose lifetime began within the evaluation of e. > + // [...] > + // - a [...] glvalue that refers to a non-volatile object > + // defined with constexpr > // > // C++11 misses the 'began within the evaluation of e' check and > // instead allows all temporaries, including things like: > This text explains what we're doing here, and why. > @@ -2512,8 +2515,10 @@ > // Therefore we use the C++1y rules in C++11 too. > const ValueDecl *VD = Info.EvaluatingDecl.dyn_cast<const > ValueDecl*>(); > const ValueDecl *ED = MTE->getExtendingDecl(); > + const VarDecl* VarD = dyn_cast<const VarDecl>(ED); > if (!(BaseType.isConstQualified() && > BaseType->isIntegralOrEnumerationType()) && > + !(VarD && VarD->isConstexpr()) && > !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) { > Info.Diag(E, diag::note_constexpr_access_static_temporary, 1) > << AK; > Info.Note(MTE->getExprLoc(), > diag::note_constexpr_temporary_here); > That change is not correct; it allows this: constexpr int &&r = 0; ++r; constexpr int n = r; // would have value 0 with your patch
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
