From: Jakub Jelinek Date: Tue, 7 Dec 2010 18:56:56 +0000 (+0100) Subject: re PR middle-end/46534 (ICE optimizing printf ("...>10MBstring\n") into puts) X-Git-Tag: releases/gcc-4.4.6~234 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=adcb78e00941f3d6d6e15d22618359613b600cff;p=thirdparty%2Fgcc.git re PR middle-end/46534 (ICE optimizing printf ("...>10MBstring\n") into puts) PR middle-end/46534 * builtins.c (expand_builtin_printf): Don't copy and modify string before build_string_literal, instead modify what build_string_literal returned. Backport from mainline 2010-11-18 Jakub Jelinek 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: r167558 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3163042f9373..2a9a61fa0cf3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2010-12-07 Jakub Jelinek + + PR middle-end/46534 + * builtins.c (expand_builtin_printf): Don't copy and modify string + before build_string_literal, instead modify what + build_string_literal returned. + + Backport from mainline + 2010-11-18 Jakub Jelinek + + 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. + 2010-12-05 Richard Guenther Ira Rosen diff --git a/gcc/builtins.c b/gcc/builtins.c index 5a84ed4d163e..34a7d24f44b2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5452,14 +5452,30 @@ expand_builtin_printf (tree exp, rtx target, enum machine_mode mode, { /* If the format specifier was "string\n", call puts("string"). */ size_t len = strlen (fmt_str); - if ((unsigned char)fmt_str[len - 1] == target_newline) + if ((unsigned char)fmt_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, fmt_str, len - 1); - newstr[len - 1] = 0; - arg = build_string_literal (len, newstr); + arg = build_string_literal (len, fmt_str); + string_cst = string_constant (arg, &offset_node); +#ifdef ENABLE_CHECKING + gcc_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); +#endif + /* 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) fn = build_call_expr (fn_puts, 1, arg); } @@ -12844,15 +12860,30 @@ fold_builtin_printf (tree fndecl, tree fmt, tree arg, bool ignore, { /* 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); +#ifdef ENABLE_CHECKING + gcc_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); +#endif + /* 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 (fn_puts, 1, newarg); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4d6d82075a1..80b9b208f2bf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-12-07 Jakub Jelinek + + Backport from mainline + 2010-11-18 Jakub Jelinek + PR middle-end/46534 + * gcc.c-torture/compile/pr46534.c: New test. + 2010-12-06 Rainer Orth * ada/acats/run_acats (which): Assign output to temporary diff --git a/gcc/testsuite/gcc.c-torture/compile/pr46534.c b/gcc/testsuite/gcc.c-torture/compile/pr46534.c new file mode 100644 index 000000000000..3023ad9f996e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr46534.c @@ -0,0 +1,17 @@ +/* PR middle-end/46534 */ + +extern int printf (const char *, ...); + +#define S1 " " +#define S2 S1 S1 S1 S1 S1 S1 S1 S1 S1 S1 +#define S3 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 +#define S4 S3 S3 S3 S3 S3 S3 S3 S3 S3 S3 +#define S5 S4 S4 S4 S4 S4 S4 S4 S4 S4 S4 +#define S6 S5 S5 S5 S5 S5 S5 S5 S5 S5 S5 +#define S7 S6 S6 S6 S6 S6 S6 S6 S6 S6 S6 + +void +foo (void) +{ + printf (S7 "\n"); +}