re PR middle-end/84831 (Invalid memory read in parse_output_constraint)
PR middle-end/84831 * stmt.c (parse_output_constraint): If the CONSTRAINT_LEN (*p, p) characters starting at p contain '\0' character, don't look beyond that. From-SVN: r258478
This commit is contained in:
parent
ee6e130378
commit
cd471b26ca
@ -1,5 +1,10 @@
|
||||
2018-03-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/84831
|
||||
* stmt.c (parse_output_constraint): If the CONSTRAINT_LEN (*p, p)
|
||||
characters starting at p contain '\0' character, don't look beyond
|
||||
that.
|
||||
|
||||
PR target/84827
|
||||
* config/i386/i386.md (round<mode>2): For 387 fancy math, disable
|
||||
pattern if -ftrapping-math -fno-fp-int-builtin-inexact.
|
||||
|
112
gcc/stmt.c
112
gcc/stmt.c
@ -247,62 +247,68 @@ parse_output_constraint (const char **constraint_p, int operand_num,
|
||||
}
|
||||
|
||||
/* Loop through the constraint string. */
|
||||
for (p = constraint + 1; *p; p += CONSTRAINT_LEN (*p, p))
|
||||
switch (*p)
|
||||
{
|
||||
case '+':
|
||||
case '=':
|
||||
error ("operand constraint contains incorrectly positioned "
|
||||
"%<+%> or %<=%>");
|
||||
return false;
|
||||
for (p = constraint + 1; *p; )
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case '+':
|
||||
case '=':
|
||||
error ("operand constraint contains incorrectly positioned "
|
||||
"%<+%> or %<=%>");
|
||||
return false;
|
||||
|
||||
case '%':
|
||||
if (operand_num + 1 == ninputs + noutputs)
|
||||
{
|
||||
error ("%<%%%> constraint used with last operand");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case '?': case '!': case '*': case '&': case '#':
|
||||
case '$': case '^':
|
||||
case 'E': case 'F': case 'G': case 'H':
|
||||
case 's': case 'i': case 'n':
|
||||
case 'I': case 'J': case 'K': case 'L': case 'M':
|
||||
case 'N': case 'O': case 'P': case ',':
|
||||
break;
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '[':
|
||||
error ("matching constraint not valid in output operand");
|
||||
return false;
|
||||
|
||||
case '<': case '>':
|
||||
/* ??? Before flow, auto inc/dec insns are not supposed to exist,
|
||||
excepting those that expand_call created. So match memory
|
||||
and hope. */
|
||||
*allows_mem = true;
|
||||
break;
|
||||
|
||||
case 'g': case 'X':
|
||||
*allows_reg = true;
|
||||
*allows_mem = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!ISALPHA (*p))
|
||||
case '%':
|
||||
if (operand_num + 1 == ninputs + noutputs)
|
||||
{
|
||||
error ("%<%%%> constraint used with last operand");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
enum constraint_num cn = lookup_constraint (p);
|
||||
if (reg_class_for_constraint (cn) != NO_REGS
|
||||
|| insn_extra_address_constraint (cn))
|
||||
*allows_reg = true;
|
||||
else if (insn_extra_memory_constraint (cn))
|
||||
|
||||
case '?': case '!': case '*': case '&': case '#':
|
||||
case '$': case '^':
|
||||
case 'E': case 'F': case 'G': case 'H':
|
||||
case 's': case 'i': case 'n':
|
||||
case 'I': case 'J': case 'K': case 'L': case 'M':
|
||||
case 'N': case 'O': case 'P': case ',':
|
||||
break;
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '[':
|
||||
error ("matching constraint not valid in output operand");
|
||||
return false;
|
||||
|
||||
case '<': case '>':
|
||||
/* ??? Before flow, auto inc/dec insns are not supposed to exist,
|
||||
excepting those that expand_call created. So match memory
|
||||
and hope. */
|
||||
*allows_mem = true;
|
||||
else
|
||||
insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g': case 'X':
|
||||
*allows_reg = true;
|
||||
*allows_mem = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!ISALPHA (*p))
|
||||
break;
|
||||
enum constraint_num cn = lookup_constraint (p);
|
||||
if (reg_class_for_constraint (cn) != NO_REGS
|
||||
|| insn_extra_address_constraint (cn))
|
||||
*allows_reg = true;
|
||||
else if (insn_extra_memory_constraint (cn))
|
||||
*allows_mem = true;
|
||||
else
|
||||
insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
|
||||
if (*p == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user