This is the mail archive of the gcc-patches@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]

[PATCH,C,C++] Fix PR43601 massive object file size bloat. [was Re: dllexport and inline]


    Hi Nathan and list,

  Referring back an old thread here:

On 22/05/2009 15:59, Nathan Sidwell wrote:
> I've committed this patch from Mark, after porting it from our stable
> 4.3 branch.  the issue here is that functions marked dllexport must be
> emitted, even if they are (also) inline.
> 
> tested on i686-mingw32
> 
> nathan

  The change in question was this one:

> ------------------------------------------------------------------------
> r147799 | nathan | 2009-05-22 22:57:15 +0800 (Fri, 22 May 2009) | 16 lines
>
>    gcc/
>    * tree.c (handle_dll_attribute): Mark dllexport'd inlines as
>    non-external.
>
>    gcc/cp
>    * decl2.c (decl_needed_p): Consider dllexport'd functions needed.
>    * semantics.c (expand_or_defer_fn): Similarly.
>
>    gcc/testsuite/
 [  snipped, see http://gcc.gnu.org/viewcvs?view=revision&revision=147799 ]
> ------------------------------------------------------------------------

  The patch omitted to update the documentation of the dllexport attribute,
which still declares:

> Currently, the @code{dllexport} attribute is ignored for inlined
> functions, unless the @option{-fkeep-inline-functions} flag has been
> used.  The attribute is also ignored for undefined symbols.

  It is also responsible for the complaint in PR43601 about unmanageable
code-bloat building the wx library; all the extra comdat sections result in a
roughly 10x increase in the overall object code file size and link-time memory
usage:

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

  In your testcases, you explain the need for the change:

> /* Test that inline functions declared "dllexport" appear in object
>    files, even if they are not called.
> 
>    This behavior is required by the ARM C++ ABI:
> 
>      Exporting a function that can be inlined should force the
>      creation and export of an out-of-line copy of it.
> 
>    and should presumably also apply.
> 
>    Visual Studio 2005 also honors that rule.  */

... but the implementation is I think overkill.  ABI compliance only requires
the dllexported function to end up in the final linked DLL, it doesn't
necessarily require us to achieve that by the particular mechanism of emitting
the function in every intermediate object file, and indeed VS avoids this
problem by emitting their inlines once only, in the pch file (effectively
they're in stdafx.obj).

  The only practical solution I could think of is the attached patch that
places your previous change under user control.  This would allow a similar
method to be implemented under GCC, using -fno-keep-inline-dllexport during
most of the compilation and then compiling a single object file without it,
that #includes all the headers with inline dllexported functions, so that all
their definitions end up in a single object file.

gcc/c-family/ChangeLog:
2011-01-21  Dave Korn  <...

	* c.opt (-fkeep-inline-dllexport): New switch.

gcc/ChangeLog:
2011-01-21  Dave Korn  <...

	* tree.c (handle_dll_attribute): Handle it.
	* doc/extend.texi (@item dllexport): Mention it.
	* doc/invoke.texi (@item -fno-keep-inline-dllexport): Document it.

gcc/cp/ChangeLog:
2011-01-21  Dave Korn  <...

	* semantics.c (expand_or_defer_fn_1): Handle it.
	* decl2.c (decl_needed_p): Likewise.

gcc/testsuite/ChangeLog:
2011-01-21  Dave Korn  <...

	* gcc.dg/dll-9a.c: New test file.
	* gcc.dg/dll-11.c: Likewise.
	* gcc.dg/dll-12.c: Likewise.
	* gcc.dg/dll-12a.c: Likewise.
	* gcc.dg/dll-11a.c: Likewise.
	* gcc.dg/dll-9.c: Likewise.
	* gcc.dg/dll-10.c: Likewise.
	* gcc.dg/dll-10a.c: Likewise.
	* g++.dg/ext/dllexport4a.cc: Likewise.
	* g++.dg/ext/dllexport4.C: Likewise.
	* g++.dg/ext/dllexport5.C: Likewise.
	* g++.dg/ext/dllexport5a.cc: Likewise.

  Nathan, does the new wording of the documentation look right to you?  Also,
do you have any ideas for other ways to resolve this problem for our users?  I
wondered about the possibility of making the keep-inline behaviour only apply
to inlines that are explicitly tagged with dllexport, rather than that inherit
it from a tag on their enclosing class, but I supposed that wouldn't satisfy
the ARM ABI requirements?

  Tested in cross from i686-pc-cygwin to i686-pc-mingw32 with no regressions.
 I'm also running a native bootstrap and test cycle.  Assuming no problems
there, and no objections/better solutions from Nathan, is this OK?

    cheers,
      DaveK


Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 168624)
+++ gcc/c-family/c.opt	(working copy)
@@ -1,6 +1,6 @@
 ; Options for the C, ObjC, C++ and ObjC++ front ends.
-; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-; Free Software Foundation, Inc.
+; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+; 2011 Free Software Foundation, Inc.
 ;
 ; This file is part of GCC.
 ;
@@ -814,6 +814,10 @@ ffriend-injection
 C++ ObjC++ Var(flag_friend_injection)
 Inject friend functions into enclosing namespace
 
+fkeep-inline-dllexport
+C C++ ObjC ObjC++ Var(flag_keep_inline_dllexport) Init(1) Report Condition(TARGET_DLLIMPORT_DECL_ATTRIBUTES)
+Don't emit dllexported inline functions unless needed
+
 flabels-ok
 C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
 
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 168624)
+++ gcc/tree.c	(working copy)
@@ -1,7 +1,7 @@
 /* Language-independent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -5509,7 +5509,8 @@ handle_dll_attribute (tree * pnode, tree name, tre
         DECL_DLLIMPORT_P (node) = 1;
     }
   else if (TREE_CODE (node) == FUNCTION_DECL
-	   && DECL_DECLARED_INLINE_P (node))
+	   && DECL_DECLARED_INLINE_P (node)
+	   && flag_keep_inline_dllexport)
     /* An exported function, even if inline, must be emitted.  */
     DECL_EXTERNAL (node) = 0;
 
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 168624)
+++ gcc/doc/extend.texi	(working copy)
@@ -1,5 +1,5 @@
 @c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
