This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.0 PATCH]: fix PR middle-end/25022 (take 2)
- From: "Kaveh R. Ghazi" <ghazi at caipclassic dot rutgers dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mark at codesourcery dot com
- Date: Thu, 1 Dec 2005 17:39:10 -0500 (EST)
- Subject: [4.0 PATCH]: fix PR middle-end/25022 (take 2)
This is an updated patch to fix PR middle-end/25022 on the 4.0 branch.
The fix is already in mainline/4.1 and the one problem that cropped up
on hpux (PR 25158) was straightened out. This updated patch merely
combines the original patch plus the fix for hpux.
I bootstrapped the patch below on i686-unknown-linux-gnu, no
regressions. Okay for 4.0?
Thanks,
--Kaveh
2005-11-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
PR middle-end/25022
* builtins.c (expand_builtin_printf, expand_builtin_fprintf,
fold_builtin_fputs): Lookup the explicit replacement functions
for any unlocked stdio builtin transformations.
PR middle-end/25158
* builtins.c (fold_builtin_fputs): Defer check for missing
replacement functions.
testsuite:
* gcc.c-torture/execute/builtins/fprintf.c,
gcc.c-torture/execute/builtins/fputs-lib.c,
gcc.c-torture/execute/builtins/fputs.c,
gcc.c-torture/execute/builtins/lib/fprintf.c,
gcc.c-torture/execute/builtins/lib/printf.c,
gcc.c-torture/execute/builtins/printf.c: Test the unlocked style.
diff -rup orig/egcc-4.0-SVN20051130/gcc/builtins.c egcc-4.0-SVN20051130/gcc/builtins.c
--- orig/egcc-4.0-SVN20051130/gcc/builtins.c 2005-11-29 00:19:26.000000000 -0500
+++ egcc-4.0-SVN20051130/gcc/builtins.c 2005-11-30 21:49:58.000000000 -0500
@@ -4663,11 +4663,12 @@ expand_builtin_printf (tree exp, rtx tar
bool unlocked)
{
tree arglist = TREE_OPERAND (exp, 1);
- tree fn_putchar = unlocked
- ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
- : implicit_built_in_decls[BUILT_IN_PUTCHAR];
- tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
- : implicit_built_in_decls[BUILT_IN_PUTS];
+ /* If we're using an unlocked function, assume the other unlocked
+ functions exist explicitly. */
+ tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_PUTCHAR];
+ tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_PUTS];
const char *fmt_str;
tree fn, fmt, arg;
@@ -4772,10 +4773,12 @@ expand_builtin_fprintf (tree exp, rtx ta
bool unlocked)
{
tree arglist = TREE_OPERAND (exp, 1);
- tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
- : implicit_built_in_decls[BUILT_IN_FPUTC];
- tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
- : implicit_built_in_decls[BUILT_IN_FPUTS];
+ /* If we're using an unlocked function, assume the other unlocked
+ functions exist explicitly. */
+ tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FPUTC];
+ tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FPUTS];
const char *fmt_str;
tree fn, fmt, fp, arg;
@@ -8953,14 +8956,15 @@ tree
fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
{
tree fn;
- tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+ /* If we're using an unlocked function, assume the other unlocked
+ functions exist explicitly. */
+ tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
: implicit_built_in_decls[BUILT_IN_FPUTC];
- tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
+ tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
: implicit_built_in_decls[BUILT_IN_FWRITE];
- /* If the return value is used, or the replacement _DECL isn't
- initialized, don't do the transformation. */
- if (!ignore || !fn_fputc || !fn_fwrite)
+ /* If the return value is used, don't do the transformation. */
+ if (!ignore)
return 0;
/* Verify the arguments in the original call. */
@@ -9022,6 +9026,11 @@ fold_builtin_fputs (tree arglist, bool i
gcc_unreachable ();
}
+ /* If the replacement _DECL isn't initialized, don't do the
+ transformation. */
+ if (!fn)
+ return 0;
+
/* These optimizations are only performed when the result is ignored,
hence there's no need to cast the result to integer_type_node. */
return build_function_call_expr (fn, arglist);
diff -rup orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fprintf.c egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fprintf.c
--- orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fprintf.c 2005-11-03 10:42:19.000000000 -0500
+++ egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fprintf.c 2005-11-30 21:49:48.000000000 -0500
@@ -6,6 +6,7 @@
Written by Kaveh R. Ghazi, 1/7/2001. */
#include <stdio.h>
+extern int fprintf_unlocked (FILE *, const char *, ...);
extern void abort(void);
void
@@ -15,6 +16,8 @@ main_test (void)
const char *const s1 = "hello world";
const char *const s2[] = { s1, 0 }, *const*s3;
+ fprintf (*s_ptr, "");
+ fprintf (*s_ptr, "%s", "");
fprintf (*s_ptr, "%s", "hello");
fprintf (*s_ptr, "%s", "\n");
fprintf (*s_ptr, "%s", *s2);
@@ -49,4 +52,10 @@ main_test (void)
/* Test at least one instance of the __builtin_ style. We do this
to ensure that it works and that the prototype is correct. */
__builtin_fprintf (*s_ptr, "%s", "hello world\n");
+ /* Check the unlocked style, these evaluate to nothing to avoid
+ problems on systems without the unlocked functions. */
+ fprintf_unlocked (*s_ptr, "");
+ __builtin_fprintf_unlocked (*s_ptr, "");
+ fprintf_unlocked (*s_ptr, "%s", "");
+ __builtin_fprintf_unlocked (*s_ptr, "%s", "");
}
diff -rup orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs-lib.c egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs-lib.c
--- orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs-lib.c 2005-11-03 10:42:19.000000000 -0500
+++ egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs-lib.c 2005-11-30 21:49:48.000000000 -0500
@@ -15,3 +15,9 @@ fputs(const char *string, FILE *stream)
return n > r ? EOF : 0;
}
+/* Locking stdio doesn't matter for the purposes of this test. */
+int
+fputs_unlocked(const char *string, FILE *stream)
+{
+ return fputs (string, stream);
+}
diff -rup orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs.c egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs.c
--- orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs.c 2005-11-03 10:42:19.000000000 -0500
+++ egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/fputs.c 2005-11-30 21:49:48.000000000 -0500
@@ -49,6 +49,10 @@ main_test(void)
prototypes are set correctly too. */
__builtin_fputc ('\n', *s_ptr);
__builtin_fwrite ("hello\n", 1, 6, *s_ptr);
+ /* Check the unlocked style, these evaluate to nothing to avoid
+ problems on systems without the unlocked functions. */
+ fputs_unlocked ("", *s_ptr);
+ __builtin_fputs_unlocked ("", *s_ptr);
/* Check side-effects in conditional expression. */
s_ptr = s_array;
diff -rup orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/fprintf.c egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/fprintf.c
--- orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/fprintf.c 2005-11-03 10:42:19.000000000 -0500
+++ egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/fprintf.c 2005-11-30 21:49:48.000000000 -0500
@@ -16,3 +16,19 @@ fprintf (FILE *fp, const char *string, .
va_end (ap);
return r;
}
+
+/* Locking stdio doesn't matter for the purposes of this test. */
+int
+fprintf_unlocked (FILE *fp, const char *string, ...)
+{
+ va_list ap;
+ int r;
+#ifdef __OPTIMIZE__
+ if (inside_main)
+ abort();
+#endif
+ va_start (ap, string);
+ r = vfprintf (fp, string, ap);
+ va_end (ap);
+ return r;
+}
diff -rup orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/printf.c egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/printf.c
--- orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/printf.c 2005-11-03 10:42:19.000000000 -0500
+++ egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/lib/printf.c 2005-11-30 21:49:48.000000000 -0500
@@ -17,3 +17,19 @@ printf (const char *string, ...)
return r;
}
+
+/* Locking stdio doesn't matter for the purposes of this test. */
+int
+printf_unlocked (const char *string, ...)
+{
+ va_list ap;
+ int r;
+#ifdef __OPTIMIZE__
+ if (inside_main)
+ abort();
+#endif
+ va_start (ap, string);
+ r = vprintf (string, ap);
+ va_end (ap);
+ return r;
+}
diff -rup orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/printf.c egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/printf.c
--- orig/egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/printf.c 2005-11-03 10:42:19.000000000 -0500
+++ egcc-4.0-SVN20051130/gcc/testsuite/gcc.c-torture/execute/builtins/printf.c 2005-11-30 21:49:48.000000000 -0500
@@ -6,6 +6,7 @@
Written by Kaveh R. Ghazi, 12/4/2000. */
extern int printf (const char *, ...);
+extern int printf_unlocked (const char *, ...);
extern void abort(void);
void
@@ -28,6 +29,7 @@ main_test (void)
if (s3 != s2+1 || *s3 != 0)
abort();
+ printf ("");
printf ("\n");
printf ("hello world\n");
@@ -38,4 +40,8 @@ main_test (void)
prototypes are set correctly too. */
__builtin_putchar ('\n');
__builtin_puts ("hello");
+ /* Check the unlocked style, these evaluate to nothing to avoid
+ problems on systems without the unlocked functions. */
+ printf_unlocked ("");
+ __builtin_printf_unlocked ("");
}