April 02, 2015
I have successfully built GDC on CubieBoard2 (Cubian) now.
I've rebuilt GDC on the G5 as well, using the same script.

I've used nano for making object.d and start.d, in order to avoid too many problems with character encoding.
In addition, I've used hexdump -C <file>.d to verify that the text-files are actually the same, thus I think it's fairly safe to rule out character encoding problems.

GDC on Cubian works, while GDC on the G5 seems to fail.

I've attempted to see if I could find anything in the sources, by first doing a grep -R 'mismatched array lengths' *; however I think I got lost in expressions.c as I don't have a good overview.

As the main difference between my Mac and other platforms is that it's a Big Endian architecture, I expected to be able to find something in the scanner/parser, where it would perhaps be reading a 16-bit or 32-bit character 'buffer' and then bit-shifting the read characters to the right instead of reading byte-by-byte.

But looking at macro.c; I understand that such kind of optimizations are probably not used.

So are there any suggestions on enabling debug-code, which might give hints on what is going wrong ?
April 02, 2015
On Thursday, 2 April 2015 at 05:55:52 UTC, Jens Bauer wrote:

> So are there any suggestions on enabling debug-code, which might give hints on what is going wrong ?

You can find information on debugging GDC here:
http://wiki.dlang.org/GDC/Development/DevelopmentEnvironment

Mike
April 02, 2015
Am Thu, 02 Apr 2015 05:55:48 +0000
schrieb "Jens Bauer" <doctor@who.no>:

> 
> So are there any suggestions on enabling debug-code, which might give hints on what is going wrong ?

I'm not sure if there's any debug code, but here's what I would do:

/opt/gdc/bin/gdc test.d -c -wrapper gdb,--args

break expression.c:11707
break expression.c:11570
break init.c:1015
run

Breakpoint 2, AssignExp::semantic (this=0x7ffff656fad0,
sc=0x7ffff656f440)
    at ../../gcc-5-20150201/gcc/d/dfrontend/expression.c:11570

* bt (not that useful in this case)
* maybe print the dim1/2 values in gdb.
* Look at code: we're interested in TypeSArray
* grep TypeSArray parse.c

break parse.c:3104
break parse.c:2969
break parse.c:7666

run
Breakpoint 2, Parser::parseBasicType2 (this=0x7fffffffdc70,
t=0x7ffff64de350)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:2969
2969	                        t = new TypeSArray(t,e);

print *e
print e->toChars()
print *(IntegerExp*)e

break expression.c:2620
run (y)

print loc
cont (wrong integerexp)
print loc
cont (wrong integerexp)

IntegerExp::IntegerExp (this=0x7ffff64e1ff0, loc=..., value=0,
    type=0x7ffff64de2c0)
    at ../../gcc-5-20150201/gcc/d/dfrontend/expression.c:2620
2620	IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type
*type)
(gdb) print loc
$3 = {filename = 0x1d6db30 "test.d", linnum = 9, charnum = 10}
(gdb) bt
#0  IntegerExp::IntegerExp (this=0x7ffff64e1ff0, loc=..., value=0,
    type=0x7ffff64de2c0)
    at ../../gcc-5-20150201/gcc/d/dfrontend/expression.c:2620
#1  0x000000000070bd57 in Parser::parsePrimaryExp (
    this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:6893
#2  0x00000000007075b9 in Parser::parseUnaryExp (
    this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7247
#3  0x0000000000707d52 in Parser::parseMulExp
(this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7270
#4  0x0000000000707ea2 in Parser::parseAddExp
(this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7293
#5  0x0000000000707ff2 in Parser::parseShiftExp (
    this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7316
#6  0x0000000000708141 in Parser::parseCmpExp
(this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7340
#7  0x00000000007083a1 in Parser::parseAndExp
(this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7413
#8  0x0000000000708462 in Parser::parseXorExp
(this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7430
#9  0x0000000000708532 in Parser::parseOrExp
(this=this@entry=0x7fffffffdc70)
---Type <return> to continue, or q <return> to quit---
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7446
#10 0x0000000000708602 in Parser::parseAndAndExp (
    this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7464
#11 0x00000000007086a2 in Parser::parseOrOrExp
(this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7480
#12 0x0000000000708742 in Parser::parseCondExp
(this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7497
#13 0x00000000007087e6 in Parser::parseAssignExp (
    this=this@entry=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:7515
#14 0x000000000070b54b in Parser::parseBasicType2 (this=0x7fffffffdc70,
    t=0x7ffff64de350)
at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:2961
#15 0x0000000000703e84 in Parser::parseDeclarations
(this=0x7fffffffdc70,
    autodecl=48, pAttrs=0xa00000009, comment=0x0)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:3516
#16 0x00000000007010de in Parser::parseStatement (this=0x7fffffffdc70,
    flags=9, endPtr=0x0)
at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:4413
#17 0x00000000007013fb in Parser::parseStatement (this=0x7fffffffdc70,
    flags=2, endPtr=0x0)
at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:4498
#18 0x000000000070210c in Parser::parseStatement (this=0x7fffffffdc70,
    flags=-162652272, endPtr=0x0)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:4518
---Type <return> to continue, or q <return> to quit---
#19 0x00000000007013fb in Parser::parseStatement (this=0x7fffffffdc70,
    flags=1, endPtr=0x0)
at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:4498
#20 0x0000000000703b2d in Parser::parseContracts (this=0x7fffffffdc70,
f=
    0x7ffff64e1d40) at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:3874
#21 0x00000000007044da in Parser::parseDeclarations
(this=0x7fffffffdc70,
    autodecl=48, autodecl@entry=false, pAttrs=0xa00000009,
    pAttrs@entry=0x7fffffffdb80, comment=0x0)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:3688
#22 0x0000000000705601 in Parser::parseDeclDefs (
    this=this@entry=0x7fffffffdc70, once=once@entry=0,
    pLastDecl=0x7fffffffdb18, pLastDecl@entry=0x0,
pAttrs=0x7fffffffdb80,
    pAttrs@entry=0x0)
