diff options
Diffstat (limited to 'packages/gcc/gcc-4.3.1/fedora/gcc43-pr33763.patch')
-rw-r--r-- | packages/gcc/gcc-4.3.1/fedora/gcc43-pr33763.patch | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/packages/gcc/gcc-4.3.1/fedora/gcc43-pr33763.patch b/packages/gcc/gcc-4.3.1/fedora/gcc43-pr33763.patch new file mode 100644 index 0000000000..9e9c90d271 --- /dev/null +++ b/packages/gcc/gcc-4.3.1/fedora/gcc43-pr33763.patch @@ -0,0 +1,153 @@ +2007-11-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/33763 + * gcc.dg/pr33763.c: New test. + * g++.dg/opt/inline13.C: New test. + +2007-11-06 Jan Hubicka <jh@suse.cz> + + PR tree-optimization/33763 + * tree-inline.c (expand_call_inline): Silently ignore always_inline + attribute for redefined extern inline functions. + +--- gcc/tree-inline.c.jj 2007-11-06 09:29:04.000000000 +0100 ++++ gcc/tree-inline.c 2007-11-06 16:19:12.000000000 +0100 +@@ -2582,6 +2582,12 @@ expand_call_inline (basic_block bb, tree + if (!cgraph_inline_p (cg_edge, &reason)) + { + if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) ++ /* For extern inline functions that get redefined we always ++ silently ignored alway_inline flag. Better behaviour would ++ be to be able to keep both bodies and use extern inline body ++ for inlining, but we can't do that because frontends overwrite ++ the body. */ ++ && !cg_edge->callee->local.redefined_extern_inline + /* Avoid warnings during early inline pass. */ + && (!flag_unit_at_a_time || cgraph_global_info_ready)) + { +--- gcc/testsuite/gcc.dg/pr33763.c.jj 2007-11-06 16:19:12.000000000 +0100 ++++ gcc/testsuite/gcc.dg/pr33763.c 2007-11-06 16:19:12.000000000 +0100 +@@ -0,0 +1,60 @@ ++/* PR tree-optimization/33763 */ ++/* { dg-do compile } */ ++/* { dg-options "-O2" } */ ++ ++typedef struct ++{ ++ void *a; ++ void *b; ++} T; ++extern void *foo (const char *, const char *); ++extern void *bar (void *, const char *, T); ++extern int baz (const char *, int); ++ ++extern inline __attribute__ ((always_inline, gnu_inline)) int ++baz (const char *x, int y) ++{ ++ return 2; ++} ++ ++int ++baz (const char *x, int y) ++{ ++ return 1; ++} ++ ++int xa, xb; ++ ++static void * ++inl (const char *x, const char *y) ++{ ++ T t = { &xa, &xb }; ++ int *f = (int *) __builtin_malloc (sizeof (int)); ++ const char *z; ++ int o = 0; ++ void *r = 0; ++ ++ for (z = y; *z; z++) ++ { ++ if (*z == 'r') ++ o |= 1; ++ if (*z == 'w') ++ o |= 2; ++ } ++ if (o == 1) ++ *f = baz (x, 0); ++ if (o == 2) ++ *f = baz (x, 1); ++ if (o == 3) ++ *f = baz (x, 2); ++ ++ if (o && *f > 0) ++ r = bar (f, "w", t); ++ return r; ++} ++ ++void * ++foo (const char *x, const char *y) ++{ ++ return inl (x, y); ++} +--- gcc/testsuite/g++.dg/opt/inline13.C.jj 2007-11-06 16:20:20.000000000 +0100 ++++ gcc/testsuite/g++.dg/opt/inline13.C 2007-11-06 16:21:30.000000000 +0100 +@@ -0,0 +1,60 @@ ++// PR tree-optimization/33763 ++// { dg-do compile } ++// { dg-options "-O2" } ++ ++typedef struct ++{ ++ void *a; ++ void *b; ++} T; ++extern void *foo (const char *, const char *); ++extern void *bar (void *, const char *, T); ++extern int baz (const char *, int); ++ ++extern inline __attribute__ ((always_inline, gnu_inline)) int ++baz (const char *x, int y) ++{ ++ return 2; ++} ++ ++int ++baz (const char *x, int y) ++{ ++ return 1; ++} ++ ++int xa, xb; ++ ++static void * ++inl (const char *x, const char *y) ++{ ++ T t = { &xa, &xb }; ++ int *f = (int *) __builtin_malloc (sizeof (int)); ++ const char *z; ++ int o = 0; ++ void *r = 0; ++ ++ for (z = y; *z; z++) ++ { ++ if (*z == 'r') ++ o |= 1; ++ if (*z == 'w') ++ o |= 2; ++ } ++ if (o == 1) ++ *f = baz (x, 0); ++ if (o == 2) ++ *f = baz (x, 1); ++ if (o == 3) ++ *f = baz (x, 2); ++ ++ if (o && *f > 0) ++ r = bar (f, "w", t); ++ return r; ++} ++ ++void * ++foo (const char *x, const char *y) ++{ ++ return inl (x, y); ++} |