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
[....]

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:
@@ -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);
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:
@@ -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);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to