at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:337
#23 0x0000000000709a3b in Parser::parseModule (this=0x7fffffffdc70)
    at ../../gcc-5-20150201/gcc/d/dfrontend/parse.c:187
#24 0x00000000006f3ec5 in Module::parse (this=0x7ffff64e1810)
    at ../../gcc-5-20150201/gcc/d/dfrontend/module.c:519
#25 0x0000000000748e19 in d_parse_file ()
    at ../../gcc-5-20150201/gcc/d/d-lang.cc:962
#26 0x0000000000bc2402 in compile_file ()
    at ../../gcc-5-20150201/gcc/toplev.c:594
#27 0x0000000000616b9c in do_compile ()
    at ../../gcc-5-20150201/gcc/toplev.c:2063
#28 toplev::main (this=this@entry=0x7fffffffdeb0, argc=argc@entry=11,
---Type <return> to continue, or q <return> to quit---
    argv=argv@entry=0x7fffffffdfb8)
at ../../gcc-5-20150201/gcc/toplev.c:2161
#29 0x000000000061754a in main (argc=11, argv=0x7fffffffdfb8)
    at ../../gcc-5-20150201/gcc/main.c:39




It could be quite some more work to find where exactly things go wrong, but this should give an idea about one way to debug this.
April 02, 2015
>> So are there any suggestions on enabling debug-code, which might give hints on what is going wrong ?
>
> I'm not sure if there's any debug code, but here's what I would do [snip]

Mike and Johannes - Thank you both for the suggestions.
I will follow the debug path you've given me when I've finished the current build.
(I'm still attempting to find a way to have both coffee and cake; eg. multilib support in GCC /and/ GDC).

I expect to get more information about this, and of course, I hope to find what causes the bug.
When my next build is finished, I plan to add a zero in front of the number 3:
uint[03] message =
... just in case it's a read-pointer "alignment-style" problem.

If the bug is related to Big Endian architectures, then it's a bit more important than if it's only related to PowerMacs; because there are other Big Endian hosts ...
PowerPC based Amiga, MIPS based hosts, Cortex-A based hosts, 68xxx based hosts, other PowerPC based systems (IBM, YellowDog, etc) - and all those I forgot, plus future architectures.

If you are working with a BE host and come across this post, please post a comment, whether or not it works for you.
April 02, 2015
I got a little further, and will continue to look into the issue.
Currently, this is what I've gotten so far...

arm-none-eabi-gdc start.d -c -wrapper gdb,--args

break expression.c:11707
break expression.c:11570
break init.c:1015
break init.c:557
run

...

Breakpoint 1, AssignExp::semantic (this=0x4170b9f0, sc=0x4170b860) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/expression.c:11707
11707	                error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2);


(gdb) print dim1
$1 = 0

(gdb) print dim2
$2 = 3

... dim1 is the one which is incorrect.
dim1 comes from tsa1; tsa1 comes from se1, se1 comes from e1.


(gdb) print *e1
$3 = {
  <RootObject> = {
    _vptr$RootObject = 0xf07570
  },
  members of Expression:
  loc = {
    filename = 0x41605be0 "start.d",
    linnum = 46,
    charnum = 13
  },
  op = TOKvar,
  type = 0x41709040,
  size = 36 '$',
  parens = 0 '\0'
}

(gdb) print e1->toChars()
$4 = 0x41611a74 "message"

(gdb) print e1->isLvalue()
$5 = 1

(gdb) print e1->type->ty
$6 = 1 '\001'


