[PATCH] An lvalue-to-rvalue conversion should be supported in case of a non-volatile glvalue that refers to a non-volatile object defined with constexpr.

Karthik Bhat kv.bhat at samsung.com
Tue Nov 19 22:18:52 PST 2013


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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2226.1.patch
Type: text/x-patch
Size: 1295 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131119/fed8641c/attachment.bin>


More information about the cfe-commits mailing list