From 47ea1edfbce523efbccac2377388798ec7800460 Mon Sep 17 00:00:00 2001 From: Dave Korn Date: Wed, 26 Jan 2011 01:41:23 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++ gcc/c-family/ChangeLog | 4 ++ gcc/c-family/c.opt | 8 +++- gcc/cp/ChangeLog | 5 +++ gcc/cp/decl2.c | 7 ++-- gcc/cp/semantics.c | 3 +- gcc/doc/extend.texi | 13 ++++-- gcc/doc/invoke.texi | 7 ++++ gcc/testsuite/ChangeLog | 15 +++++++ gcc/testsuite/g++.dg/ext/dllexport4.C | 54 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/ext/dllexport4a.cc | 21 ++++++++++ gcc/testsuite/g++.dg/ext/dllexport5.C | 52 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/ext/dllexport5a.cc | 21 ++++++++++ gcc/testsuite/gcc.dg/dll-10.c | 54 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/dll-10a.c | 21 ++++++++++ gcc/testsuite/gcc.dg/dll-11.c | 52 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/dll-11a.c | 21 ++++++++++ gcc/testsuite/gcc.dg/dll-12.c | 52 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/dll-12a.c | 21 ++++++++++ gcc/testsuite/gcc.dg/dll-9.c | 54 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/dll-9a.c | 21 ++++++++++ gcc/tree.c | 7 ++-- 22 files changed, 506 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/dllexport4.C create mode 100644 gcc/testsuite/g++.dg/ext/dllexport4a.cc create mode 100755 gcc/testsuite/g++.dg/ext/dllexport5.C create mode 100644 gcc/testsuite/g++.dg/ext/dllexport5a.cc create mode 100644 gcc/testsuite/gcc.dg/dll-10.c create mode 100644 gcc/testsuite/gcc.dg/dll-10a.c create mode 100644 gcc/testsuite/gcc.dg/dll-11.c create mode 100644 gcc/testsuite/gcc.dg/dll-11a.c create mode 100644 gcc/testsuite/gcc.dg/dll-12.c create mode 100644 gcc/testsuite/gcc.dg/dll-12a.c create mode 100644 gcc/testsuite/gcc.dg/dll-9.c create mode 100644 gcc/testsuite/gcc.dg/dll-9a.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 31838c69e73..b5a4141202d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-01-26 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. + 2011-01-25 Ian Lance Taylor PR tree-optimization/26854 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index f55bc2d49cf..f9efc213fde 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2011-01-26 Dave Korn + + * c.opt (-fkeep-inline-dllexport): New switch. + 2011-01-12 Richard Guenther PR middle-end/32511 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 868247168fe..b0d9e5bed89 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 81e44573032..d6113a2146a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2011-01-26 Dave Korn + + * semantics.c (expand_or_defer_fn_1): Handle it. + * decl2.c (decl_needed_p): Likewise. + 2011-01-21 Jason Merrill PR c++/47041 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 288552880a7..a4b7dfa9bee 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 dc29c7a9a71..ea8a7ae8669 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 bc60bfe3f96..5a2b2684d90 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 37a6e4e98f6..d2ff7b609a9 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 9db1dc7bafc..74409eee9e8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2011-01-26 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. + 2011-01-25 Sebastian Pop 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 00000000000..81c57c3fbca --- /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 00000000000..80caf321742 --- /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 00000000000..8b27807315e --- /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 00000000000..80caf321742 --- /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 00000000000..2f0c6ce31a5 --- /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 00000000000..80caf321742 --- /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 00000000000..5fa2e6f19f5 --- /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 00000000000..80caf321742 --- /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 00000000000..4f8829964a7 --- /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 00000000000..80caf321742 --- /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 00000000000..ae641d29d6c --- /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 00000000000..80caf321742 --- /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 be2cf98948e..f1f80053775 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;