Richard Earnshaw <rearn...@arm.com> writes:
> For constraints there are operand modifiers and constraint qualifiers.
> Operand modifiers apply to all alternatives and must appear, in
> traditional syntax before the first alternative.  Constraint
> qualifiers, on the other hand must appear in each alternative to which
> they apply.
>
> There's no easy way to validate the distinction in the traditional md
> format, but when using the new compact format we can enforce some
> semantic checking of these characters to avoid some potentially
> surprising code generation.
>
> gcc/
>
>       * gensupport.cc (conlist::conlist): Pass a location to the constructor.
>       Only allow skipping of non-alpha-numeric characters when parsing a
>       number and only allow '=', '+' or '%'.  Add some error checking when
>       parsing an operand number.
>       (parse_section_layout): Pass the location to the conlist constructor.
>       (parse_section): Allow an optional list of forbidden characters.
>       If specified, reject strings containing them.
>       (convert_syntax): Reject '=', '+' or '%' in an alternative.

OK, thanks.  Patch 1 looks good to me as well.

Richard

> ---
>  gcc/gensupport.cc | 37 ++++++++++++++++++++++++++-----------
>  1 file changed, 26 insertions(+), 11 deletions(-)
>
> diff --git a/gcc/gensupport.cc b/gcc/gensupport.cc
> index 80f1976faf1..ac0132860a9 100644
> --- a/gcc/gensupport.cc
> +++ b/gcc/gensupport.cc
> @@ -656,7 +656,7 @@ public:
>       i.e. if rtx is the relevant match_operand or match_scratch then
>       [ns..ns + len) should equal itoa (XINT (rtx, 0)), and if set_attr then
>       [ns..ns + len) should equal XSTR (rtx, 0).  */
> -  conlist (const char *ns, unsigned int len, bool numeric)
> +  conlist (const char *ns, unsigned int len, bool numeric, file_location loc)
>    {
>      /* Trim leading whitespaces.  */
>      while (len > 0 && ISBLANK (*ns))
> @@ -670,16 +670,26 @@ public:
>        if (!ISBLANK (ns[i]))
>       break;
>  
> -    /* Parse off any modifiers.  */
> -    while (len > 0 && !ISALNUM (*ns))
> -      {
> -     con += *(ns++);
> -     len--;
> -      }
> +    /* Only numeric values can have modifiers.  */
> +    if (numeric)
> +      /* Parse off any modifiers.  */
> +      while (len > 0 && !ISALNUM (*ns))
> +     {
> +       if (*ns != '=' && *ns != '+' && *ns != '%')
> +         error_at (loc, "`%c` is not a valid operand modifier", *ns);
> +       con += *(ns++);
> +       len--;
> +     }
>  
>      name.assign (ns, len);
>      if (numeric)
> -      idx = strtol (name.c_str (), (char **)NULL, 10);
> +      {
> +     char *endstr;
> +     /* There should only be a numeric value now... */
> +     idx = strtol (name.c_str (), &endstr, 10);
> +     if (*endstr != '\0')
> +       error_at (loc, "operand number expected, found %s", name.c_str ());
> +      }
>    }
>  
>    /* Adds a character to the end of the string.  */
> @@ -832,7 +842,7 @@ parse_section_layout (file_location loc, const char 
> **templ, const char *label,
>         *templ += len;
>         if (val == ',')
>           (*templ)++;
> -       list.push_back (conlist (name_start, len, numeric));
> +       list.push_back (conlist (name_start, len, numeric, loc));
>       }
>      }
>  }
> @@ -845,7 +855,8 @@ parse_section_layout (file_location loc, const char 
> **templ, const char *label,
>  
>  static void
>  parse_section (const char **templ, unsigned int n_elems, unsigned int alt_no,
> -            vec_conlist &list, file_location loc, const char *name)
> +            vec_conlist &list, file_location loc, const char *name,
> +            const char *invalid_chars = NULL)
>  {
>    unsigned int i;
>  
> @@ -856,6 +867,10 @@ parse_section (const char **templ, unsigned int n_elems, 
> unsigned int alt_no,
>        {
>       if (**templ == 0 || **templ == '\n')
>         fatal_at (loc, "missing ']'");
> +     if (invalid_chars
> +         && strchr (invalid_chars, **templ))
> +       error_at (loc, "'%c' is not permitted in an alternative for a %s",
> +                 **templ, name);
>       list[i].add (**templ);
>       if (**templ == ',')
>         {
> @@ -981,7 +996,7 @@ convert_syntax (rtx x, file_location loc)
>         /* Parse the constraint list, then the attribute list.  */
>         if (tconvec.size () > 0)
>           parse_section (&templ, tconvec.size (), alt_no, tconvec, loc,
> -                        "constraint");
> +                        "constraint", "=+%");
>  
>         if (attrvec.size () > 0)
>           {

Reply via email to