From 10b04d1e0b3f4435a8f2e806fddf12ff8b864623 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 16 Jul 2019 08:41:21 +0000 Subject: [PATCH] Report ambiguous uses of .md attributes 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 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 | 20 ++++++++++++++++++ gcc/read-md.h | 4 ++-- gcc/read-rtl.c | 67 +++++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec6567d..30e6e7e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,25 @@ 2019-07-16 Richard Sandiford + * 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 + * read-md.h (md_reader::ptr_loc): Moved from read-md.c. Use file_location instead of separate fields. (md_reader::set_md_ptr_loc): Take a file_location instead of a diff --git a/gcc/read-md.h b/gcc/read-md.h index eff4012..377b9f1 100644 --- a/gcc/read-md.h +++ b/gcc/read-md.h @@ -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 *); diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 6b1b811..3b5d999 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -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 *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 *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); -- 2.7.4