-@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
 @c Free Software Foundation, Inc.
 
 @c This is part of the GCC manual.
@@ -2212,10 +2212,15 @@ On systems that support the @code{visibility} attr
 attribute also implies ``default'' visibility.  It is an error to
 explicitly specify any other visibility.
 
-Currently, the @code{dllexport} attribute is ignored for inlined
-functions, unless the @option{-fkeep-inline-functions} flag has been
-used.  The attribute is also ignored for undefined symbols.
+In previous versions of GCC, the @code{dllexport} attribute was ignored 
+for inlined functions, unless the @option{-fkeep-inline-functions} flag
+had been used.  The default behaviour now is to emit all dllexported
+inline functions; however, this can cause object file-size bloat, in
+which case the old behaviour can be restored by using
+@option{-fno-keep-inline-dllexport}.
 
+The attribute is also ignored for undefined symbols.
+
 When applied to C++ classes, the attribute marks defined non-inlined
 member functions and static data members as exports.  Static consts
 initialized in-class are not marked unless they are also defined
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 168624)
+++ gcc/doc/invoke.texi	(working copy)
@@ -1,5 +1,5 @@
 @c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-@c 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+@c 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
 @c Free Software Foundation, Inc.
 @c This is part of the GCC manual.
 @c For copying conditions, see the file gcc.texi.
@@ -6147,6 +6147,13 @@ abstract measurement of function's size.  In no wa
 of assembly instructions and as such its exact meaning might change from one
 release to an another.
 
+@item -fno-keep-inline-dllexport
+@opindex -fno-keep-inline-dllexport
+This is a more fine-grained version of @option{-fkeep-inline-functions},
+which applies only to functions that are declared using the @code{dllexport}
+attribute or declspec (@xref{Function Attributes,,Declaring Attributes of
+Functions}.)
+
 @item -fkeep-inline-functions
 @opindex fkeep-inline-functions
 In C, emit @code{static} functions that are declared @code{inline}
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 168624)
+++ gcc/cp/semantics.c	(working copy)
@@ -4,7 +4,7 @@
    and during the instantiation of template functions.
 
    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-		 2008, 2009, 2010 Free Software Foundation, Inc.
+		 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.
 
