Dave Korn <dave.korn.cyg...@gmail.com> writes:

> On 02/03/2011 07:56, Liu wrote:
>
>> The wrong code is :
>>  L9284: ATTRIBUTE_UNUSED_LABEL
>>   x3 = XEXP (x2, {);
>>   if (x3 == const_int_rtx[MAX_SAVED_CONST_INT + (13)])
>>     goto L9285;
>>   goto ret0;
>
>   Well, that's coming from here:
>
>       else
>       printf ("%sx%d = XEXP (x%d, %c);\n",
>               indent, depth + 1, depth, newpos[depth]);
>       ++depth;
Interesting.  Looks you have a define_insn which has too many entries.
It can only have 26 elements, but, annoyingly, genrecog doesn't check
for that.

It's a bit odd to have more than 26 elements.  Do you have any
incredibly large define_insn patterns?

> in the MATCH_OPERAND case of the big switch in add_to_sequence().  Possibly
> change_state needs to do something like
>
>       printf ("%sx%d = XEXP (x%d, %d);\n",
>               indent, depth + 1, depth,
>               newpos[depth] > 'a'
>                 ? newpos[depth] - 'a'
>                 : newpos[depth] - '0');

No, change_state uses upper case and lower case letters to mean
different things.  In this case it's meant to be a lower case letter but
it has overrun.

This patch should at least cause genrecog to crash for you rather than
generating bogus output.  I've verified that this patch bootstraps on
x86_64 and makes no difference in the generated insn-recog.c.  Can you
see whether this gives you a crash?  Any opinion on whether I should
commit this to mainline?

Ian

Index: genrecog.c
===================================================================
--- genrecog.c	(revision 169848)
+++ genrecog.c	(working copy)
@@ -912,6 +912,7 @@ add_to_sequence (rtx pattern, struct dec
 	      /* Which insn we're looking at is represented by A-Z. We don't
 	         ever use 'A', however; it is always implied.  */
 
+	      gcc_assert (i < 26);
 	      subpos[depth] = (i > 0 ? 'A' + i : 0);
 	      sub = add_to_sequence (XVECEXP (pattern, 0, i),
 				     last, subpos, insn_type, 0);
@@ -1002,6 +1003,9 @@ add_to_sequence (rtx pattern, struct dec
 	    char base = (was_code == MATCH_OPERATOR ? '0' : 'a');
 	    for (i = 0; i < (size_t) XVECLEN (pattern, 2); i++)
 	      {
+		gcc_assert (was_code == MATCH_OPERATOR
+			    ? ISDIGIT (i + base)
+			    : ISLOWER (i + base));
 		subpos[depth] = i + base;
 		sub = add_to_sequence (XVECEXP (pattern, 2, i),
 				       &sub->success, subpos, insn_type, 0);
@@ -1102,6 +1106,7 @@ add_to_sequence (rtx pattern, struct dec
 	    int j;
 	    for (j = 0; j < XVECLEN (pattern, i); j++)
 	      {
+		gcc_assert (j < 26);
 		subpos[depth] = 'a' + j;
 		sub = add_to_sequence (XVECEXP (pattern, i, j),
 				       &sub->success, subpos, insn_type, 0);
@@ -2528,6 +2533,7 @@ make_insn_sequence (rtx insn, enum routi
 	}
       XVECLEN (x, 0) = j;
 
+      gcc_assert (j - 1 < 26);
       c_test_pos[0] = 'A' + j - 1;
       c_test_pos[1] = '\0';
     }

Reply via email to