It seems that during some forms of macro expansion, a token consisting of several ampersands (e.g., &&) is turned into a token consisting of a single ampersand (&). The example below uses &&, however, the same results occur when using the token &&& or &&&&. This is quite deadly, as both && and & are legal tokens in GAS of course, the first being the short-circuit AND, the other the boolean AND operator. Also, use of &&& or &&&& did _not_ cause a syntax error in this case, as would normally be expected.
Because of GAS's decision to use an operator precedence scheme different from C's (& having higher priority than the relational operators <, >, ==, ...), the expression A != B && A != C creates a different parse tree than A != B & A != C. This is how the bug expressed itself to me: conditional parts of the code where being assembled, although they should not have been. Included below is the listing file produced by GAS which exhibits the error. The line labeled 31 of the listing shows the definition of code which is later incorrectly expanded. Note that the && operator is used. Please disregard the comment starting at the line labeled 32, I forgot to take it out in the reduced test case. Some of the lines labeled 41 show the incorrect expansion (e.g., the third such line). Note that such lines are printed with just the & operator. This is not just an error in the list generator part of the assembler: e.g., the 13th occurance of line 41 (the block headed by ".if temp !=1 && context != 1") causes the code "stw 1, s_gpr1 (context)" to be emitted, even though the the condition ".if temp !=1 && context != 1" is false ("temp" being set to 1 in line 22). GNU assembler version 2.19.51 (powerpc-eabi) using BFD version (Sourcery G++ Lite 4.4-79) 2.19.51.20090709. options passed : --gdwarf2 -mppc -mspe -me500 -many -aglmns=gas-and-test.o.lst input file : c:\DOCUME~1\mchn1350\LOCALS~1\Temp\ccPTz6Qh.s output file : gas-and-test.o target : powerpc-unknown-eabi time stamp : 2010-07-22T05:48:27.000W. Euro¿GL 1 # 1 "gas-and-test.S" 1 .macro concat s1, s2, s3, s4, s5 0 0 0 2 .noaltmacro 3 \s1\s2\s3\s4\s5 4 .endm 5 6 .set reg_size, 4 7 8 .macro alloc_reg r 9 s_\r : .space reg_size 10 .endm 11 12 .struct 13 .set j, 0 14 .rept 1 << 5 15 .altmacro 16 concat <alloc_reg gpr>, %j 17 .set j, 1 + j 18 .endr 19 .previous 20 21 .set context, 12 22 .set temp, 1 23 24 .macro save_gpr gpr 25 .noaltmacro 26 stw \gpr, s_gpr\gpr (context) 27 .endm 28 29 .macro mvgpr macro 30 .irp r, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 31 .if temp != \r && context != \r 32 /* the extra parentheses around the clauses 33 of the && operators are because GAS insists 34 on turning && into & (!) and & has the wrong 35 precedence */ 36 \macro \r 37 .endif 38 .endr 39 .endm 40 41 mvgpr save_gpr 41 > .irp r,0,1,3,4,5,6,7,8,9,10,11,12 41 >> .if temp!=0&context!=0 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 0 41 >>> .noaltmacro 41 0000 900C0000 >>> stw 0,s_gpr0(context) 41 >> .endif 41 >> 41 >> .if temp!=1&context!=1 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 1 41 >>> .noaltmacro 41 0004 902C0004 >>> stw 1,s_gpr1(context) 41 >> .endif 41 >> 41 >> .if temp!=3&context!=3 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 3 41 >>> .noaltmacro 41 0008 906C000C >>> stw 3,s_gpr3(context) 41 >> .endif 41 >> 41 >> .if temp!=4&context!=4 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 4 41 >>> .noaltmacro 41 000c 908C0010 >>> stw 4,s_gpr4(context) 41 >> .endif 41 >> 41 >> .if temp!=5&context!=5 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 5 41 >>> .noaltmacro 41 0010 90AC0014 >>> stw 5,s_gpr5(context) 41 >> .endif 41 >> 41 >> .if temp!=6&context!=6 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 6 41 >>> .noaltmacro 41 0014 90CC0018 >>> stw 6,s_gpr6(context) 41 >> .endif 41 >> 41 >> .if temp!=7&context!=7 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 7 41 >>> .noaltmacro 41 0018 90EC001C >>> stw 7,s_gpr7(context) 41 >> .endif 41 >> 41 >> .if temp!=8&context!=8 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 8 41 >>> .noaltmacro 41 001c 910C0020 >>> stw 8,s_gpr8(context) 41 >> .endif 41 >> 41 >> .if temp!=9&context!=9 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 9 41 >>> .noaltmacro 41 0020 912C0024 >>> stw 9,s_gpr9(context) 41 >> .endif 41 >> 41 >> .if temp!=10&context!=10 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 10 41 >>> .noaltmacro 41 0024 914C0028 >>> stw 10,s_gpr10(context) 41 >> .endif 41 >> 41 >> .if temp!=11&context!=11 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 11 41 >>> .noaltmacro 41 0028 916C002C >>> stw 11,s_gpr11(context) 41 >> .endif 41 >> 41 >> .if temp!=12&context!=12 41 >> 41 >> 41 >> 41 >> 41 >> save_gpr 12 41 >>> .noaltmacro 41 002c 918C0030 >>> stw 12,s_gpr12(context) 41 >> .endif DEFINED SYMBOLS gas-and-test.S:6 *ABS*:00000004 reg_size gas-and-test.S:12 *ABS*:00000020 j *ABS*:00000000 s_gpr0 *ABS*:00000004 s_gpr1 *ABS*:00000008 s_gpr2 *ABS*:0000000c s_gpr3 *ABS*:00000010 s_gpr4 *ABS*:00000014 s_gpr5 *ABS*:00000018 s_gpr6 *ABS*:0000001c s_gpr7 *ABS*:00000020 s_gpr8 *ABS*:00000024 s_gpr9 *ABS*:00000028 s_gpr10 *ABS*:0000002c s_gpr11 *ABS*:00000030 s_gpr12 *ABS*:00000034 s_gpr13 *ABS*:00000038 s_gpr14 *ABS*:0000003c s_gpr15 *ABS*:00000040 s_gpr16 *ABS*:00000044 s_gpr17 *ABS*:00000048 s_gpr18 *ABS*:0000004c s_gpr19 *ABS*:00000050 s_gpr20 *ABS*:00000054 s_gpr21 *ABS*:00000058 s_gpr22 *ABS*:0000005c s_gpr23 *ABS*:00000060 s_gpr24 *ABS*:00000064 s_gpr25 *ABS*:00000068 s_gpr26 *ABS*:0000006c s_gpr27 *ABS*:00000070 s_gpr28 *ABS*:00000074 s_gpr29 *ABS*:00000078 s_gpr30 *ABS*:0000007c s_gpr31 gas-and-test.S:21 *ABS*:0000000c context gas-and-test.S:22 *ABS*:00000001 temp NO UNDEFINED SYMBOLS -- Summary: consecutive ampersands collapsed during macro expansion (&& changed to &) Product: binutils Version: 2.19 Status: NEW Severity: critical Priority: P2 Component: gas AssignedTo: unassigned at sources dot redhat dot com ReportedBy: konrad dot schwarz at siemens dot com CC: bug-binutils at gnu dot org GCC host triplet: Sourcery G++ Lite for Windows, running under Cygwin GCC target triplet: powerpc-unknown-eabi http://sourceware.org/bugzilla/show_bug.cgi?id=11830 ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils