gcc/gcc47-pr33763.patch
Jakub Jelinek 5c29a25740 4.7.0-0.2
2012-01-03 15:17:22 +01:00

154 lines
3.3 KiB
Diff

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
@@ -3817,6 +3817,12 @@ expand_call_inline (basic_block bb, gimp
goto egress;
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
+ /* For extern inline functions that get redefined we always
+ silently ignored always_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. */
&& cgraph_global_info_ready
/* PR 20090218-1_0.c. Body can be provided by another module. */
--- 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);
+}