This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/33763] [4.4/4.5/4.6/4.7 Regression] Bogus inlining failed in call to `xxx': redefined extern inline functions are not considered for inlining


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33763

--- Comment #31 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-01-13 09:26:45 UTC ---
Ok, so the following patch makes

extern __inline __attribute__ ((__always_inline__))
void open ()
{
}
void bar ()
{
  open ();
}
void open ()
{
  open ();
}

"work" as in the extern inline variant is used for the callin bar()
and the call in open () is recursive and all following calls would
refer to it.  That means, we end up with two cgraph nodes (but do
not magically use one for inlining and one for the offline copy - that
would need to be fixed in the C frontend by _not_ changing name-lookup
to lookup the 2nd version, but I'm not sure that is desired).

At least you can say the behavior makes sense and it avoids the ICEs, too.

I'm going to test this.

Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c        (revision 183121)
+++ gcc/c-decl.c        (working copy)
@@ -2513,6 +2513,24 @@ duplicate_decls (tree newdecl, tree oldd
       return false;
     }

+  /* If we have a redeclared extern inline function simply drop olddecl
+     on the floor instead of merging it with newdecl.  */
+  if (TREE_CODE (newdecl) == FUNCTION_DECL
+      && DECL_INITIAL (newdecl)
+      && DECL_INITIAL (olddecl)
+      && !(!(DECL_DECLARED_INLINE_P (olddecl)
+            && DECL_EXTERNAL (olddecl))
+          || (DECL_DECLARED_INLINE_P (newdecl)
+              && DECL_EXTERNAL (newdecl))
+          || (!flag_gnu89_inline
+              && (!DECL_DECLARED_INLINE_P (olddecl)
+                  || !lookup_attribute ("gnu_inline",
+                                        DECL_ATTRIBUTES (olddecl)))
+              && (!DECL_DECLARED_INLINE_P (newdecl)
+                  || !lookup_attribute ("gnu_inline",
+                                        DECL_ATTRIBUTES (newdecl))))))
+    return false;
+
   merge_decls (newdecl, olddecl, newtype, oldtype);
   return true;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]