From 8d2625a8b21bfc6a958d46dd21c0d88c005ca25b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 15 Sep 2007 08:08:15 +0000 Subject: [PATCH] 4.1.2-23.fc7 --- gcc41-builtin-va-arg-pack-len.patch | 368 ++++++++++++++++++++++++++++ gcc41-pr27954.patch | 84 +++++++ gcc41.spec | 11 +- 3 files changed, 462 insertions(+), 1 deletion(-) create mode 100644 gcc41-builtin-va-arg-pack-len.patch create mode 100644 gcc41-pr27954.patch diff --git a/gcc41-builtin-va-arg-pack-len.patch b/gcc41-builtin-va-arg-pack-len.patch new file mode 100644 index 0000000..672cecd --- /dev/null +++ b/gcc41-builtin-va-arg-pack-len.patch @@ -0,0 +1,368 @@ +2007-09-11 Jakub Jelinek + + * builtins.def (BUILT_IN_VA_ARG_PACK_LEN): New builtin. + * builtins.c (expand_builtin) : Issue + error if __builtin_va_arg_pack_len () wasn't optimized out during + inlining. + * tree-inline.c (copy_bb): Replace __builtin_va_arg_pack_len () + with the number of inline's anonymous arguments. + * doc/extend.texi: Document __builtin_va_arg_pack_len (). + + * gcc.dg/va-arg-pack-len-1.c: New test. + * g++.dg/va-arg-pack-len-1.C: New test. + +--- gcc/builtins.def.jj 2007-09-06 10:19:24.000000000 +0200 ++++ gcc/builtins.def 2007-09-14 21:07:41.000000000 +0200 +@@ -666,6 +666,7 @@ DEF_GCC_BUILTIN (BUILT_IN_VA_COPY + DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL) + DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL) + DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LIST) ++DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LIST) + DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) + DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) + +--- gcc/builtins.c.jj 2007-09-06 11:04:56.000000000 +0200 ++++ gcc/builtins.c 2007-09-14 21:07:41.000000000 +0200 +@@ -5985,6 +5985,12 @@ expand_builtin (tree exp, rtx target, rt + error ("invalid use of %<__builtin_va_arg_pack ()%>"); + return const0_rtx; + ++ case BUILT_IN_VA_ARG_PACK_LEN: ++ /* All valid uses of __builtin_va_arg_pack_len () are removed during ++ inlining. */ ++ error ("invalid use of %<__builtin_va_arg_pack_len ()%>"); ++ return const0_rtx; ++ + /* Return the address of the first anonymous stack arg. */ + case BUILT_IN_NEXT_ARG: + if (fold_builtin_next_arg (arglist)) +--- gcc/tree-inline.c.jj 2007-09-06 12:35:57.000000000 +0200 ++++ gcc/tree-inline.c 2007-09-14 21:22:48.000000000 +0200 +@@ -741,6 +741,37 @@ copy_bb (copy_body_data *id, basic_block + *a = copy_list (arglist); + CALL_EXPR_VA_ARG_PACK (call) = 0; + } ++ else if (call ++ && id->call_expr ++ && (decl = get_callee_fndecl (call)) ++ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL ++ && DECL_FUNCTION_CODE (decl) ++ == BUILT_IN_VA_ARG_PACK_LEN) ++ { ++ /* __builtin_va_arg_pack_len () should be replaced by ++ the number of anonymous arguments. */ ++ int nargs; ++ tree count, *call_ptr, p, a; ++ ++ a = TREE_OPERAND (id->call_expr, 1); ++ for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p)) ++ a = TREE_CHAIN (a); ++ ++ for (nargs = 0; a; a = TREE_CHAIN (a)) ++ nargs++; ++ ++ count = build_int_cst (integer_type_node, nargs); ++ call_ptr = &stmt; ++ if (TREE_CODE (*call_ptr) == MODIFY_EXPR) ++ call_ptr = &TREE_OPERAND (*call_ptr, 1); ++ if (TREE_CODE (*call_ptr) == WITH_SIZE_EXPR) ++ call_ptr = &TREE_OPERAND (*call_ptr, 0); ++ gcc_assert (*call_ptr == call && call_ptr != &stmt); ++ *call_ptr = count; ++ update_stmt (stmt); ++ call = NULL_TREE; ++ } ++ + /* We're duplicating a CALL_EXPR. Find any corresponding + callgraph edges and update or duplicate them. */ + if (call && (decl = get_callee_fndecl (call))) +--- gcc/doc/extend.texi.jj 2007-09-06 10:19:25.000000000 +0200 ++++ gcc/doc/extend.texi 2007-09-14 21:07:41.000000000 +0200 +@@ -578,6 +578,41 @@ myprintf (FILE *f, const char *format, . + @end smallexample + @end deftypefn + ++@deftypefn {Built-in Function} __builtin_va_arg_pack_len () ++This built-in function returns the number of anonymous arguments of ++an inline function. It can be used only in inline functions which ++will be always inlined, never compiled as a separate function, such ++as those using @code{__attribute__ ((__always_inline__))} or ++@code{__attribute__ ((__gnu_inline__))} extern inline functions. ++For example following will do link or runtime checking of open ++arguments for optimized code: ++@smallexample ++#ifdef __OPTIMIZE__ ++extern inline __attribute__((__gnu_inline__)) int ++myopen (const char *path, int oflag, ...) ++@{ ++ if (__builtin_va_arg_pack_len () > 1) ++ warn_open_too_many_arguments (); ++ ++ if (__builtin_constant_p (oflag)) ++ @{ ++ if ((oflag & O_CREAT) != 0 && __builtin_va_arg_pack_len () < 1) ++ @{ ++ warn_open_missing_mode (); ++ return __open_2 (path, oflag); ++ @} ++ return open (path, oflag, __builtin_va_arg_pack ()); ++ @} ++ ++ if (__builtin_va_arg_pack_len () < 1) ++ return __open_2 (path, oflag); ++ ++ return open (path, oflag, __builtin_va_arg_pack ()); ++@} ++#endif ++@end smallexample ++@end deftypefn ++ + @node Typeof + @section Referring to a Type with @code{typeof} + @findex typeof +--- gcc/testsuite/gcc.dg/va-arg-pack-len-1.c.jj 2007-09-14 21:07:41.000000000 +0200 ++++ gcc/testsuite/gcc.dg/va-arg-pack-len-1.c 2007-09-14 21:07:41.000000000 +0200 +@@ -0,0 +1,120 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2" } */ ++ ++#include ++ ++extern int warn_open_missing_mode (void); ++extern int warn_open_too_many_arguments (void); ++extern void abort (void); ++ ++char expected_char; ++ ++__attribute__((noinline)) int ++myopen2 (const char *path, int oflag) ++{ ++ if (expected_char++ != path[0] || path[1] != '\0') ++ abort (); ++ switch (path[0]) ++ { ++ case 'f': ++ if (oflag != 0x2) ++ abort (); ++ break; ++ case 'g': ++ if (oflag != 0x43) ++ abort (); ++ /* In real __open_2 this would terminate the program: ++ open with O_CREAT without third argument. */ ++ return -6; ++ default: ++ abort (); ++ } ++ return 0; ++} ++ ++__attribute__((noinline)) int ++myopenva (const char *path, int oflag, ...) ++{ ++ int mode = 0; ++ va_list ap; ++ if ((oflag & 0x40) != 0) ++ { ++ va_start (ap, oflag); ++ mode = va_arg (ap, int); ++ va_end (ap); ++ } ++ if (expected_char++ != path[0] || path[1] != '\0') ++ abort (); ++ switch (path[0]) ++ { ++ case 'a': ++ if (oflag != 0x43 || mode != 0644) ++ abort (); ++ break; ++ case 'b': ++ if (oflag != 0x3) ++ abort (); ++ break; ++ case 'c': ++ if (oflag != 0x2) ++ abort (); ++ break; ++ case 'd': ++ if (oflag != 0x43 || mode != 0600) ++ abort (); ++ break; ++ case 'e': ++ if (oflag != 0x3) ++ abort (); ++ break; ++ default: ++ abort (); ++ } ++ return 0; ++} ++ ++extern inline __attribute__((always_inline, gnu_inline)) int ++myopen (const char *path, int oflag, ...) ++{ ++ if (__builtin_va_arg_pack_len () > 1) ++ warn_open_too_many_arguments (); ++ ++ if (__builtin_constant_p (oflag)) ++ { ++ if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1) ++ { ++ warn_open_missing_mode (); ++ return myopen2 (path, oflag); ++ } ++ return myopenva (path, oflag, __builtin_va_arg_pack ()); ++ } ++ ++ if (__builtin_va_arg_pack_len () < 1) ++ return myopen2 (path, oflag); ++ ++ return myopenva (path, oflag, __builtin_va_arg_pack ()); ++} ++ ++volatile int l0; ++ ++int ++main (void) ++{ ++ expected_char = 'a'; ++ if (myopen ("a", 0x43, 0644)) ++ abort (); ++ if (myopen ("b", 0x3, 0755)) ++ abort (); ++ if (myopen ("c", 0x2)) ++ abort (); ++ if (myopen ("d", l0 + 0x43, 0600)) ++ abort (); ++ if (myopen ("e", l0 + 0x3, 0700)) ++ abort (); ++ if (myopen ("f", l0 + 0x2)) ++ abort (); ++ /* Invalid use of myopen, but only detectable at runtime. */ ++ if (myopen ("g", l0 + 0x43) != -6) ++ abort (); ++ return 0; ++} +--- gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C.jj 2007-09-14 21:07:41.000000000 +0200 ++++ gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C 2007-09-14 21:07:41.000000000 +0200 +@@ -0,0 +1,120 @@ ++// { dg-do run } ++// { dg-options "-O2" } ++ ++#include ++ ++extern "C" int warn_open_missing_mode (void); ++extern "C" int warn_open_too_many_arguments (void); ++extern "C" void abort (void); ++ ++char expected_char; ++ ++__attribute__((noinline)) int ++myopen2 (const char *path, int oflag) ++{ ++ if (expected_char++ != path[0] || path[1] != '\0') ++ abort (); ++ switch (path[0]) ++ { ++ case 'f': ++ if (oflag != 0x2) ++ abort (); ++ break; ++ case 'g': ++ if (oflag != 0x43) ++ abort (); ++ // In real __open_2 this would terminate the program: ++ // open with O_CREAT without third argument. ++ return -6; ++ default: ++ abort (); ++ } ++ return 0; ++} ++ ++__attribute__((noinline)) int ++myopenva (const char *path, int oflag, ...) ++{ ++ int mode = 0; ++ va_list ap; ++ if ((oflag & 0x40) != 0) ++ { ++ va_start (ap, oflag); ++ mode = va_arg (ap, int); ++ va_end (ap); ++ } ++ if (expected_char++ != path[0] || path[1] != '\0') ++ abort (); ++ switch (path[0]) ++ { ++ case 'a': ++ if (oflag != 0x43 || mode != 0644) ++ abort (); ++ break; ++ case 'b': ++ if (oflag != 0x3) ++ abort (); ++ break; ++ case 'c': ++ if (oflag != 0x2) ++ abort (); ++ break; ++ case 'd': ++ if (oflag != 0x43 || mode != 0600) ++ abort (); ++ break; ++ case 'e': ++ if (oflag != 0x3) ++ abort (); ++ break; ++ default: ++ abort (); ++ } ++ return 0; ++} ++ ++extern inline __attribute__((always_inline, gnu_inline)) int ++myopen (const char *path, int oflag, ...) ++{ ++ if (__builtin_va_arg_pack_len () > 1) ++ warn_open_too_many_arguments (); ++ ++ if (__builtin_constant_p (oflag)) ++ { ++ if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1) ++ { ++ warn_open_missing_mode (); ++ return myopen2 (path, oflag); ++ } ++ return myopenva (path, oflag, __builtin_va_arg_pack ()); ++ } ++ ++ if (__builtin_va_arg_pack_len () < 1) ++ return myopen2 (path, oflag); ++ ++ return myopenva (path, oflag, __builtin_va_arg_pack ()); ++} ++ ++volatile int l0; ++ ++int ++main (void) ++{ ++ expected_char = 'a'; ++ if (myopen ("a", 0x43, 0644)) ++ abort (); ++ if (myopen ("b", 0x3, 0755)) ++ abort (); ++ if (myopen ("c", 0x2)) ++ abort (); ++ if (myopen ("d", l0 + 0x43, 0600)) ++ abort (); ++ if (myopen ("e", l0 + 0x3, 0700)) ++ abort (); ++ if (myopen ("f", l0 + 0x2)) ++ abort (); ++ // Invalid use of myopen, but only detectable at runtime. ++ if (myopen ("g", l0 + 0x43) != -6) ++ abort (); ++ return 0; ++} diff --git a/gcc41-pr27954.patch b/gcc41-pr27954.patch new file mode 100644 index 0000000..db11c3a --- /dev/null +++ b/gcc41-pr27954.patch @@ -0,0 +1,84 @@ +2006-10-27 Jerry DeLisle + + PR fortran/27954 + * decl.c (gfc_free_data_all): New function to free all data structures + after errors in DATA statements and declarations. + (top_var_list): Use new function.(top_val_list): Use new function. + (gfc_match_data_decl): Use new function. + + PR libgfortran/27954 + * gfortran.dg/error_recovery_2.f90: New test. + +--- gcc/fortran/decl.c (revision 118083) ++++ gcc/fortran/decl.c (revision 118086) +@@ -128,6 +128,21 @@ gfc_free_data (gfc_data * p) + } + + ++/* Free all data in a namespace. */ ++static void ++gfc_free_data_all (gfc_namespace * ns) ++{ ++ gfc_data *d; ++ ++ for (;ns->data;) ++ { ++ d = ns->data->next; ++ gfc_free (ns->data); ++ ns->data = d; ++ } ++} ++ ++ + static match var_element (gfc_data_variable *); + + /* Match a list of variables terminated by an iterator and a right +@@ -262,6 +277,7 @@ top_var_list (gfc_data * d) + + syntax: + gfc_syntax_error (ST_DATA); ++ gfc_free_data_all (gfc_current_ns); + return MATCH_ERROR; + } + +@@ -374,6 +390,7 @@ top_val_list (gfc_data * data) + + syntax: + gfc_syntax_error (ST_DATA); ++ gfc_free_data_all (gfc_current_ns); + return MATCH_ERROR; + } + +@@ -2368,6 +2385,8 @@ ok: + gfc_error ("Syntax error in data declaration at %C"); + m = MATCH_ERROR; + ++ gfc_free_data_all (gfc_current_ns); ++ + cleanup: + gfc_free_array_spec (current_as); + current_as = NULL; +--- gcc/testsuite/gfortran.dg/error_recovery_2.f90 (revision 0) ++++ gcc/testsuite/gfortran.dg/error_recovery_2.f90 (revision 118086) +@@ -0,0 +1,21 @@ ++! { dg-do compile } ++! PR27954 Internal compiler error on bad statements ++! Derived from test case submitted in PR. ++subroutine bad1 ++ character*20 :: y, x 00 ! { dg-error "Syntax error" } ++ data y /'abcdef'/, x /'jbnhjk'/ pp ! { dg-error "Syntax error" } ++end subroutine bad1 ++ ++subroutine bad2 ++ character*20 :: y, x 00 ! { dg-error "Syntax error" } ++ data y /'abcdef'/, x /'jbnhjk'/ pp ! { dg-error "Syntax error" } ++ print *, "basket case." ++end subroutine bad2 ++ ++subroutine bad3 ++ implicit none ++ character*20 :: y, x 00 ! { dg-error "Syntax error" } ++ data y /'abcdef'/, x /'jbnhjk'/ pp ! { dg-error "Syntax error" } ++ print *, "basket case that segfaults without patch." ++end subroutine bad3 ++ diff --git a/gcc41.spec b/gcc41.spec index db97a1e..689743a 100644 --- a/gcc41.spec +++ b/gcc41.spec @@ -1,6 +1,6 @@ %define DATE 20070821 %define gcc_version 4.1.2 -%define gcc_release 22 +%define gcc_release 23 %define _unpackaged_files_terminate_build 0 %define multilib_64_archs sparc64 ppc64 s390x x86_64 %define include_gappletviewer 1 @@ -148,6 +148,8 @@ Patch33: gcc41-ppc64-ia64-GNU-stack.patch Patch34: gcc41-builtin-chk-anticipated.patch Patch35: gcc41-builtin-throw.patch Patch36: gcc41-builtin-va-arg-pack.patch +Patch37: gcc41-builtin-va-arg-pack-len.patch +Patch38: gcc41-pr27954.patch # On ARM EABI systems, we do want -gnueabi to be part of the # target triple. @@ -467,6 +469,8 @@ which are required to run programs compiled with the GNAT. %patch34 -p0 -b .builtin-chk-anticipated~ %patch35 -p0 -b .builtin-throw~ %patch36 -p0 -b .builtin-va-arg-pack~ +%patch37 -p0 -b .builtin-va-arg-pack-len~ +%patch38 -p0 -b .pr27954~ sed -i -e 's/4\.1\.3/4.1.2/' gcc/BASE-VER gcc/version.c sed -i -e 's/" (Red Hat[^)]*)"/" (Red Hat %{version}-%{gcc_release})"/' gcc/version.c @@ -1621,6 +1625,11 @@ fi %doc rpm.doc/changelogs/libmudflap/ChangeLog* %changelog +* Fri Sep 14 2007 Jakub Jelinek 4.1.2-23.fc7 +- backport __builtin_va_arg_pack_len () support +- fix Fortran error recovery with DATA (Jerry DeLisle, #281331, + PR fortran/27954) + * Fri Sep 7 2007 Jakub Jelinek 4.1.2-22.fc7 - fix __builtin_va_arg_pack () support for C++