This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Old-C++ ABI inline method heuristic problem
- To: bernds at redhat dot com
- Subject: [PATCH] Old-C++ ABI inline method heuristic problem
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Wed, 9 May 2001 16:23:34 +0200
- Cc: gcc-patches at gcc dot gnu dot org
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
Hi!
This has been reported against gcc-2.96-RH, but similar problem exists in
gcc-2.95.x.
The issue is that g++'s heuristic in old ABI which finds whether to emit
weak body of inline method which has not been successfully inlined for some
reason (in avifile case it is because of of inline throttling, in the
testcase below because of static variable in the method) does not work
always.
Particularly, if in a compilation unit other than the one which defines
first non-inline non-abstract virtual method some method is defined as
inline outside of the class definition and is used only in that compilation
unit, g++ does not emit the inline body of the function although it is used
(but it is not emitted in the class-exporting unit either, since it is not
defined there at all).
So, this patch takes the worse from both worlds, emitting inline method
bodies both in the objects which have not successfully inlined it and for
ABI compatibility in the exporting object as well.
2001-05-07 Jakub Jelinek <jakub@redhat.com>
* decl2.c (import_export_decl): Emit referenced inline methods even
in the unit which just imports the class.
* g++.old-deja/g++.other/inline21.C: New test.
--- gcc/cp/decl2.c.jj Thu May 3 16:12:37 2001
+++ gcc/cp/decl2.c Sat May 5 16:29:55 2001
@@ -2777,16 +2777,28 @@ import_export_decl (decl)
? (! DECL_THIS_INLINE (decl))
: (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))))
{
- DECL_NOT_REALLY_EXTERN (decl)
- = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
- || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines
- && !DECL_VINDEX (decl)));
-
- /* Always make artificials weak. */
- if (DECL_ARTIFICIAL (decl) && flag_weak)
+ if (! flag_new_abi && DECL_THIS_INLINE (decl)
+ && ! DECL_ARTIFICIAL (decl)
+ && ! DECL_VINDEX (decl) && CLASSTYPE_INTERFACE_ONLY (ctype))
+ /* The heuristic does not work well, since even if we are
+ interface only unit of a certain class, some methods can
+ be declared inline only in this unit (provided they are
+ used only there). In this case, emit linkonce code of the
+ inline function as well. */
comdat_linkage (decl);
else
- maybe_make_one_only (decl);
+ {
+ DECL_NOT_REALLY_EXTERN (decl)
+ = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
+ || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines
+ && !DECL_VINDEX (decl)));
+
+ /* Always make artificials weak. */
+ if (DECL_ARTIFICIAL (decl) && flag_weak)
+ comdat_linkage (decl);
+ else
+ maybe_make_one_only (decl);
+ }
}
else
comdat_linkage (decl);
--- gcc/testsuite/g++.old-deja/g++.other/inline21.C.jj Mon May 7 17:03:08 2001
+++ gcc/testsuite/g++.old-deja/g++.other/inline21.C Fri May 4 18:27:04 2001
@@ -0,0 +1,28 @@
+// Build don't run:
+
+struct B
+{
+ virtual ~B() {}
+};
+
+struct A : public B
+{
+ ~A();
+ void foo(void);
+ void bar(void);
+};
+
+inline void A::foo(void)
+{
+ static int i;
+ i++;
+}
+
+void A::bar()
+{
+ foo();
+}
+
+int main()
+{
+}
Jakub