summaryrefslogtreecommitdiff
path: root/packages/gcc/gcc-4.3.2/fedora/gcc43-pr33763.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/gcc/gcc-4.3.2/fedora/gcc43-pr33763.patch')
-rw-r--r--packages/gcc/gcc-4.3.2/fedora/gcc43-pr33763.patch153
1 files changed, 153 insertions, 0 deletions
diff --git a/packages/gcc/gcc-4.3.2/fedora/gcc43-pr33763.patch b/packages/gcc/gcc-4.3.2/fedora/gcc43-pr33763.patch
new file mode 100644
index 0000000000..9e9c90d271
--- /dev/null
+++ b/packages/gcc/gcc-4.3.2/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);
++}