From: Jakub Jelinek Date: Tue, 13 Mar 2018 08:12:07 +0000 (+0100) Subject: re PR middle-end/84831 (Invalid memory read in parse_output_constraint) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cd471b26ca3923f6ca39105c0efe166248ec0425;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20dbd41d9e3..077dcef3f20 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2018-03-13 Jakub Jelinek + 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 (round2): For 387 fancy math, disable pattern if -ftrapping-math -fno-fp-int-builtin-inexact. diff --git a/gcc/stmt.c b/gcc/stmt.c index 457fe7f6f78..9493dccf734 100644 --- a/gcc/stmt.c +++ b/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 '%': - 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 '?': 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 '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 '<': 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; - 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; + } - default: - if (!ISALPHA (*p)) + for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++) + if (*p == '\0') 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; }