On Mon, 12 Mar 2018, Jakub Jelinek wrote:

> Hi!
> 
> I thought the vregs pass is the first one to analyze constraints,
> but I was wrong, already before that parse_{output,input}_constraint
> are called, already during GIMPLE passes.  They don't really fail miserably
> if , appears in the middle of multi-letter constraint (unlike e.g. the RA),
> which is what my previous patch was fixing, but care if '\0' appears
> in the middle of multi-letter constraint, because then we continue walking
> random characters after the constraint string.  parse_input_constraint
> is actually fine, because it has c_len = strlen (constraint); and uses
> j < c_len, but parse_output_constraint doesn't do that.  While doing it
> is possible, I think it is needlessly slow (needs to walk the constraint
> twice), so this patch instead makes sure there are no '\0's in the middle
> of constraints, if there are, doesn't jump over it.
> 
> The patch is larger because of reindentation, here is diff -upbd for
> easier understanding what has changed.
> 
> --- gcc/stmt.c.jj     2018-01-03 10:19:55.150533956 +0100
> +++ gcc/stmt.c        2018-03-12 13:25:03.790733765 +0100
> @@ -247,7 +247,8 @@ parse_output_constraint (const char **co
>      }
>  
>    /* Loop through the constraint string.  */
> -  for (p = constraint + 1; *p; p += CONSTRAINT_LEN (*p, p))
> +  for (p = constraint + 1; *p; )
> +    {
>      switch (*p)
>        {
>        case '+':
> @@ -304,6 +305,11 @@ parse_output_constraint (const char **co
>       break;
>        }
>  
> +      for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
> +     if (*p == '\0')
> +       break;
> +    }
> +
>    return true;
>  }
>  
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Richard.

> 2018-03-12  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/84831
>       * stmt.c (parse_output_constraint): If the CONSTRAINT_LEN (*p, p)
>       characters starting at p contain '\0' character, don't look beyond
>       that.
> 
> --- gcc/stmt.c.jj     2018-01-03 10:19:55.150533956 +0100
> +++ gcc/stmt.c        2018-03-12 13:25:03.790733765 +0100
> @@ -247,62 +247,68 @@ parse_output_constraint (const char **co
>      }
>  
>    /* Loop through the constraint string.  */
> -  for (p = constraint + 1; *p; p += CONSTRAINT_LEN (*p, p))
> -    switch (*p)
> -      {
> -      case '+':
> -      case '=':
> -     error ("operand constraint contains incorrectly positioned "
> -            "%<+%> or %<=%>");
> -     return false;
> -
> -      case '%':
> -     if (operand_num + 1 == ninputs + noutputs)
> -       {
> -         error ("%<%%%> constraint used with last operand");
> -         return false;
> -       }
> -     break;
> -
> -      case '?':  case '!':  case '*':  case '&':  case '#':
> -      case '$':  case '^':
> -      case 'E':  case 'F':  case 'G':  case 'H':
> -      case 's':  case 'i':  case 'n':
> -      case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
> -      case 'N':  case 'O':  case 'P':  case ',':
> -     break;
> -
> -      case '0':  case '1':  case '2':  case '3':  case '4':
> -      case '5':  case '6':  case '7':  case '8':  case '9':
> -      case '[':
> -     error ("matching constraint not valid in output operand");
> -     return false;
> -
> -      case '<':  case '>':
> -     /* ??? Before flow, auto inc/dec insns are not supposed to exist,
> -        excepting those that expand_call created.  So match memory
> -        and hope.  */
> -     *allows_mem = true;
> -     break;
> -
> -      case 'g':  case 'X':
> -     *allows_reg = true;
> -     *allows_mem = true;
> -     break;
> -
> -      default:
> -     if (!ISALPHA (*p))
> -       break;
> -     enum constraint_num cn = lookup_constraint (p);
> -     if (reg_class_for_constraint (cn) != NO_REGS
> -         || insn_extra_address_constraint (cn))
> +  for (p = constraint + 1; *p; )
> +    {
> +      switch (*p)
> +     {
> +     case '+':
> +     case '=':
> +       error ("operand constraint contains incorrectly positioned "
> +              "%<+%> or %<=%>");
> +       return false;
> +
> +     case '%':
> +       if (operand_num + 1 == ninputs + noutputs)
> +         {
> +           error ("%<%%%> constraint used with last operand");
> +           return false;
> +         }
> +       break;
> +
> +     case '?':  case '!':  case '*':  case '&':  case '#':
> +     case '$':  case '^':
> +     case 'E':  case 'F':  case 'G':  case 'H':
> +     case 's':  case 'i':  case 'n':
> +     case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
> +     case 'N':  case 'O':  case 'P':  case ',':
> +       break;
> +
> +     case '0':  case '1':  case '2':  case '3':  case '4':
> +     case '5':  case '6':  case '7':  case '8':  case '9':
> +     case '[':
> +       error ("matching constraint not valid in output operand");
> +       return false;
> +
> +     case '<':  case '>':
> +       /* ??? Before flow, auto inc/dec insns are not supposed to exist,
> +          excepting those that expand_call created.  So match memory
> +          and hope.  */
> +       *allows_mem = true;
> +       break;
> +
> +     case 'g':  case 'X':
>         *allows_reg = true;
> -     else if (insn_extra_memory_constraint (cn))
>         *allows_mem = true;
> -     else
> -       insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
> -     break;
> -      }
> +       break;
> +
> +     default:
> +       if (!ISALPHA (*p))
> +         break;
> +       enum constraint_num cn = lookup_constraint (p);
> +       if (reg_class_for_constraint (cn) != NO_REGS
> +           || insn_extra_address_constraint (cn))
> +         *allows_reg = true;
> +       else if (insn_extra_memory_constraint (cn))
> +         *allows_mem = true;
> +       else
> +         insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
> +       break;
> +     }
> +
> +      for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
> +     if (*p == '\0')
> +       break;
> +    }
>  
>    return true;
>  }
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to