This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch/RFA] Fix mingw/cygwin dllimport PR's 7910 (et al) and 11021
- From: Christopher Faylor <cgf at redhat dot com>
- To: Danny Smith <dannysmith at users dot sourceforge dot net>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Mumit Khan <khan at NanoTech dot Wisc dot EDU>
- Date: Fri, 30 May 2003 09:12:33 -0400
- Subject: Re: [Patch/RFA] Fix mingw/cygwin dllimport PR's 7910 (et al) and 11021
- References: <000a01c3264a$3d2312d0$0690a7cb@DANNY>
I'll apply this patch to my local sandbox this weekend and do some
tests.
Is there anything in this change which requires documentation tweaks?
cgf
On Fri, May 30, 2003 at 02:24:36AM +0100, Danny Smith wrote:
>
>Hi,
>The attached patch fixes dllimport PR's c++7910 (and duplicates) and
>c++/11021. and expands the testsuite for handling of dllimport
>attributes.
>
>PR 7910 and related problems all arise when we try to apply a the
>dllimport attribute to a definition. The patch trys to check for this
>ambiguity as early as possible, throws errors when the syntax is
>obviously inconsistent and discards the attribute (with warning) if a
>redeclaration or definition is seen later.
>
>It also throws error if the symbol is defined with only local scope,
> eg '__attribute__((dllimport)) static int foo'
>
>Dllimport is also inconsistent with virtual methods in C++ classes.
>The attribute says that we cannot treat the symbols address as a
>constant. Thus we simply disregard the attribute for virtual methods,
>avoiding the PR 11021 segfault. The cost for disregarding the
>attribute for functions is small:an additional thunk in the dll.
>
>Multiple inheritance and dll's requires an additional dllexport
>modification to get some virtual amd non-virtual thunks exported
>from the dll. Once I develop the testcase[s] for that I'll submit.
>
>The patch is based on earlier work by Mumit Khan, by I have moved
>things around quite a bit and don't try to follow MSVC 'rules' as
>strictly. particularly when they seemed to encourage sloppy code.
>I would like to put Mumit's name on the ChangeLog as well,
>but will await his review.
>
>I would really appreciate comments on this because. although I've
>happy with my empirical tests on real dll's,I'm in a bit over my
>head.
>
>Booted and regtested i386-pc-mingw
>gcc version 3.4 20030528 (experimental)
>
>Danny
>
>ChangeLog
>
>2002-05-30 Danny Smith <dannysmith@users.sourceforge.net>
>
> PR c++/7910
> * config/i386/winnt.c (ix86_handle_dll_attribute): Don't add
> dllimport attribute if function is defined at declaration, but
> throw error instead. Likewise for dllimport'd variable
> definitions. Throw error if dllimport or dllexport symbol is
> not global.
> (i386_pe_dllimport_p): Ignore dllimport attribute of functions
> if defined after declaration or if inlined. Handle static data
> members of C++ classes. Emit warnings.
> (i386_pe_mark_dllexport): Warn about inconsistent dll
>attributes.
> (i386_pe_mark_dllimport): Remove unnecessary checks; already
>done.
> (i386_pe_encode_section_info): Warn if the dllimport attribute
> and symbol prefix have been instantiated and then overridden.
> * testsuite/g++.dg/ext/dllimport1.C: Add mingw32 as target. Add
> test for warnings.
> * testsuite/g++.dg/ext/dllimport2.C: Add test for warnings.
> * testsuite/g++.dg/ext/dllimport3.C: Likeswise..
> * testsuite/g++.dg/ext/dllimport4.C: New file. Test that errors
> are emitted if dllimport symbols defined at declaration.
> * testsuite/g++.dg/ext/dllimport5.C: New file. Test that errors
> are emitted if dll[im/ex]port attribute on local symbol.
> * testsuite/g++.dg/ext/dllimport6.C: New file. Test that static
> members of C++ classes are marked.
> * testsuite/g++.dg/ext/dllimport7.C: New file. Test that errors
> are emitted for definition of static data in classes marked as
> dllimport.
> * testsuite/g++.dg/ext/dllimport8.C: New file. Test dllimport
> handling and warnings for static functions in C++ classes.
> * testsuite/g++.dg/ext/dllimport9.C: New file. More tests of
> inline function and dllimport.
>
> * testsuite/g++.dg/ext/dllexport1.C: New file. Test that inline
> functions are exported using -fkeep-inlines.
>
> PR c++/11021
> * config/i386/winnt.c (i386_pe_dllimport_p): Ignore dllimport
> attributes for virtual methods.
> * testsuite/g++.dg/ext/dllimport10.C: New file.
>
> * config/i386/winnt.c (i386_pe_output_labelref): Fix indents.
>
>
>Index: config/i386/winnt.c
>===================================================================
>RCS file: /cvs/gcc/gcc/gcc/config/i386/winnt.c,v
>retrieving revision 1.47
>diff -c -3 -p -r1.47 winnt.c
>*** config/i386/winnt.c 21 May 2003 00:33:26 -0000 1.47
>--- config/i386/winnt.c 29 May 2003 22:16:34 -0000
>*************** void i386_pe_mark_dllimport PARAMS ((tre
>*** 66,81 ****
> /* Handle a "dllimport" or "dllexport" attribute;
> arguments as in struct attribute_spec.handler. */
> tree
>! ix86_handle_dll_attribute (node, name, args, flags, no_add_attrs)
>! tree *node;
> tree name;
> tree args;
> int flags;
> bool *no_add_attrs;
> {
> /* These attributes may apply to structure and union types being created,
> but otherwise should pass to the declaration involved. */
>! if (!DECL_P (*node))
> {
> if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
> | (int) ATTR_FLAG_ARRAY_NEXT))
>--- 66,83 ----
> /* Handle a "dllimport" or "dllexport" attribute;
> arguments as in struct attribute_spec.handler. */
> tree
>! ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
>! tree * pnode;
> tree name;
> tree args;
> int flags;
> bool *no_add_attrs;
> {
>+ tree node = *pnode;
>+
> /* These attributes may apply to structure and union types being created,
> but otherwise should pass to the declaration involved. */
>! if (!DECL_P (node))
> {
> if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
> | (int) ATTR_FLAG_ARRAY_NEXT))
>*************** ix86_handle_dll_attribute (node, name, a
>*** 83,102 ****
> *no_add_attrs = true;
> return tree_cons (name, args, NULL_TREE);
> }
>! if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
> {
> warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
> *no_add_attrs = true;
> }
> }
>
>! /* `extern' needn't be specified with dllimport.
>! Specify `extern' now and hope for the best. Sigh. */
>! else if (TREE_CODE (*node) == VAR_DECL
>! && is_attribute_p ("dllimport", name))
> {
>! DECL_EXTERNAL (*node) = 1;
>! TREE_PUBLIC (*node) = 1;
> }
>
> return NULL_TREE;
>--- 85,141 ----
> *no_add_attrs = true;
> return tree_cons (name, args, NULL_TREE);
> }
>! if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
> {
> warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
> *no_add_attrs = true;
>+ return NULL_TREE;
>+ }
>+ }
>+
>+ /* Throw errpor on dllimport ambiguities seen now before they cause any damage. */
>+ else if (is_attribute_p ("dllimport", name))
>+ {
>+ /* Like MS, treat definition of dllimported variables and
>+ non-inlined functions on declaration as syntax errors.
>+ We allow the attribute for function definitions if declared
>+ inline, but just ignore it in i386_pe_dllimport_p. */
>+ if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node)
>+ && !DECL_INLINE (node))
>+ {
>+ error ("%Hfunction `%D' definition is marked dllimport.",
>+ &DECL_SOURCE_LOCATION (node), node);
>+ *no_add_attrs = true;
>+ }
>+
>+ else if (TREE_CODE (node) == VAR_DECL)
>+ {
>+ if (DECL_INITIAL (node))
>+ {
>+ error ("%Hvariable `%D' definition is marked dllimport.",
>+ &DECL_SOURCE_LOCATION (node), node);
>+ *no_add_attrs = true;
>+ }
>+
>+ /* `extern' needn't be specified with dllimport. Specify
>+ `extern' now and hope for the best. Be careful that we don't
>+ set TREE_PUBLIC for variables declared static (class static
>+ data is already public) so we can catch syntax ambiguity
>+ below. */
>+ if (!TREE_STATIC (node))
>+ TREE_PUBLIC (node) = 1;
>+ DECL_EXTERNAL (node) = 1;
> }
> }
>
>! /* Throw error if symbol is not accessible at global scope. */
>! if (!TREE_PUBLIC (node)
>! && (TREE_CODE (node) == VAR_DECL
>! || TREE_CODE (node) == FUNCTION_DECL))
> {
>! error ("%Hexternal linkage required for symbol '%D' because of '%s' attribute.",
>! &DECL_SOURCE_LOCATION (node), node,IDENTIFIER_POINTER (name));
>! *no_add_attrs = true;
> }
>
> return NULL_TREE;
>*************** i386_pe_dllimport_p (decl)
>*** 181,187 ****
> tree decl;
> {
> tree imp;
>!
> if (TREE_CODE (decl) == FUNCTION_DECL
> && TARGET_NOP_FUN_DLLIMPORT)
> return 0;
>--- 220,227 ----
> tree decl;
> {
> tree imp;
>! int context_imp = 0;
>!
> if (TREE_CODE (decl) == FUNCTION_DECL
> && TARGET_NOP_FUN_DLLIMPORT)
> return 0;
>*************** i386_pe_dllimport_p (decl)
>*** 189,205 ****
> if (TREE_CODE (decl) != VAR_DECL
> && TREE_CODE (decl) != FUNCTION_DECL)
> return 0;
> imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
>- if (imp)
>- return 1;
>
> /* Class members get the dllimport status of their class. */
>! if (associated_type (decl))
> {
> imp = lookup_attribute ("dllimport",
> TYPE_ATTRIBUTES (associated_type (decl)));
> if (imp)
>! return 1;
> }
>
> return 0;
>--- 229,312 ----
> if (TREE_CODE (decl) != VAR_DECL
> && TREE_CODE (decl) != FUNCTION_DECL)
> return 0;
>+
> imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
>
> /* Class members get the dllimport status of their class. */
>! if (!imp && associated_type (decl))
> {
> imp = lookup_attribute ("dllimport",
> TYPE_ATTRIBUTES (associated_type (decl)));
> if (imp)
>! context_imp = 1;
>! }
>!
>! if (imp)
>! {
>! /* Don't mark defined functions as dllimport. If the definition
>! itself was marked with dllimport, then an error is raised. This
>! handles the case when the definition overrides an earlier
>! declaration. */
>! if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)
>! && !DECL_INLINE (decl))
>! {
>! warning ("%Hdefinition of '%D' previously marked as dllimport: attribute ignored",
>! &DECL_SOURCE_LOCATION (decl), decl);
>! return 0;
>! }
>!
>! /* We ignore the dllimport attribute for inlined functions
>! This differs from MSVC behaviour which treats it like GNUC
>! 'extern inline' extension. */
>! else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
>! {
>! if (extra_warnings)
>! warning ("%Hinline function '%D' marked as dllimport: attribute ignored.",
>! &DECL_SOURCE_LOCATION (decl), decl);
>! return 0;
>! }
>!
>! /* Turn off importing C++ virtual methods to able to create
>! vtables using thunks. */
>! else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
>! && DECL_VIRTUAL_P (decl))
>! {
>! return 0;
>! }
>!
>! /* Class static data members */
>! else if (TREE_CODE (decl) == VAR_DECL
>! && TREE_STATIC (decl) && TREE_PUBLIC (decl)
>! && context_imp)
>! {
>! if (DECL_VIRTUAL_P (decl))
>! {
>! /* Mark vtable symbol with _imp_, only if we
>! know it is defined externally. */
>! if (!DECL_EXTERNAL (decl))
>! return 0;
>! }
>!
>! /* Don't allow definition of static data members. */
>! else if (!DECL_EXTERNAL (decl))
>! {
>! error ("%Hdefinition of static data member '%D' of dllimport'd class.",
>! &DECL_SOURCE_LOCATION (decl), decl);
>! return 0;
>! }
>!
>! /* Should in-class initialization of static consts raise an
>! error too, or just ignore the attribute, as here? */
>! else if (DECL_INITIAL (decl)
>! && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
>! {
>! warning ("%Hin-class initialization of '%D': dllimport attribute ignored.",
>! &DECL_SOURCE_LOCATION (decl), decl);
>! return 0;
>! }
>! }
>!
>! return 1;
> }
>
> return 0;
>*************** i386_pe_mark_dllexport (decl)
>*** 246,253 ****
> else
> abort ();
> if (i386_pe_dllimport_name_p (oldname))
>! /* Remove DLL_IMPORT_PREFIX. */
>! oldname += strlen (DLL_IMPORT_PREFIX);
> else if (i386_pe_dllexport_name_p (oldname))
> return; /* already done */
>
>--- 353,365 ----
> else
> abort ();
> if (i386_pe_dllimport_name_p (oldname))
>! {
>! warning ("%Hinconsistent dll linkage for '%D, dllexport assumed.",
>! &DECL_SOURCE_LOCATION (decl), decl);
>! /* Remove DLL_IMPORT_PREFIX. */
>! oldname += strlen (DLL_IMPORT_PREFIX);
>! DECL_NON_ADDR_CONST_P (decl) = 0;
>! }
> else if (i386_pe_dllexport_name_p (oldname))
> return; /* already done */
>
>*************** i386_pe_mark_dllimport (decl)
>*** 291,331 ****
> }
> else if (i386_pe_dllimport_name_p (oldname))
> {
>! /* Already done, but force correct linkage since the redeclaration
>! might have omitted explicit extern. Sigh. */
>! if (TREE_CODE (decl) == VAR_DECL
>! /* ??? Is this test for vtables needed? */
>! && !DECL_VIRTUAL_P (decl))
> {
>! DECL_EXTERNAL (decl) = 1;
>! TREE_PUBLIC (decl) = 1;
> }
> return;
> }
>
>- /* ??? One can well ask why we're making these checks here,
>- and that would be a good question. */
>-
>- /* Imported variables can't be initialized. Note that C++ classes
>- are marked initial, so we need to check. */
>- if (TREE_CODE (decl) == VAR_DECL
>- && !DECL_VIRTUAL_P (decl)
>- && (DECL_INITIAL (decl)
>- && ! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
>- {
>- error_with_decl (decl, "initialized variable `%s' is marked dllimport");
>- return;
>- }
>- /* Nor can they be static. */
>- if (TREE_CODE (decl) == VAR_DECL
>- /* ??? Is this test for vtables needed? */
>- && !DECL_VIRTUAL_P (decl)
>- && 0 /*???*/)
>- {
>- error_with_decl (decl, "static variable `%s' is marked dllimport");
>- return;
>- }
>-
> newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
> sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
>
>--- 403,418 ----
> }
> else if (i386_pe_dllimport_name_p (oldname))
> {
>! /* Already done, but do a sanity check to prevent assembler errors. */
>! if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
> {
>! error ("%Hfailure in redeclaration of '%D': dllimport'd symbol lacks external linkage.",
>! &DECL_SOURCE_LOCATION (decl), decl);
>! abort();
> }
> return;
> }
>
> newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
> sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
>
>*************** i386_pe_encode_section_info (decl, rtl,
>*** 443,449 ****
>
> /* Mark the decl so we can tell from the rtl whether the object is
> dllexport'd or dllimport'd. This also handles dllexport/dllimport
>! override semantics. */
>
> if (i386_pe_dllexport_p (decl))
> i386_pe_mark_dllexport (decl);
>--- 530,536 ----
>
> /* Mark the decl so we can tell from the rtl whether the object is
> dllexport'd or dllimport'd. This also handles dllexport/dllimport
>! override semantics. */
>
> if (i386_pe_dllexport_p (decl))
> i386_pe_mark_dllexport (decl);
>*************** i386_pe_encode_section_info (decl, rtl,
>*** 466,471 ****
>--- 553,564 ----
> tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
> rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
>
>+ warning ("%H%s of %s '%D', previously marked with '_imp_' dllimport prefix.",
>+ &DECL_SOURCE_LOCATION (decl),
>+ DECL_INITIAL (decl) ? "definition" : "redeclaration",
>+ TREE_CODE (decl) == VAR_DECL ? "variable" : "function",
>+ decl);
>+
> XEXP (DECL_RTL (decl), 0) = newrtl;
>
> DECL_NON_ADDR_CONST_P (decl) = 0;
>*************** void i386_pe_output_labelref (stream, na
>*** 519,526 ****
> {
> if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
> == 0)
>! /* A dll import */
>! {
> if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
> /* A dllimport fastcall symbol. */
> {
>--- 612,619 ----
> {
> if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
> == 0)
>! /* A dll import */
>! {
> if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
> /* A dllimport fastcall symbol. */
> {
>*************** i386_pe_asm_file_end (file)
>*** 796,799 ****
> }
> }
> }
>-
>--- 889,891 ----
>Index: testsuite/g++.dg/ext/dllimport1.C
>===================================================================
>RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/dllimport1.C,v
>retrieving revision 1.1
>diff -c -3 -p -r1.1 dllimport1.C
>*** testsuite/g++.dg/ext/dllimport1.C 12 Apr 2003 20:01:29 -0000 1.1
>--- testsuite/g++.dg/ext/dllimport1.C 29 May 2003 22:16:34 -0000
>***************
>*** 1,12 ****
>! // { dg-do compile { target i?86-*-cygwin* } }
>
> class __attribute__((dllimport)) Foo
> {
> public:
> virtual void dummy_foo_func(void)
>! {}
> };
>
> class Bar : public Foo
> {
> public:
>--- 1,20 ----
>! // PR c++/7910
>! // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>! // { dg-options { -Wall -W } }
>
> class __attribute__((dllimport)) Foo
> {
> public:
> virtual void dummy_foo_func(void)
>! {} // { dg-warning "inline function" }
>! virtual void dummy_foo_fun2(void);
>! virtual ~Foo(); // avoid warning
> };
>
>+ void Foo::dummy_foo_fun2()
>+ { // { dg-warning "definition" }
>+ }
>+
> class Bar : public Foo
> {
> public:
>*************** Bar::~Bar()
>*** 19,21 ****
>--- 27,31 ----
>
> void Bar::dummy_bar_func()
> {}
>+
>+ // { dg-final { scan-assembler-not "__imp___ZN3Foo14dummy_foo_fun" } }
>Index: testsuite/g++.dg/ext/dllimport2.C
>===================================================================
>RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/dllimport2.C,v
>retrieving revision 1.1
>diff -c -3 -p -r1.1 dllimport2.C
>*** testsuite/g++.dg/ext/dllimport2.C 21 May 2003 00:33:27 -0000 1.1
>--- testsuite/g++.dg/ext/dllimport2.C 29 May 2003 22:16:34 -0000
>***************
>*** 1,15 ****
> // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>
>! // PR 9738 Dllimport attribute is overriden by later definition
>
> void __attribute__((dllimport)) Bar(void);
>
>! void Foo(void)
>! {
>! Bar();
>! }
>
>! void Bar(void)
>! {
>! }
>
>--- 1,15 ----
> // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>
>! // PR c++/9738 Dllimport attribute is overriden by later definition
>
> void __attribute__((dllimport)) Bar(void);
>
>! void Foo(void)
>! {
>! Bar();
>! }
>
>! void Bar(void)
>! { // { dg-warning "definition" }
>! }
>
>Index: testsuite/g++.dg/ext/dllimport3.C
>===================================================================
>RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/dllimport3.C,v
>retrieving revision 1.1
>diff -c -3 -p -r1.1 dllimport3.C
>*** testsuite/g++.dg/ext/dllimport3.C 21 May 2003 00:33:27 -0000 1.1
>--- testsuite/g++.dg/ext/dllimport3.C 29 May 2003 22:16:34 -0000
>*************** struct Foo
>*** 15,21 ****
> void* dummy = &f;
> }
>
>! struct Foo f;
>
> // Dllimport sets DECL_NON_ADDR_CONST_P to 1, so following
> // assignment would require static_initialization_and_destruction
>--- 15,21 ----
> void* dummy = &f;
> }
>
>! struct Foo f; // { dg-warning "redeclaration" }
>
> // Dllimport sets DECL_NON_ADDR_CONST_P to 1, so following
> // assignment would require static_initialization_and_destruction
>*** /dev/null Fri May 30 01:30:45 2003
>--- testsuite/g++.dg/ext/dllimport4.C Thu May 29 03:04:48 2003
>***************
>*** 0 ****
>--- 1,6 ----
>+ // Throw error if explicit dllimport attribute in definition itself.
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+
>+ __attribute__((dllimport)) void bar () { } // { dg-error "definition" }
>+
>+ __attribute__((dllimport)) int foo = 1; // { dg-error "definition" }
>*** /dev/null Fri May 30 01:30:56 2003
>--- testsuite/g++.dg/ext/dllimport5.C Mon May 26 04:07:19 2003
>***************
>*** 0 ****
>--- 1,25 ----
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+ // Raise error if static symbol definition has dllimport attribute.
>+
>+
>+ __attribute__((dllimport))
>+ static int static_impvar; // { dg-error "external linkage required" }
>+
>+ __attribute__((dllexport))
>+ static int static_expvar; // { dg-error "external linkage required" }
>+
>+ __attribute__((dllimport))
>+ static void static_impfun(void); // { dg-error "external linkage required" }
>+
>+ void foo()
>+ {
>+ __attribute__((dllimport)) int foovar; // OK, implicit "extern"
>+ foovar++;
>+ }
>+
>+ void bar()
>+ {
>+ __attribute__((dllexport)) int barvar; // { dg-error "external linkage required" }
>+ barvar++;
>+ }
>+
>*** /dev/null Fri May 30 01:31:03 2003
>--- testsuite/g++.dg/ext/dllimport6.C Thu May 29 03:15:16 2003
>***************
>*** 0 ****
>--- 1,32 ----
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+ // Do mark class static members as dllimport.
>+ // Don't mark in-class initialized static consts as dllimport.
>+
>+ struct Baz
>+ {
>+ Baz(int a_ =0) : a(a_) {};
>+ int a;
>+ };
>+
>+ class __attribute__ ((dllimport)) Bar
>+ {
>+ public:
>+ enum {one = 1};
>+ static const int two = 2; // { dg-warning "in-class initialization" }
>+ static const int three; // Do import.
>+ static const Baz null_baz; // Do import.
>+ };
>+
>+ int foo()
>+ {
>+ Bar foobar;
>+ int a = foobar.two;
>+ int b = foobar.three;
>+ int c = foobar.null_baz.a;
>+ return (a + b + c);
>+ }
>+
>+ // { dg-final { scan-assembler __imp___ZN3Bar8null_bazE } }
>+ // { dg-final { scan-assembler-not __imp___ZN3Bar3twoE } }
>+ // { dg-final { scan-assembler __imp___ZN3Bar5threeE } }
>+
>*** /dev/null Fri May 30 01:31:09 2003
>--- testsuite/g++.dg/ext/dllimport7.C Tue May 27 10:11:40 2003
>***************
>*** 0 ****
>--- 1,30 ----
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+
>+ // Throw errors on definition of dllimport'd static data member .
>+
>+
>+ struct Baz
>+ {
>+ Baz(int a_ =0) : a(a_) {};
>+ int a;
>+ };
>+
>+ class __attribute__ ((dllimport)) Bar
>+ {
>+ public:
>+ enum {one = 1};
>+ static const int two;
>+ static const int three;
>+ static const Baz null_baz;
>+ };
>+
>+ const int Bar::three = 3; // { dg-error "definition of static data" }
>+ const Baz Bar::null_baz; // { dg-error "definition of static data" }
>+
>+ void foo()
>+ {
>+ Bar foobar;
>+ int a = foobar.two;
>+ int b = foobar.three;
>+ int c = foobar.null_baz.a;
>+ }
>*** /dev/null Fri May 30 01:31:14 2003
>--- testsuite/g++.dg/ext/dllimport8.C Thu May 29 04:50:11 2003
>***************
>*** 0 ****
>--- 1,30 ----
>+ // PR c++/8378
>+ // Ignore dllimport of static members if marked inlined.
>+ // or if definition follows declaration in dllimported class.
>+
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+ // { dg-options { -Wall -W } }
>+
>+
>+ struct __attribute__((dllimport)) Foo
>+ {
>+ static int static_int;
>+ static void static_func1();
>+ static void static_func2();
>+ };
>+
>+ void Foo::static_func1()
>+ { // { dg-warning "definition" }
>+ }
>+
>+ inline void Foo::static_func2()
>+ { // { dg-warning "inline function" }
>+ }
>+
>+ void testfoo()
>+ {
>+ Foo::static_func1();
>+ Foo::static_func2();
>+ }
>+
>+ // { dg-final { scan-assembler-not "__imp__" } }
>*** /dev/null Fri May 30 01:31:20 2003
>--- testsuite/g++.dg/ext/dllimport9.C Thu May 29 10:47:04 2003
>***************
>*** 0 ****
>--- 1,30 ----
>+ // Handle dllimport attribute for functions declared inline.
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+ // { dg-options -fkeep-inline-functions }
>+
>+ __attribute__((dllimport)) inline void bar() { }
>+
>+ __attribute__((dllimport)) void foo ();
>+ inline void foo() { }
>+
>+ struct __attribute__ ((dllimport)) Blah
>+ {
>+ void in_blah () { }
>+ void out_blah ();
>+ };
>+
>+ inline void Blah::out_blah(){ }
>+
>+ __attribute__((dllimport)) void boo ();
>+ void baz() { boo (); }
>+ inline void boo() { foo (); } // { dg-warning "definition" }
>+
>+
>+ // { dg-final { scan-assembler "_Z3barv" } }
>+ // { dg-final { scan-assembler-not "__imp___Z3barv" } }
>+ // { dg-final { scan-assembler "_Z3foov" } }
>+ // { dg-final { scan-assembler-not "__imp___Z3foov" } }
>+ // { dg-final { scan-assembler "_ZN4Blah8out_blahEv" } }
>+ // { dg-final { scan-assembler-not "__imp___ZN4Blah8out_blahEv" } }
>+ // { dg-final { scan-assembler "_ZN4Blah7in_blahEv" } }
>+ // { dg-final { scan-assembler-not "__imp___ZN4Blah7in_blahEv" } }
>*** /dev/null Fri May 30 01:31:26 2003
>--- testsuite/g++.dg/ext/dllimport10.C Thu May 29 04:50:39 2003
>***************
>*** 0 ****
>--- 1,21 ----
>+ // PR c++/11021
>+ // Inherit a virtual method from a dllimport'd base class
>+
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+
>+ class __declspec(dllimport) Base_in_Dll {
>+ public:
>+ virtual void vfunc1(void) const;
>+ virtual void vfunc2(void) const;
>+ };
>+
>+ class Derived_in_App : public Base_in_Dll
>+ {
>+ public:
>+ void vfunc1(void) const
>+ {
>+ }
>+ // inherit vfunc2
>+ };
>+
>+ Derived_in_App appclass;
>*** /dev/null Fri May 30 01:31:35 2003
>--- testsuite/g++.dg/ext/dllexport1.C Fri May 23 10:14:44 2003
>***************
>*** 0 ****
>--- 1,19 ----
>+ // Test that inline functions are exported with -fkeep-inline-functions.
>+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
>+ // { dg-options -fkeep-inline-functions }
>+
>+ __attribute__((dllexport)) inline int foo(int a) { return a;}
>+
>+ class __attribute__((dllexport)) Bar
>+ {
>+ public:
>+ int inline_bar(int a) {return a;}
>+ int outline_bar(int a);
>+ };
>+
>+ int Bar::outline_bar(int a) {return a;}
>+
>+
>+ // { dg-final { scan-assembler "\.section\[ \t\]*.drectve\n.*_ZN3Bar11outline_barEi" } }
>+ // { dg-final { scan-assembler " -export:_ZN3Bar10inline_barEi" } }
>+ // { dg-final { scan-assembler " -export:_Z3fooi" } }