@@ -3446,7 +3446,8 @@ expand_or_defer_fn_1 (tree fn)
       if ((flag_keep_inline_functions
 	   && DECL_DECLARED_INLINE_P (fn)
 	   && !DECL_REALLY_EXTERN (fn))
-	  || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))
+	  || (flag_keep_inline_dllexport
+	      && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn))))
 	mark_needed (fn);
     }
 
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 168624)
+++ gcc/cp/decl2.c	(working copy)
@@ -1,7 +1,7 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -1780,7 +1780,8 @@ decl_needed_p (tree decl)
       return true;
   /* Functions marked "dllexport" must be emitted so that they are
      visible to other DLLs.  */
-  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
+  if (flag_keep_inline_dllexport
+      && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
     return true;
   /* Otherwise, DECL does not need to be emitted -- yet.  A subsequent
      reference to DECL might cause it to be emitted later.  */
Index: gcc/testsuite/gcc.dg/dll-9a.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-9a.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-9a.c	(revision 0)
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+  i1();
+  i3();
+  i4();
+  i5();
+
+  e1();
+  e3();
+  e4();
+  e5();
+}
Index: gcc/testsuite/gcc.dg/dll-11.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-11.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-11.c	(revision 0)
@@ -0,0 +1,52 @@
+/* { dg-do link } */
+/* { dg-require-dll "" } */
+/* { dg-additional-sources "dll-11a.c" } */
+/* { dg-options "-w -O2 -std=gnu89 -fkeep-inline-dllexport" } */
+
+/* Test that inline functions declared "dllexport" appear in object files,
+   even if they are not called, when -fkeep-inline-dllexport is supplied.
+
+   This behavior is required by the ARM C++ ABI:
+
+     Exporting a function that can be inlined should force the
+     creation and export of an out-of-line copy of it.
+
+   and should presumably also apply.
+
+   Visual Studio 2005 also honors that rule.  */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition.  */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+   -- does not cause errors.  */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
Index: gcc/testsuite/gcc.dg/dll-12.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-12.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-12.c	(revision 0)
@@ -0,0 +1,52 @@
+/* { dg-do link } */
+/* { dg-require-dll "" } */
+/* { dg-additional-sources "dll-12a.c" } */
+/* { dg-options "-w -O2 -std=gnu99 -fkeep-inline-dllexport" } */
+
+/* Test that inline functions declared "dllexport" appear in object files,
+   even if they are not called, when -fkeep-inline-dllexport is supplied.
+
+   This behavior is required by the ARM C++ ABI:
+
+     Exporting a function that can be inlined should force the
+     creation and export of an out-of-line copy of it.
+
+   and should presumably also apply.
+
+   Visual Studio 2005 also honors that rule.  */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition.  */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+   -- does not cause errors.  */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
Index: gcc/testsuite/gcc.dg/dll-12a.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-12a.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-12a.c	(revision 0)
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+  i1();
+  i3();
+  i4();
+  i5();
+
+  e1();
+  e3();
+  e4();
+  e5();
+}
Index: gcc/testsuite/gcc.dg/dll-11a.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-11a.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-11a.c	(revision 0)
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+  i1();
+  i3();
+  i4();
+  i5();
+
+  e1();
+  e3();
+  e4();
+  e5();
+}
Index: gcc/testsuite/gcc.dg/dll-9.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-9.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-9.c	(revision 0)
@@ -0,0 +1,54 @@
+/* { dg-do link } */
+/* { dg-require-dll "" } */
+/* { dg-additional-sources "dll-9a.c" } */
+/* { dg-options "-w -O2 -std=gnu89 -fno-keep-inline-dllexport" } */
+/* { dg-prune-output .*undefined.* } */
+/* { dg-xfail-if "link failure expected" { *-*-* } } */
+
+/* Test that inline functions declared "dllexport" appear in object files,
+   even if they are not called - except when -fno-keep-inline-dllexport.
+
+   This behavior is required by the ARM C++ ABI:
+
+     Exporting a function that can be inlined should force the
+     creation and export of an out-of-line copy of it.
+
+   and should presumably also apply.
+
+   Visual Studio 2005 also honors that rule.  */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition.  */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+   -- does not cause errors.  */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
Index: gcc/testsuite/gcc.dg/dll-10.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-10.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-10.c	(revision 0)
@@ -0,0 +1,54 @@
+/* { dg-do link } */
+/* { dg-require-dll "" } */
+/* { dg-additional-sources "dll-10a.c" } */
+/* { dg-options "-w -O2 -std=gnu99 -fno-keep-inline-dllexport" } */
+/* { dg-prune-output .*undefined.* } */
+/* { dg-xfail-if "link failure expected" { *-*-* } } */
+
+/* Test that inline functions declared "dllexport" appear in object files,
+   even if they are not called - except when -fno-keep-inline-dllexport.
+
+   This behavior is required by the ARM C++ ABI:
+
+     Exporting a function that can be inlined should force the
+     creation and export of an out-of-line copy of it.
+
+   and should presumably also apply.
+
+   Visual Studio 2005 also honors that rule.  */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition.  */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+   -- does not cause errors.  */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
Index: gcc/testsuite/gcc.dg/dll-10a.c
===================================================================
--- gcc/testsuite/gcc.dg/dll-10a.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dll-10a.c	(revision 0)
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+  i1();
+  i3();
+  i4();
+  i5();
+
+  e1();
+  e3();
+  e4();
+  e5();
+}
Index: gcc/testsuite/g++.dg/ext/dllexport4a.cc
===================================================================
--- gcc/testsuite/g++.dg/ext/dllexport4a.cc	(revision 0)
+++ gcc/testsuite/g++.dg/ext/dllexport4a.cc	(revision 0)
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+  i1();
+  i3();
+  i4();
+  i5();
+
+  e1();
+  e3();
+  e4();
+  e5();
+}
Index: gcc/testsuite/g++.dg/ext/dllexport4.C
===================================================================
--- gcc/testsuite/g++.dg/ext/dllexport4.C	(revision 0)
+++ gcc/testsuite/g++.dg/ext/dllexport4.C	(revision 0)
@@ -0,0 +1,54 @@
+// { dg-do link }
+// { dg-require-dll "" }
+// { dg-additional-sources "dllexport4a.cc" }
+// { dg-options "-O2 -fno-keep-inline-dllexport" }
+// { dg-prune-output .*undefined.* }
+// { dg-xfail-if "link failure expected" { *-*-* } }
+
+/* Test that inline functions declared "dllexport" appear in object files,
+   even if they are not called - except when -fno-keep-inline-dllexport.
+
+   This behavior is required by the ARM C++ ABI:
+
+     Exporting a function that can be inlined should force the
+     creation and export of an out-of-line copy of it.
+
+   and should presumably also apply.
+
+   Visual Studio 2005 also honors that rule.  */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition.  */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+   -- does not cause errors.  */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
Index: gcc/testsuite/g++.dg/ext/dllexport5.C
===================================================================
--- gcc/testsuite/g++.dg/ext/dllexport5.C	(revision 0)
+++ gcc/testsuite/g++.dg/ext/dllexport5.C	(revision 0)
@@ -0,0 +1,52 @@
+// { dg-do link }
+// { dg-require-dll "" }
+// { dg-additional-sources "dllexport5a.cc" }
+// { dg-options "-O2 -fkeep-inline-dllexport" }
+
+/* Test that inline functions declared "dllexport" appear in object files,
+   even if they are not called, when -fkeep-inline-dllexport is supplied.
+
+   This behavior is required by the ARM C++ ABI:
+
+     Exporting a function that can be inlined should force the
+     creation and export of an out-of-line copy of it.
+
+   and should presumably also apply.
+
+   Visual Studio 2005 also honors that rule.  */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition.  */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+   -- does not cause errors.  */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();

Property changes on: gcc/testsuite/g++.dg/ext/dllexport5.C
___________________________________________________________________
Added: svn:executable
   + *

Index: gcc/testsuite/g++.dg/ext/dllexport5a.cc
===================================================================
--- gcc/testsuite/g++.dg/ext/dllexport5a.cc	(revision 0)
+++ gcc/testsuite/g++.dg/ext/dllexport5a.cc	(revision 0)
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+  i1();
+  i3();
+  i4();
+  i5();
+
+  e1();
+  e3();
+  e4();
+  e5();
+}

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