[committed] Improve error reporting from genattrtab.c
Richard Sandiford
richard.sandiford@arm.com
Tue Dec 1 09:34:00 GMT 2015
The errors reported by check_attr_value weren't very helpful because
they always used the location of the define(_enum)_attr, even if the
error was in a define_insn. Also, the errors reported by
check_attr_test didn't say which attribute was faulty.
Although not technically a bug fix, it was really useful in writing
the patch for PR68432.
Tested on a variety of targets and applied.
Richard
gcc/
* genattrtab.c (check_attr_test): Take an attr_desc instead of
an is_const flag. Put the file_location argument first.
Update recursive calls. Improve error messages.
(check_attr_value): Take a file location and use it instead
of attr->loc. Improve error messages. Update calls to
check_attr_test.
(check_defs): Update call to check_attr_value.
(make_canonical): Likewise.
(gen_attr): Likewise.
(main): Likewise.
(gen_insn_reserv): Update call to check_attr_test.
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 32b837c..2caf8f6 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -729,9 +729,8 @@ attr_copy_rtx (rtx orig)
return copy;
}
-/* Given a test expression for an attribute, ensure it is validly formed.
- IS_CONST indicates whether the expression is constant for each compiler
- run (a constant expression may not test any particular insn).
+/* Given a test expression EXP for attribute ATTR, ensure it is validly
+ formed. LOC is the location of the .md construct that contains EXP.
Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
@@ -744,9 +743,8 @@ attr_copy_rtx (rtx orig)
Return the new expression, if any. */
static rtx
-check_attr_test (rtx exp, int is_const, file_location loc)
+check_attr_test (file_location loc, rtx exp, attr_desc *attr)
{
- struct attr_desc *attr;
struct attr_value *av;
const char *name_ptr, *p;
rtx orexp, newexp;
@@ -756,26 +754,27 @@ check_attr_test (rtx exp, int is_const, file_location loc)
case EQ_ATTR:
/* Handle negation test. */
if (XSTR (exp, 1)[0] == '!')
- return check_attr_test (attr_rtx (NOT,
+ return check_attr_test (loc,
+ attr_rtx (NOT,
attr_eq (XSTR (exp, 0),
&XSTR (exp, 1)[1])),
- is_const, loc);
+ attr);
else if (n_comma_elts (XSTR (exp, 1)) == 1)
{
- attr = find_attr (&XSTR (exp, 0), 0);
- if (attr == NULL)
+ attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
+ if (attr2 == NULL)
{
if (! strcmp (XSTR (exp, 0), "alternative"))
return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1)));
else
- fatal_at (loc, "unknown attribute `%s' in EQ_ATTR",
- XSTR (exp, 0));
+ fatal_at (loc, "unknown attribute `%s' in definition of"
+ " attribute `%s'", XSTR (exp, 0), attr->name);
}
- if (is_const && ! attr->is_const)
- fatal_at (loc, "constant expression uses insn attribute `%s'"
- " in EQ_ATTR", XSTR (exp, 0));
+ if (attr->is_const && ! attr2->is_const)
+ fatal_at (loc, "constant attribute `%s' cannot test non-constant"
+ " attribute `%s'", attr->name, attr2->name);
/* Copy this just to make it permanent,
so expressions using it can be permanent too. */
@@ -784,26 +783,26 @@ check_attr_test (rtx exp, int is_const, file_location loc)
/* It shouldn't be possible to simplify the value given to a
constant attribute, so don't expand this until it's time to
write the test expression. */
- if (attr->is_const)
+ if (attr2->is_const)
ATTR_IND_SIMPLIFIED_P (exp) = 1;
- if (attr->is_numeric)
+ if (attr2->is_numeric)
{
for (p = XSTR (exp, 1); *p; p++)
if (! ISDIGIT (*p))
fatal_at (loc, "attribute `%s' takes only numeric values",
- XSTR (exp, 0));
+ attr2->name);
}
else
{
- for (av = attr->first_value; av; av = av->next)
+ for (av = attr2->first_value; av; av = av->next)
if (GET_CODE (av->value) == CONST_STRING
&& ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
break;
if (av == NULL)
- fatal_at (loc, "unknown value `%s' for `%s' attribute",
- XSTR (exp, 1), XSTR (exp, 0));
+ fatal_at (loc, "unknown value `%s' for attribute `%s'",
+ XSTR (exp, 1), attr2->name);
}
}
else
@@ -829,7 +828,7 @@ check_attr_test (rtx exp, int is_const, file_location loc)
orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
}
- return check_attr_test (orexp, is_const, loc);
+ return check_attr_test (loc, orexp, attr);
}
}
break;
@@ -846,12 +845,12 @@ check_attr_test (rtx exp, int is_const, file_location loc)
case IOR:
case AND:
- XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, loc);
- XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, loc);
+ XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
+ XEXP (exp, 1) = check_attr_test (loc, XEXP (exp, 1), attr);
break;
case NOT:
- XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, loc);
+ XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
break;
case MATCH_TEST:
@@ -860,9 +859,10 @@ check_attr_test (rtx exp, int is_const, file_location loc)
break;
case MATCH_OPERAND:
- if (is_const)
- fatal_at (loc, "RTL operator \"%s\" not valid in constant attribute"
- " test", GET_RTX_NAME (GET_CODE (exp)));
+ if (attr->is_const)
+ fatal_at (loc, "invalid operator `%s' in definition of constant"
+ " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
+ attr->name);
/* These cases can't be simplified. */
ATTR_IND_SIMPLIFIED_P (exp) = 1;
break;
@@ -880,7 +880,7 @@ check_attr_test (rtx exp, int is_const, file_location loc)
break;
case SYMBOL_REF:
- if (is_const)
+ if (attr->is_const)
{
/* These cases are valid for constant attributes, but can't be
simplified. */
@@ -889,21 +889,21 @@ check_attr_test (rtx exp, int is_const, file_location loc)
break;
}
default:
- fatal_at (loc, "RTL operator \"%s\" not valid in attribute test",
- GET_RTX_NAME (GET_CODE (exp)));
+ fatal_at (loc, "invalid operator `%s' in definition of attribute"
+ " `%s'", GET_RTX_NAME (GET_CODE (exp)), attr->name);
}
return exp;
}
-/* Given an expression, ensure that it is validly formed and that all named
- attribute values are valid for the given attribute. Issue a fatal error
- if not.
+/* Given an expression EXP, ensure that it is validly formed and that
+ all named attribute values are valid for ATTR. Issue an error if not.
+ LOC is the location of the .md construct that contains EXP.
Return a perhaps modified replacement expression for the value. */
static rtx
-check_attr_value (rtx exp, struct attr_desc *attr)
+check_attr_value (file_location loc, rtx exp, struct attr_desc *attr)
{
struct attr_value *av;
const char *p;
@@ -914,16 +914,16 @@ check_attr_value (rtx exp, struct attr_desc *attr)
case CONST_INT:
if (!attr->is_numeric)
{
- error_at (attr->loc,
- "CONST_INT not valid for non-numeric attribute %s",
+ error_at (loc,
+ "CONST_INT not valid for non-numeric attribute `%s'",
attr->name);
break;
}
if (INTVAL (exp) < 0)
{
- error_at (attr->loc,
- "negative numeric value specified for attribute %s",
+ error_at (loc,
+ "negative numeric value specified for attribute `%s'",
attr->name);
break;
}
@@ -939,9 +939,9 @@ check_attr_value (rtx exp, struct attr_desc *attr)
for (; *p; p++)
if (! ISDIGIT (*p))
{
- error_at (attr->loc,
- "non-numeric value for numeric attribute %s",
- attr->name);
+ error_at (loc,
+ "non-numeric value specified for numeric"
+ " attribute `%s'", attr->name);
break;
}
break;
@@ -953,15 +953,14 @@ check_attr_value (rtx exp, struct attr_desc *attr)
break;
if (av == NULL)
- error_at (attr->loc, "unknown value `%s' for `%s' attribute",
+ error_at (loc, "unknown value `%s' for attribute `%s'",
XSTR (exp, 0), attr->name);
break;
case IF_THEN_ELSE:
- XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), attr->is_const,
- attr->loc);
- XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
- XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
+ XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
+ XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
+ XEXP (exp, 2) = check_attr_value (loc, XEXP (exp, 2), attr);
break;
case PLUS:
@@ -971,16 +970,17 @@ check_attr_value (rtx exp, struct attr_desc *attr)
case MOD:
if (!attr->is_numeric)
{
- error_at (attr->loc, "invalid operation `%s' for non-numeric"
- " attribute value", GET_RTX_NAME (GET_CODE (exp)));
+ error_at (loc, "invalid operation `%s' for non-numeric"
+ " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
+ attr->name);
break;
}
/* Fall through. */
case IOR:
case AND:
- XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
- XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
+ XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
+ XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
break;
case FFS:
@@ -989,41 +989,42 @@ check_attr_value (rtx exp, struct attr_desc *attr)
case POPCOUNT:
case PARITY:
case BSWAP:
- XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
+ XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
break;
case COND:
if (XVECLEN (exp, 0) % 2 != 0)
{
- error_at (attr->loc, "first operand of COND must have even length");
+ error_at (loc, "first operand of COND must have even length");
break;
}
for (i = 0; i < XVECLEN (exp, 0); i += 2)
{
- XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
- attr->is_const, attr->loc);
+ XVECEXP (exp, 0, i) = check_attr_test (attr->loc,
+ XVECEXP (exp, 0, i),
+ attr);
XVECEXP (exp, 0, i + 1)
- = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
+ = check_attr_value (loc, XVECEXP (exp, 0, i + 1), attr);
}
- XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
+ XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
break;
case ATTR:
{
struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
if (attr2 == NULL)
- error_at (attr->loc, "unknown attribute `%s' in ATTR",
+ error_at (loc, "unknown attribute `%s' in ATTR",
XSTR (exp, 0));
else if (attr->is_const && ! attr2->is_const)
error_at (attr->loc,
- "non-constant attribute `%s' referenced from `%s'",
- XSTR (exp, 0), attr->name);
+ "constant attribute `%s' cannot refer to non-constant"
+ " attribute `%s'", attr->name, attr2->name);
else if (attr->is_numeric != attr2->is_numeric)
- error_at (attr->loc,
+ error_at (loc,
"numeric attribute mismatch calling `%s' from `%s'",
- XSTR (exp, 0), attr->name);
+ attr2->name, attr->name);
}
break;
@@ -1034,8 +1035,8 @@ check_attr_value (rtx exp, struct attr_desc *attr)
return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
default:
- error_at (attr->loc, "invalid operation `%s' for attribute value",
- GET_RTX_NAME (GET_CODE (exp)));
+ error_at (loc, "invalid operator `%s' in definition of attribute `%s'",
+ GET_RTX_NAME (GET_CODE (exp)), attr->name);
break;
}
@@ -1163,7 +1164,7 @@ check_defs (void)
}
XVECEXP (id->def, id->vec_idx, i) = value;
- XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
+ XEXP (value, 1) = check_attr_value (id->loc, XEXP (value, 1), attr);
}
}
}
@@ -1204,7 +1205,7 @@ make_canonical (file_location loc, struct attr_desc *attr, rtx exp)
This makes the COND something that won't be considered an arbitrary
expression by walk_attr_value. */
ATTR_IND_SIMPLIFIED_P (exp) = 1;
- exp = check_attr_value (exp, attr);
+ exp = check_attr_value (loc, exp, attr);
break;
case IF_THEN_ELSE:
@@ -3186,7 +3187,7 @@ gen_attr (md_rtx_info *info)
error_at (info->loc, "`length' attribute must take numeric values");
/* Set up the default value. */
- XEXP (def, 2) = check_attr_value (XEXP (def, 2), attr);
+ XEXP (def, 2) = check_attr_value (info->loc, XEXP (def, 2), attr);
attr->default_val = get_attr_value (info->loc, XEXP (def, 2), attr, -2);
}
@@ -4755,9 +4756,14 @@ gen_insn_reserv (md_rtx_info *info)
struct insn_reserv *decl = oballoc (struct insn_reserv);
rtx def = info->def;
+ struct attr_desc attr;
+ memset (&attr, 0, sizeof (attr));
+ attr.name = DEF_ATTR_STRING (XSTR (def, 0));
+ attr.loc = info->loc;
+
decl->name = DEF_ATTR_STRING (XSTR (def, 0));
decl->default_latency = XINT (def, 1);
- decl->condexp = check_attr_test (XEXP (def, 2), 0, info->loc);
+ decl->condexp = check_attr_test (info->loc, XEXP (def, 2), &attr);
decl->insn_num = n_insn_reservs;
decl->bypassed = false;
decl->next = 0;
@@ -5287,7 +5293,7 @@ main (int argc, char **argv)
for (i = 0; i < MAX_ATTRS_INDEX; i++)
for (attr = attrs[i]; attr; attr = attr->next)
attr->default_val->value
- = check_attr_value (attr->default_val->value, attr);
+ = check_attr_value (attr->loc, attr->default_val->value, attr);
if (have_error)
return FATAL_EXIT_CODE;
More information about the Gcc-patches
mailing list