On Thu, 8 Jan 2026, Jakub Jelinek wrote:
> Hi!
>
> The following invalid testcase ICEs, because we:
> 1) for some strange reason ignore invalid punctuations in
> parse_output_constraint, which has just
> default:
> if (!ISALPHA (*p))
> break;
> compared to parse_input_constraint
> default:
> if (! ISALPHA (constraint[j]))
> {
> error ("invalid punctuation %qc in constraint", constraint[j]);
> return false;
> }
> Haven't touched this because I fear it could break real-world code
> 2) the checking whether = or + is first in the output constraint is
> a warning only:
> if (p != constraint)
> warning (0, "output constraint %qc for operand %d "
> "is not at the beginning",
> *p, operand_num);
> 3) parse_input_constraint parses also the corresponding output constraint
> if the input constraint has a number as the only variant, but
> even the comment removed in the following patch explains that it
> doesn't work correctly and skips the first character; now, usually
> that is not a big deal because if the first character of the output
> constraint is = or + as it should, then the checking doesn't do anything;
> but as 2) is just a warning, we accept it and then we fail to check it
> 4) far later on we parse the whole output constraint when input constraint
> refers to it and assert it succeeds, which it doesn't due to 1), 2) and 3)
ICK. I wonder if it makes sense to be stricter with some flags?
-pedantic isn't really applicable, maybe we want a -pedantic-gnu?
> The following patch fixes the 3) spot, when switching to the output
> constraint, instead of setting j = 0; and break; (== continue;) so that it
> first does j += CONSTRAINT_LEN (constraint[0], constraint+0) and thus
> usually starts at second, sometimes third character of the output constraint
> it uses goto before the loop which sets j = 0; and doesn't do the j += ...
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Thanks,
Richard.
> 2026-01-08 Jakub Jelinek <[email protected]>
>
> PR middle-end/111817
> * stmt.cc (parse_input_constraint): For matching construct, goto
> before the loop without changing j instead of break. Remove comment
> about that problem.
>
> * c-c++-common/pr111817.c: New test.
>
> --- gcc/stmt.cc.jj 2026-01-02 09:56:10.331333745 +0100
> +++ gcc/stmt.cc 2026-01-07 15:57:35.329401594 +0100
> @@ -508,6 +508,7 @@ parse_input_constraint (const char **con
> unsigned int alt = 0;
> unsigned long match = 0;
>
> +repeat:
> for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
> switch (constraint[j])
> {
> @@ -583,12 +584,7 @@ parse_input_constraint (const char **con
> constraint = constraints[match];
> *constraint_p = constraint;
> c_len = strlen (constraint);
> - j = 0;
> - /* ??? At the end of the loop, we will skip the first part of
> - the matched constraint. This assumes not only that the
> - other constraint is an output constraint, but also that
> - the '=' or '+' come first. */
> - break;
> + goto repeat;
> }
> else
> j = end - constraint;
> --- gcc/testsuite/c-c++-common/pr111817.c.jj 2026-01-07 17:07:23.449815574
> +0100
> +++ gcc/testsuite/c-c++-common/pr111817.c 2026-01-07 17:10:47.408343658
> +0100
> @@ -0,0 +1,9 @@
> +/* PR middle-end/111817 */
> +/* { dg-do compile } */
> +
> +int
> +foo (int x, int y)
> +{
> + asm ("" : "\n=g" (x) : "0" (y)); /* { dg-warning "output constraint '='
> for operand 0 is not at the beginning" } */
> + return x; /* { dg-error "invalid punctuation
> '\\\\x\[0-9a-zA-Z]*' in constraint" "" { target *-*-* } .-1 } */
> +}
>
> Jakub
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)