Report ambiguous uses of .md attributes
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 16 Jul 2019 08:41:21 +0000 (08:41 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 16 Jul 2019 08:41:21 +0000 (08:41 +0000)
This patch reports an error if the .md file has an unscoped
attribute that maps to more than one possible value.

2019-07-16  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* read-md.h (md_reader::record_potential_iterator_use): Add a
file_location parameter.
* read-rtl.c (attribute_use::loc): New field.
(map_attr_string): Take a file_location parameter.  Report cases
in which attributes map to multiple distinct values.
(apply_attribute_uses): Update call accordingly.
(md_reader::handle_overloaded_name): Likewise.
(md_reader::apply_iterator_to_string): Likewise.  Skip empty
nonnull strings.
(record_attribute_use): Take a file_location parameter.
Initialize attribute_use::loc.
(md_reader::record_potential_iterator_use): Take a file_location
parameter.  Update call to record_attribute_use.
(rtx_reader::rtx_alloc_for_name): Update call accordingly.
(rtx_reader::read_rtx_code): Likewise.
(rtx_reader::read_rtx_operand): Likewise.  Record a location
for implicitly-expanded empty strings.

From-SVN: r273511

gcc/ChangeLog
gcc/read-md.h
gcc/read-rtl.c

index ec6567db92b20f3dbe89bcc6f61c27e740e5c28c..30e6e7ef4b08275524ff0ae51e60a14a1e599e98 100644 (file)
@@ -1,3 +1,23 @@
+2019-07-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * read-md.h (md_reader::record_potential_iterator_use): Add a
+       file_location parameter.
+       * read-rtl.c (attribute_use::loc): New field.
+       (map_attr_string): Take a file_location parameter.  Report cases
+       in which attributes map to multiple distinct values.
+       (apply_attribute_uses): Update call accordingly.
+       (md_reader::handle_overloaded_name): Likewise.
+       (md_reader::apply_iterator_to_string): Likewise.  Skip empty
+       nonnull strings.
+       (record_attribute_use): Take a file_location parameter.
+       Initialize attribute_use::loc.
+       (md_reader::record_potential_iterator_use): Take a file_location
+       parameter.  Update call to record_attribute_use.
+       (rtx_reader::rtx_alloc_for_name): Update call accordingly.
+       (rtx_reader::read_rtx_code): Likewise.
+       (rtx_reader::read_rtx_operand): Likewise.  Record a location
+       for implicitly-expanded empty strings.
+
 2019-07-16  Richard Sandiford  <richard.sandiford@arm.com>
 
        * read-md.h (md_reader::ptr_loc): Moved from read-md.c.
index eff40126f331c906273a088105d45b7ea7697ea7..377b9f186c5e3e463c6eee3f46c64dd51b2872ef 100644 (file)
@@ -212,8 +212,8 @@ class md_reader
   rtx copy_rtx_for_iterators (rtx original);
   void read_conditions ();
   void record_potential_iterator_use (struct iterator_group *group,
-                                     rtx x, unsigned int index,
-                                     const char *name);
+                                     file_location loc, rtx x,
+                                     unsigned int index, const char *name);
   struct mapping *read_mapping (struct iterator_group *group, htab_t table);
   overloaded_name *handle_overloaded_name (rtx, vec<mapping *> *);
 
index 6b1b811cbfeaba05bf7492fe91f06baac4578606..3b5d999760314b2927df85a7d9ee48516de17dd7 100644 (file)
@@ -106,6 +106,9 @@ struct attribute_use {
   /* The group that describes the use site.  */
   struct iterator_group *group;
 
+  /* The location at which the use occurs.  */
+  file_location loc;
+
   /* The name of the attribute, possibly with an "iterator:" prefix.  */
   const char *value;
 
@@ -361,10 +364,10 @@ find_subst_iter_by_attr (const char *attr)
 
 /* Map attribute string P to its current value.  Return null if the attribute
    isn't known.  If ITERATOR_OUT is nonnull, store the associated iterator
-   there.  */
+   there.  Report any errors against location LOC.  */
 
 static struct map_value *
-map_attr_string (const char *p, mapping **iterator_out = 0)
+map_attr_string (file_location loc, const char *p, mapping **iterator_out = 0)
 {
   const char *attr;
   struct mapping *iterator;
@@ -372,6 +375,8 @@ map_attr_string (const char *p, mapping **iterator_out = 0)
   struct mapping *m;
   struct map_value *v;
   int iterator_name_len;
+  struct map_value *res = NULL;
+  struct mapping *prev = NULL;
 
   /* Peel off any "iterator:" prefix.  Set ATTR to the start of the
      attribute name.  */
@@ -414,13 +419,22 @@ map_attr_string (const char *p, mapping **iterator_out = 0)
          for (v = m->values; v; v = v->next)
            if (v->number == iterator->current_value->number)
              {
+               if (res && strcmp (v->string, res->string) != 0)
+                 {
+                   error_at (loc, "ambiguous attribute '%s'; could be"
+                             " '%s' (via '%s:%s') or '%s' (via '%s:%s')",
+                             attr, res->string, prev->name, attr,
+                             v->string, iterator->name, attr);
+                   return v;
+                 }
                if (iterator_out)
                  *iterator_out = iterator;
-               return v;
+               prev = iterator;
+               res = v;
              }
        }
     }
