Commit cd471b26 by Jakub Jelinek Committed by Jakub Jelinek

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
parent ee6e1303
2018-03-13 Jakub Jelinek <jakub@redhat.com> 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 PR target/84827
* config/i386/i386.md (round<mode>2): For 387 fancy math, disable * config/i386/i386.md (round<mode>2): For 387 fancy math, disable
pattern if -ftrapping-math -fno-fp-int-builtin-inexact. pattern if -ftrapping-math -fno-fp-int-builtin-inexact.
......
...@@ -247,62 +247,68 @@ parse_output_constraint (const char **constraint_p, int operand_num, ...@@ -247,62 +247,68 @@ parse_output_constraint (const char **constraint_p, int operand_num,
} }
/* Loop through the constraint string. */ /* Loop through the constraint string. */
for (p = constraint + 1; *p; p += CONSTRAINT_LEN (*p, p)) for (p = constraint + 1; *p; )
switch (*p) {
{ switch (*p)
case '+': {
case '=': case '+':
error ("operand constraint contains incorrectly positioned " case '=':
"%<+%> or %<=%>"); error ("operand constraint contains incorrectly positioned "
return false; "%<+%> 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 '#':
if (operand_num + 1 == ninputs + noutputs) case '$': case '^':
{ case 'E': case 'F': case 'G': case 'H':
error ("%<%%%> constraint used with last operand"); case 's': case 'i': case 'n':
return false; case 'I': case 'J': case 'K': case 'L': case 'M':
} case 'N': case 'O': case 'P': case ',':
break; break;
case '?': case '!': case '*': case '&': case '#': case '0': case '1': case '2': case '3': case '4':
case '$': case '^': case '5': case '6': case '7': case '8': case '9':
case 'E': case 'F': case 'G': case 'H': case '[':
case 's': case 'i': case 'n': error ("matching constraint not valid in output operand");
case 'I': case 'J': case 'K': case 'L': case 'M': return false;
case 'N': case 'O': case 'P': case ',':
break;
case '0': case '1': case '2': case '3': case '4': case '<': case '>':
case '5': case '6': case '7': case '8': case '9': /* ??? Before flow, auto inc/dec insns are not supposed to exist,
case '[': excepting those that expand_call created. So match memory
error ("matching constraint not valid in output operand"); and hope. */
return false; *allows_mem = true;
break;
case '<': case '>': case 'g': case 'X':
/* ??? Before flow, auto inc/dec insns are not supposed to exist, *allows_reg = true;
excepting those that expand_call created. So match memory *allows_mem = true;
and hope. */ break;
*allows_mem = true;
break;
case 'g': case 'X': default:
*allows_reg = true; if (!ISALPHA (*p))
*allows_mem = true; break;
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;
}
default: for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
if (!ISALPHA (*p)) if (*p == '\0')
break; 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;
}
return true; return true;
} }
......
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