(gdb) bt
#0  AssignExp::semantic (this=0x4170b9f0, sc=0x4170b860) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/expression.c:11707
#1  0x0003e230 in _ZN10Expression8optimizeEib [inlined] () at expression.h:1409
#2  VarDeclaration::semantic (this=0x417093c0, sc=0x4170b860) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/declaration.c:1411
#3  0x00059204 in DeclarationExp::semantic (this=0x417094a0, sc=0x4170b750) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/expression.c:5958
#4  0x000fed38 in ExpStatement::semantic (this=0x41709480, sc=0x4170b750) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/statement.c:835
#5  0x00105a64 in CompoundStatement::semantic (this=0x4170b7f0, sc=0x4170b750) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/statement.c:1044
#6  0x00104838 in ScopeStatement::semantic (this=0x41709600, sc=0x4170b750) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/statement.c:1336
#7  0x0010a890 in ForStatement::semantic (this=0x4170b680, sc=0x4170aee0) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/statement.c:1546
#8  0x00105a64 in CompoundStatement::semantic (this=0x41709640, sc=0x4170ae40) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/statement.c:1044
#9  0x0007f2ec in FuncDeclaration::semantic3 (this=0x41708e70, sc=0x4170aa00) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/func.c:1622
#10 0x000d6f18 in Module::semantic3 (this=0x41707a90) at /Users/jens/toolchain/Source/gcc/gcc/d/dfrontend/module.c:787
#11 0x0012c38c in d_parse_file () at /Users/jens/toolchain/Source/gcc/gcc/d/d-lang.cc:1064
#12 0x00773ca8 in timevar_pop [inlined] () at timevar.h:548
#13 0x00773ca8 in compile_file () at /Users/jens/toolchain/Source/gcc/gcc/toplev.c:550
#14 0x00774c2c in do_compile () at /Users/jens/toolchain/Source/gcc/gcc/toplev.c:1926
#15 0x0077519c in toplev_main (argc=11, argv=0xbffff148) at /Users/jens/toolchain/Source/gcc/gcc/toplev.c:2002
#16 0x00002404 in start ()
April 02, 2015
"Jens Bauer"  wrote in message news:gufvwhyvuyuhhkgdyqxp@forum.dlang.org...

> I expect to get more information about this, and of course, I hope to find what causes the bug.
> When my next build is finished, I plan to add a zero in front of the number 3:
> uint[03] message =
> ... just in case it's a read-pointer "alignment-style" problem.

You can tell how far through the error is by triggering failures in different compilation phases.

eg to generate a parser error, give the compiler something invalid like:
pragma 3
which should generate
testx.d(2): Error: found '3' when expecting '('

This should error during semantic2
static assert(3 == 2); 

April 03, 2015
Well, it seems I found the problem.

lexer.h, line 203 reads:

    union
    {
        d_int32 int32value;
        d_uns32 uns32value;
        d_int64 int64value;
        d_uns64 uns64value;
        ...
        ...
        ...
    };

While this optimization is neat, it does not produce correct code on Big Endian or Mixed Endian platforms.

If we write a value to int64value and read it from int32value, then it will be 0 always.
This is because the int32value is always read if the upper 32 bits of the int64value is zero.
And since a Big Endian platform reads the most significant bits/bytes first, they'll read the upper 32 bits, not the lower 32 bits.

lexer.c:1874; Lexer::number(Token *t) correctly writes n to t->uns64value.
-But let's take parse.c:6384 - here token.uns32value is read, thus we'll get a zero, no matter which value was written by number(Token *).

In parse.c:6379 we would get a minus one always.

Looking for union-"tricks", I also found ...
stringtable.c:24 hash will not be the same value on Big Endian, Mixed Endian and Little Endian machines.
To hash correctly, read one byte at a time, then use bit-shifting by 8 if another byte is to be read.
April 03, 2015
I better also mention that the problem is the same for floats in Lexer::inreal(Token *).
April 03, 2015
On Friday, 3 April 2015 at 08:06:03 UTC, Jens Bauer wrote:
> I better also mention that the problem is the same for floats in Lexer::inreal(Token *).

Ignore that - it's always read/written as a long double.
Sorry for then noise.
April 03, 2015
Am Fri, 03 Apr 2015 07:32:21 +0000
schrieb "Jens Bauer" <doctor@who.no>:

> Well, it seems I found the problem.
> 
> lexer.h, line 203 reads:
> 
>      union
>      {
>          d_int32 int32value;
>          d_uns32 uns32value;
>          d_int64 int64value;
>          d_uns64 uns64value;
>          ...
>          ...
>          ...
>      };
> 
> While this optimization is neat, it does not produce correct code on Big Endian or Mixed Endian platforms.
> 
> If we write a value to int64value and read it from int32value,
> then it will be 0 always.
> This is because the int32value is always read if the upper 32
> bits of the int64value is zero.
> And since a Big Endian platform reads the most significant
> bits/bytes first, they'll read the upper 32 bits, not the lower
> 32 bits.
> 
> lexer.c:1874; Lexer::number(Token *t) correctly writes n to
> t->uns64value.
> -But let's take parse.c:6384 - here token.uns32value is read,
> thus we'll get a zero, no matter which value was written by
> number(Token *).
> 
> In parse.c:6379 we would get a minus one always.

Nice find. If you open a pull request on
https://github.com/D-Programming-Language/dmd
please notify me (@jpf91). I'll make sure to backport the fix to gdc
once it's been committed to dmd upstream.

> Looking for union-"tricks", I also found ...
> stringtable.c:24 hash will not be the same value on Big Endian,
> Mixed Endian and Little Endian machines.
> To hash correctly, read one byte at a time, then use bit-shifting
> by 8 if another byte is to be read.

IIRC it does not really matter if the hash is different here as it's only used internally in the compiler. So as long as it still hashes correctly ('no' collisions) it shouldn't matter.