[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.
Richard Smith
richard at metafoo.co.uk
Wed Nov 20 11:59:24 PST 2013
On Tue, Nov 19, 2013 at 10:18 PM, Karthik Bhat <kv.bhat at samsung.com> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131120/866e8ecd/attachment.html>
More information about the cfe-commits
mailing list