aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-03-13 09:12:07 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-03-13 09:12:07 +0100
commitcd471b26ca3923f6ca39105c0efe166248ec0425 (patch)
tree2156fd4967a528df8a83ab807dd54ad5c85273dd /gcc
parentee6e1303781ca90a35e962c52fe0f6f83a0bc10e (diff)
downloadgcc-cd471b26ca3923f6ca39105c0efe166248ec0425.zip
gcc-cd471b26ca3923f6ca39105c0efe166248ec0425.tar.gz
gcc-cd471b26ca3923f6ca39105c0efe166248ec0425.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/stmt.c104
2 files changed, 60 insertions, 49 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 20dbd41..077dcef 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 457fe7f..9493dcc 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;
}