Thread overview
[Issue 11268] New: [REG 2.064beta] cannot use non-constant CTFE pointer in an initializer
Oct 15, 2013
Jacob Carlborg
Oct 16, 2013
Don
Oct 16, 2013
Jacob Carlborg
Oct 17, 2013
Don
Oct 17, 2013
Luís Marques
[Issue 11268] Cannot use non-constant CTFE pointer in an initializer
Oct 18, 2013
Don
Oct 18, 2013
Jacob Carlborg
October 15, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11268

           Summary: [REG 2.064beta] cannot use non-constant CTFE pointer
                    in an initializer
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: doob@me.com


--- Comment #0 from Jacob Carlborg <doob@me.com> 2013-10-15 00:54:51 PDT ---
This code fails to compile with DMD 2.064 beta:

class OS
{
    static const char[] REBARCLASSNAME = "ReBarWindow32";
}

class CoolBar
{
    static const char* ReBarClass = OS.REBARCLASSNAME.ptr; // line 14
}

Error message:

main.d(14): Error: cannot use non-constant CTFE pointer in an initializer
'"ReBarWindow32"[0]'

The commit that caused this regression is:

43a6c87194cae799650249b10a4f7c910081d280

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 16, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11268



--- Comment #1 from Don <clugdbug@yahoo.com.au> 2013-10-16 07:08:18 PDT ---
Did this actually work correctly before?

Or was it acting as macro, ie was equivalent to:
   static const char* ReBarClass = "ReBarWindow32".ptr;
?

Tests that I've done suggest that it was acting as a macro.
Obviously this should work. But is it actually a regression, or a change from
wrong-code --> rejects-valid ?

In any case it is probably just an over-zealous check in init.c :
hasNonConstPointers().

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 16, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11268



--- Comment #2 from Jacob Carlborg <doob@me.com> 2013-10-16 11:51:50 PDT ---
(In reply to comment #1)
> Did this actually work correctly before?
> 
> Or was it acting as macro, ie was equivalent to:
>    static const char* ReBarClass = "ReBarWindow32".ptr;
> ?

What do you mean "acting as a macro"?

> Tests that I've done suggest that it was acting as a macro.
> Obviously this should work. But is it actually a regression, or a change from
> wrong-code --> rejects-valid ?

I don't know. All I'm saying is that it used to compile but now it doesn't.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 17, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11268



--- Comment #3 from Don <clugdbug@yahoo.com.au> 2013-10-16 18:46:18 PDT ---
This isn't a regression. It used to compile, but it generated wrong code. Here's a reduced case:
---
static const char [] x = "abc";
static const char *p = x.ptr;

void main()
{
   assert(p == x.ptr);
}
---
2.063: compiles, but assert fails
2.064: does not compile.
That's an improvement.

With the way the glue layer works at the moment, I don't think this can be made to work right now. The glue layer only allows you to have a pointer to a symbol, but this is a pointer to a nameless string literal. It could never have generated correct code.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 17, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11268


Luís Marques <luis@luismarques.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |luis@luismarques.eu


--- Comment #4 from Luís Marques <luis@luismarques.eu> 2013-10-16 20:54:58 PDT ---
(In reply to comment #3)
> This isn't a regression. It used to compile, but it generated wrong code.

This also used to compile and fail the assert:

    const foo = "foo";
    const(char)* p = foo.ptr;

    void main()
    {
        assert(p == foo.ptr);
    }

(although I did not rely on that behavior, so for me this was a regression)

But if you change to:

    const foo = "foo";
    const(char)* p = foo; // remove .ptr

    void main()
    {
        assert(p == foo.ptr);
    }

It still compiles with git head, and fails the assert.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11268


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
            Summary|[REG 2.064beta] cannot use  |Cannot use non-constant
                   |non-constant CTFE pointer   |CTFE pointer in an
                   |in an initializer           |initializer
           Severity|regression                  |normal


--- Comment #5 from Don <clugdbug@yahoo.com.au> 2013-10-18 00:25:23 PDT ---
(In reply to comment #4)
> (In reply to comment #3)
> > This isn't a regression. It used to compile, but it generated wrong code.
> 
> This also used to compile and fail the assert:
> 
>     const foo = "foo";
>     const(char)* p = foo.ptr;
> 
>     void main()
>     {
>         assert(p == foo.ptr);
>     }
> 
> (although I did not rely on that behavior, so for me this was a regression)

The compiler was still generating wrong code.
I'm downgrading this bug from regression to rejects-valid, since AFAIK there
were no cases where the compiler generated correct code.

Sometimes there are "regressions" where something no longer compiles that was previously wrong, but happened to work in a few special cases. But this doesn't even seem to be one of those issues. It was always wrong.

> But if you change to:
> 
>     const foo = "foo";
>     const(char)* p = foo; // remove .ptr
> 
>     void main()
>     {
>         assert(p == foo.ptr);
>     }
> 
> It still compiles with git head, and fails the assert.

Interesting. I'm not sure if that's a bug, or not. It's a slightly different
case though.
It's treating "foo" as a rvalue, not an lvalue. It evaluates foo, and the
implicit conversion to char * happens afterwards. But with ".ptr" it _has_ to
treat foo as an lvalue. while evaluating it. So the order of evaluation is
different.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11268



--- Comment #6 from Jacob Carlborg <doob@me.com> 2013-10-18 02:32:32 PDT ---
(In reply to comment #3)
> This isn't a regression. It used to compile, but it generated wrong code. Here's a reduced case:
> ---
> static const char [] x = "abc";
> static const char *p = x.ptr;
> 
> void main()
> {
>    assert(p == x.ptr);
> }
> ---

I think the original code only wanted a char* with the content "ReBarWindow32" at compile time.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------