Thread overview
[dmd-internals] CTFE problem - need debugging hint
Jan 02, 2013
Kai Nacke
Jan 03, 2013
Don Clugston
Jan 08, 2013
Kai
January 02, 2013
Hi!

While trying to port LDC to PPC64 I ran into the following CTFE issue. This small program (reduced from std.conv.to!string(int)):

import core.stdc.stdio : printf;

string toStr()
{
    char x[];
    x.length = 16;
    x[0..3] = "666";
    x.length = 3;
    return cast(string) x;
}

string gencode()
{
    return "int x = " ~ toStr ~ ";";
}

void main()
{
    mixin(gencode());
    printf("Value of gencode: |%s|\n", gencode().ptr);
}

produces the error:
bug2.d(19): Error: expression expected, not 'EOF'
bug2.d(19): Error: semicolon expected, not 'EOF'
(the mixin statement is in line 19)

From the log I conclude that it must have something to do with the split range and array join:

bug2.d(8) VarExp::interpret() x
REF ASSIGN: x=['6', '6', '6']
ARRAY LITERAL type=char[] 0x10011b59040:
 void
 void
 void
bug2.d(9) ReturnStatement::interpret(cast(string)x)
bug2.d(9) CastExp::interpret() cast(string)x
bug2.d(9) VarExp::interpret() x
RETURN bug2.d(9)
ARRAY LITERAL type=char[] 0x10011b59040:
 void
 void
 void
bug2.d(4) -CompoundStatement::interpret() 0x10011b59040
 -CompoundStatement::interpret() 0x10011b59040
bug2.d(14) StringExp::interpret() ";"
RETURN bug2.d(14)
STRING "int x = \x00\x00\x00;" 0x10011b593c0
 -CompoundStatement::interpret() 0x10011b593e0

Needless to say that it works on x86 with dmd (2.061) and on x86_64 with ldc2 (based on 2.060).
The error does not show up if I (a) replace the mixin statement with mixin("int x = " ~ toStr ~ ";") or (b) do a return "666" in toStr().

Does anybody have a hint how  I can reduce this further? E.g. is there a way to view the content of the array?

Thanks in advance.

Kai


_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

January 03, 2013
On 2 January 2013 17:44, Kai Nacke <kai.nacke@redstar.de> wrote:
> Hi!
>
> While trying to port LDC to PPC64 I ran into the following CTFE issue. This
> small program (reduced from std.conv.to!string(int)):
>
> import core.stdc.stdio : printf;
>
> string toStr()
> {
>     char x[];
>     x.length = 16;
>     x[0..3] = "666";
>     x.length = 3;
>     return cast(string) x;
> }
>
> string gencode()
> {
>     return "int x = " ~ toStr ~ ";";
> }
>
> void main()
> {
>     mixin(gencode());
>     printf("Value of gencode: |%s|\n", gencode().ptr);
> }
>
> produces the error:
> bug2.d(19): Error: expression expected, not 'EOF'
> bug2.d(19): Error: semicolon expected, not 'EOF'
> (the mixin statement is in line 19)
>
> From the log I conclude that it must have something to do with the split range and array join:
>
> bug2.d(8) VarExp::interpret() x
> REF ASSIGN: x=['6', '6', '6']
> ARRAY LITERAL type=char[] 0x10011b59040:
>  void
>  void
>  void
> bug2.d(9) ReturnStatement::interpret(cast(string)x)
> bug2.d(9) CastExp::interpret() cast(string)x
> bug2.d(9) VarExp::interpret() x
> RETURN bug2.d(9)
> ARRAY LITERAL type=char[] 0x10011b59040:
>  void
>  void
>  void

Something has gone wrong by this point. x is still [void, void, void],
when it should be ['6','6','6'].
Looks as though the assignment didn't happen properly.

> Does anybody have a hint how  I can reduce this further? E.g. is there a way to view the content of the array?

showCtfeExpr(arr).

Probably you can get a reduced test case like
static assert(toStr()=="666");
I don't think the mixin bit is relevant, unless it's a compilation order issue.


>
> Thanks in advance.
>
> Kai
>
>
> _______________________________________________
> dmd-internals mailing list
> dmd-internals@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-internals
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

January 08, 2013
Hi Don!

Thanks for your suggestion. I finally solved my problem.

1. showCtfeExpr() does not show array literals but always "void". If the operation is TOKarrayliteral then the variables sd and cd are NULL. Inside the loop to print the elements there is no assignment to z which should hold the value of the current element. Therefore the function always outputs "void". (Happens with dmd on Windows, too.)

2. After I understand the (wrong) output I was able to find the place where the null bytes where created. The culprit is ctfeCat(). Inside this function the array elements are copied with memcpy(). The source is always a variable v of type dinteger_t. This inherently assumes a little endian architecture. But Linux/PPC is big endian - therefore the null bytes.

I am going to check if there are other endian-related problems and then I prepare a pull request for it.

Thanks for your help again.

Kai

On 03.01.2013 08:35, Don Clugston wrote:
> On 2 January 2013 17:44, Kai Nacke <kai.nacke@redstar.de> wrote:
>> Hi!
>>
>> While trying to port LDC to PPC64 I ran into the following CTFE issue. This
>> small program (reduced from std.conv.to!string(int)):
>>
>> import core.stdc.stdio : printf;
>>
>> string toStr()
>> {
>>      char x[];
>>      x.length = 16;
>>      x[0..3] = "666";
>>      x.length = 3;
>>      return cast(string) x;
>> }
>>
>> string gencode()
>> {
>>      return "int x = " ~ toStr ~ ";";
>> }
>>
>> void main()
>> {
>>      mixin(gencode());
>>      printf("Value of gencode: |%s|\n", gencode().ptr);
>> }
>>
>> produces the error:
>> bug2.d(19): Error: expression expected, not 'EOF'
>> bug2.d(19): Error: semicolon expected, not 'EOF'
>> (the mixin statement is in line 19)
>>
>>  From the log I conclude that it must have something to do with the split
>> range and array join:
>>
>> bug2.d(8) VarExp::interpret() x
>> REF ASSIGN: x=['6', '6', '6']
>> ARRAY LITERAL type=char[] 0x10011b59040:
>>   void
>>   void
>>   void
>> bug2.d(9) ReturnStatement::interpret(cast(string)x)
>> bug2.d(9) CastExp::interpret() cast(string)x
>> bug2.d(9) VarExp::interpret() x
>> RETURN bug2.d(9)
>> ARRAY LITERAL type=char[] 0x10011b59040:
>>   void
>>   void
>>   void
> Something has gone wrong by this point. x is still [void, void, void],
> when it should be ['6','6','6'].
> Looks as though the assignment didn't happen properly.
>
>> Does anybody have a hint how  I can reduce this further? E.g. is there a way
>> to view the content of the array?
> showCtfeExpr(arr).
>
> Probably you can get a reduced test case like
> static assert(toStr()=="666");
> I don't think the mixin bit is relevant, unless it's a compilation order issue.
>
>
>> Thanks in advance.
>>
>> Kai
>>
>>
>> _______________________________________________
>> dmd-internals mailing list
>> dmd-internals@puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/dmd-internals
> _______________________________________________
> dmd-internals mailing list
> dmd-internals@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-internals
>

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals