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