diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-11-18 21:51:19 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-11-18 21:51:19 +0100 |
commit | 63871cda441faa0dcc4cdc5968127d988a3867ae (patch) | |
tree | f06cef25453dfeb910d97af097a869bda55bed15 /gcc/builtins.c | |
parent | 9916a9e47bc4fba2344bb2c136e277be3007769b (diff) | |
download | gcc-63871cda441faa0dcc4cdc5968127d988a3867ae.zip gcc-63871cda441faa0dcc4cdc5968127d988a3867ae.tar.gz gcc-63871cda441faa0dcc4cdc5968127d988a3867ae.tar.bz2 |
re PR middle-end/46534 (ICE optimizing printf ("...>10MBstring\n") into puts)
PR middle-end/46534
* builtins.c (fold_builtin_printf): Don't copy and modify string
before build_string_literal, instead modify what
build_string_literal returned.
* gcc.c-torture/compile/pr46534.c: New test.
From-SVN: r166918
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 5f2959c..c9e8e68 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -12892,15 +12892,28 @@ fold_builtin_printf (location_t loc, tree fndecl, tree fmt, { /* If the string was "string\n", call puts("string"). */ size_t len = strlen (str); - if ((unsigned char)str[len - 1] == target_newline) + if ((unsigned char)str[len - 1] == target_newline + && (size_t) (int) len == len + && (int) len > 0) { + char *newstr; + tree offset_node, string_cst; + /* Create a NUL-terminated string that's one char shorter than the original, stripping off the trailing '\n'. */ - char *newstr = XALLOCAVEC (char, len); - memcpy (newstr, str, len - 1); - newstr[len - 1] = 0; - - newarg = build_string_literal (len, newstr); + newarg = build_string_literal (len, str); + string_cst = string_constant (newarg, &offset_node); + gcc_checking_assert (string_cst + && (TREE_STRING_LENGTH (string_cst) + == (int) len) + && integer_zerop (offset_node) + && (unsigned char) + TREE_STRING_POINTER (string_cst)[len - 1] + == target_newline); + /* build_string_literal creates a new STRING_CST, + modify it in place to avoid double copying. */ + newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst)); + newstr[len - 1] = '\0'; if (fn_puts) call = build_call_expr_loc (loc, fn_puts, 1, newarg); } |