diff mbox series

[11/11] Report ambiguous uses of .md attributes

Message ID mpta7dswl94.fsf@arm.com
State New
Headers show
Series Diagnose ambiguous .md attribute uses | expand

Commit Message

Richard Sandiford July 5, 2019, 3:31 p.m. UTC
This patch reports an error if the .md file has an unscoped
attribute that maps to more than one possible value.

I'll apply this once the port patches are in.


2019-07-05  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.
diff mbox series

Patch

Index: gcc/read-md.h
===================================================================
--- gcc/read-md.h	2019-07-05 15:08:52.698765764 +0100
+++ gcc/read-md.h	2019-07-05 15:09:08.694633872 +0100
@@ -211,8 +211,8 @@  struct mapping;
   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: gcc/read-rtl.c
===================================================================
--- gcc/read-rtl.c	2019-07-01 09:37:05.780536545 +0100
+++ gcc/read-rtl.c	2019-07-05 15:09:08.694633872 +0100
@@ -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 *att
 
 /* 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
   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
 	  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 (con
   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 o
 
   /* 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 o
     {
       *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 *ite
   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
       /* 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 ch
       /* 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 *c
   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
 		|| 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
 	    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
     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);