Commit 10b04d1e by Richard Sandiford Committed by Richard Sandiford

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
parent 737eb767
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.
Use file_location instead of separate fields.
(md_reader::set_md_ptr_loc): Take a file_location instead of a
......
......@@ -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 *> *);
......
......@@ -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);
file_location loc = read_name (&name);
record_potential_iterator_use (&ints, loc, return_rtx, idx,
name.string);
break;
}
case 'r':
read_name (&name);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment