aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDave Korn <dave.korn.cygwin@gmail.com>2011-01-26 01:41:23 +0000
committerDave Korn <davek@gcc.gnu.org>2011-01-26 01:41:23 +0000
commit47ea1edfbce523efbccac2377388798ec7800460 (patch)
tree7791b2c5afa7301952887cfb93c353a67dacb1ce /gcc
parent744f0946bcbf7be92a725383d41c31673849efa9 (diff)
downloadgcc-47ea1edfbce523efbccac2377388798ec7800460.zip
gcc-47ea1edfbce523efbccac2377388798ec7800460.tar.gz
gcc-47ea1edfbce523efbccac2377388798ec7800460.tar.bz2
c.opt (-fkeep-inline-dllexport): New switch.
gcc/c-family/ChangeLog: * c.opt (-fkeep-inline-dllexport): New switch. gcc/ChangeLog: * 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: * semantics.c (expand_or_defer_fn_1): Handle it. * decl2.c (decl_needed_p): Likewise. gcc/testsuite/ChangeLog: * 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. From-SVN: r169268
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-family/ChangeLog4
-rw-r--r--gcc/c-family/c.opt8
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl2.c7
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/doc/extend.texi13
-rw-r--r--gcc/doc/invoke.texi7
-rw-r--r--gcc/testsuite/ChangeLog15
-rw-r--r--gcc/testsuite/g++.dg/ext/dllexport4.C54
-rw-r--r--gcc/testsuite/g++.dg/ext/dllexport4a.cc21
-rwxr-xr-xgcc/testsuite/g++.dg/ext/dllexport5.C52
-rw-r--r--gcc/testsuite/g++.dg/ext/dllexport5a.cc21
-rw-r--r--gcc/testsuite/gcc.dg/dll-10.c54
-rw-r--r--gcc/testsuite/gcc.dg/dll-10a.c21
-rw-r--r--gcc/testsuite/gcc.dg/dll-11.c52
-rw-r--r--gcc/testsuite/gcc.dg/dll-11a.c21
-rw-r--r--gcc/testsuite/gcc.dg/dll-12.c52
-rw-r--r--gcc/testsuite/gcc.dg/dll-12a.c21
-rw-r--r--gcc/testsuite/gcc.dg/dll-9.c54
-rw-r--r--gcc/testsuite/gcc.dg/dll-9a.c21
-rw-r--r--gcc/tree.c7
22 files changed, 506 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 31838c6..b5a4141 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-01-26 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * tree.c (handle_dll_attribute): Handle it.
+ * doc/extend.texi (@item dllexport): Mention it.
+ * doc/invoke.texi (@item -fno-keep-inline-dllexport): Document it.
+
2011-01-25 Ian Lance Taylor <iant@google.com>
PR tree-optimization/26854
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index f55bc2d..f9efc21 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,7 @@
+2011-01-26 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * c.opt (-fkeep-inline-dllexport): New switch.
+
2011-01-12 Richard Guenther <rguenther@suse.de>
PR middle-end/32511
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 8682471..b0d9e5b 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -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)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 81e4457..d6113a2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2011-01-26 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * semantics.c (expand_or_defer_fn_1): Handle it.
+ * decl2.c (decl_needed_p): Likewise.
+
2011-01-21 Jason Merrill <jason@redhat.com>
PR c++/47041
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2885528..a4b7dfa 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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.
@@ -1781,7 +1781,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. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index dc29c7a..ea8a7ae 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3482,7 +3482,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);
}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index bc60bfe..5a2b268 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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.
@@ -2213,9 +2213,14 @@ On systems that support the @code{visibility} attribute, this
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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 37a6e4e..d2ff7b6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6149,6 +6149,13 @@ abstract measurement of function's size. In no way does it represent a count
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}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9db1dc7..74409ee 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,18 @@
+2011-01-26 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * 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.
+
2011-01-25 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/46970
diff --git a/gcc/testsuite/g++.dg/ext/dllexport4.C b/gcc/testsuite/g++.dg/ext/dllexport4.C
new file mode 100644
index 0000000..81c57c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/dllexport4.C
@@ -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();
diff --git a/gcc/testsuite/g++.dg/ext/dllexport4a.cc b/gcc/testsuite/g++.dg/ext/dllexport4a.cc
new file mode 100644
index 0000000..80caf32
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/dllexport4a.cc
@@ -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();
+}
diff --git a/gcc/testsuite/g++.dg/ext/dllexport5.C b/gcc/testsuite/g++.dg/ext/dllexport5.C
new file mode 100755
index 0000000..8b27807
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/dllexport5.C
@@ -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();
diff --git a/gcc/testsuite/g++.dg/ext/dllexport5a.cc b/gcc/testsuite/g++.dg/ext/dllexport5a.cc
new file mode 100644
index 0000000..80caf32
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/dllexport5a.cc
@@ -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();
+}
diff --git a/gcc/testsuite/gcc.dg/dll-10.c b/gcc/testsuite/gcc.dg/dll-10.c
new file mode 100644
index 0000000..2f0c6ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-10.c
@@ -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();
diff --git a/gcc/testsuite/gcc.dg/dll-10a.c b/gcc/testsuite/gcc.dg/dll-10a.c
new file mode 100644
index 0000000..80caf32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-10a.c
@@ -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();
+}
diff --git a/gcc/testsuite/gcc.dg/dll-11.c b/gcc/testsuite/gcc.dg/dll-11.c
new file mode 100644
index 0000000..5fa2e6f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-11.c
@@ -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();
diff --git a/gcc/testsuite/gcc.dg/dll-11a.c b/gcc/testsuite/gcc.dg/dll-11a.c
new file mode 100644
index 0000000..80caf32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-11a.c
@@ -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();
+}
diff --git a/gcc/testsuite/gcc.dg/dll-12.c b/gcc/testsuite/gcc.dg/dll-12.c
new file mode 100644
index 0000000..4f88299
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-12.c
@@ -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();
diff --git a/gcc/testsuite/gcc.dg/dll-12a.c b/gcc/testsuite/gcc.dg/dll-12a.c
new file mode 100644
index 0000000..80caf32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-12a.c
@@ -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();
+}
diff --git a/gcc/testsuite/gcc.dg/dll-9.c b/gcc/testsuite/gcc.dg/dll-9.c
new file mode 100644
index 0000000..ae641d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-9.c
@@ -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();
diff --git a/gcc/testsuite/gcc.dg/dll-9a.c b/gcc/testsuite/gcc.dg/dll-9a.c
new file mode 100644
index 0000000..80caf32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-9a.c
@@ -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();
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index be2cf98..f1f8005 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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, tree args, int flags,
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;