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  <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
This commit is contained in:
Richard Sandiford 2019-07-16 08:41:21 +00:00 committed by Richard Sandiford
parent 737eb76789
commit 10b04d1e0b
3 changed files with 67 additions and 24 deletions

View 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.

View 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 *> *);

View 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);