aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-11-18 21:51:19 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2010-11-18 21:51:19 +0100
commit63871cda441faa0dcc4cdc5968127d988a3867ae (patch)
treef06cef25453dfeb910d97af097a869bda55bed15 /gcc
parent9916a9e47bc4fba2344bb2c136e277be3007769b (diff)
downloadgcc-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')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/builtins.c25
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr46534.c17
4 files changed, 48 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5375091..12eaf9c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ 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-11-18 Nathan Froyd <froydnj@codesourcery.com>
PR c/33193
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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7ef06b1..e349b19 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/46534
+ * gcc.c-torture/compile/pr46534.c: New test.
+
2010-11-18 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/atomic4.ad[sb]: New test.
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 0000000..3023ad9
--- /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");
+}