-  return NULL;
+  return res;
 }
 
 /* Apply the current iterator values to STRING.  Return the new string
@@ -432,16 +446,17 @@ md_reader::apply_iterator_to_string (const char *string)
   char *base, *copy, *p, *start, *end;
   struct map_value *v;
 
-  if (string == 0)
+  if (string == 0 || string[0] == 0)
     return string;
 
+  file_location loc = get_md_ptr_loc (string)->loc;
   base = p = copy = ASTRDUP (string);
   while ((start = strchr (p, '<')) && (end = strchr (start, '>')))
     {
       p = start + 1;
 
       *end = 0;
-      v = map_attr_string (p);
+      v = map_attr_string (loc, p);
       *end = '>';
       if (v == 0)
        continue;
@@ -572,7 +587,7 @@ apply_attribute_uses (void)
 
   FOR_EACH_VEC_ELT (attribute_uses, i, ause)
     {
-      v = map_attr_string (ause->value);
+      v = map_attr_string (ause->loc, ause->value);
       if (!v)
        fatal_with_file_and_line ("unknown iterator value `%s'", ause->value);
       ause->group->apply_iterator (ause->x, ause->index,
@@ -656,6 +671,7 @@ md_reader::handle_overloaded_name (rtx original, vec<mapping *> *iterators)
 
   /* Remove the '@', so that no other code needs to worry about it.  */
   const char *name = XSTR (original, 0);
+  file_location loc = get_md_ptr_loc (name)->loc;
   copy_md_ptr_loc (name + 1, name);
   name += 1;
   XSTR (original, 0) = name;
@@ -672,7 +688,7 @@ md_reader::handle_overloaded_name (rtx original, vec<mapping *> *iterators)
     {
       *end = 0;
       mapping *iterator;
-      if (!map_attr_string (start + 1, &iterator))
+      if (!map_attr_string (loc, start + 1, &iterator))
        fatal_with_file_and_line ("unknown iterator `%s'", start + 1);
       *end = '>';
 
@@ -1126,24 +1142,25 @@ record_iterator_use (struct mapping *iterator, rtx x, unsigned int index)
   iterator_uses.safe_push (iuse);
 }
 
-/* Record that X uses attribute VALUE, which must match a built-in
-   value from group GROUP.  If the use is in an operand of X, INDEX
-   is the index of that operand, otherwise it is ignored.  */
+/* Record that X uses attribute VALUE at location LOC, where VALUE must
+   match a built-in value from group GROUP.  If the use is in an operand
+   of X, INDEX is the index of that operand, otherwise it is ignored.  */
 
 static void
-record_attribute_use (struct iterator_group *group, rtx x,
+record_attribute_use (struct iterator_group *group, file_location loc, rtx x,
                      unsigned int index, const char *value)
 {
-  struct attribute_use ause = {group, value, x, index};
+  struct attribute_use ause = {group, loc, value, x, index};
   attribute_uses.safe_push (ause);
 }
 
 /* Interpret NAME as either a built-in value, iterator or attribute
    for group GROUP.  X and INDEX are the values to pass to GROUP's
-   apply_iterator callback.  */
+   apply_iterator callback.  LOC is the location of the use.  */
 
 void
 md_reader::record_potential_iterator_use (struct iterator_group *group,
+                                         file_location loc,
                                          rtx x, unsigned int index,
                                          const char *name)
 {
@@ -1156,7 +1173,7 @@ md_reader::record_potential_iterator_use (struct iterator_group *group,
       /* Copy the attribute string into permanent storage, without the
         angle brackets around it.  */
       obstack_grow0 (&m_string_obstack, name + 1, len - 2);
-      record_attribute_use (group, x, index,
+      record_attribute_use (group, loc, x, index,
                            XOBFINISH (&m_string_obstack, char *));
     }
   else
@@ -1540,7 +1557,8 @@ rtx_reader::rtx_alloc_for_name (const char *name)
       /* Pick the first possible code for now, and record the attribute
         use for later.  */
       rtx x = rtx_alloc (check_code_attribute (m));
-      record_attribute_use (&codes, x, 0, deferred_name);
+      record_attribute_use (&codes, get_current_location (),
+                           x, 0, deferred_name);
       return x;
     }
 
@@ -1639,8 +1657,8 @@ rtx_reader::read_rtx_code (const char *code_name)
   c = read_skip_spaces ();
   if (c == ':')
     {
-      read_name (&name);
-      record_potential_iterator_use (&modes, return_rtx, 0, name.string);
+      file_location loc = read_name (&name);
+      record_potential_iterator_use (&modes, loc, return_rtx, 0, name.string);
     }
   else
     unread_char (c);
@@ -1862,6 +1880,7 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
                || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT
                || GET_CODE (return_rtx) == DEFINE_INSN_AND_REWRITE))
          {
+           const char *old_stringbuf = stringbuf;
            struct obstack *string_obstack = get_string_obstack ();
            char line_name[20];
            const char *read_md_filename = get_filename ();
@@ -1875,6 +1894,7 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
            sprintf (line_name, ":%d", get_lineno ());
            obstack_grow (string_obstack, line_name, strlen (line_name)+1);
            stringbuf = XOBFINISH (string_obstack, char *);
+           copy_md_ptr_loc (stringbuf, old_stringbuf);
          }
 
        /* Find attr-names in the string.  */
@@ -1946,10 +1966,13 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
     case 'i':
     case 'n':
     case 'p':
-      /* Can be an iterator or an integer constant.  */
-      read_name (&name);
-      record_potential_iterator_use (&ints, return_rtx, idx, name.string);
-      break;
+      {
+       /* Can be an iterator or an integer constant.  */
+       file_location loc = read_name (&name);
+       record_potential_iterator_use (&ints, loc, return_rtx, idx,
+                                      name.string);
+       break;
+      }
 
     case 'r':
       read_name (&name);