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]

[Bug c++/9738. c++/5287, c++/7910, c++/11021 ] [3.3 regression] [mingw]: Patch


Hello.

The attached backport fixes mingw/cygwin dllimport regressions
on 3.3 branch.  Chris Faylor has approved changes to config/i386/winnt.c
for branch.  However, for these to have any affect, backport of
patches to c-decl.c (duplicate_decls) and to cp/decl.c (dupicate_decls)
to re-invoke make_decl_rtl are also required, so I need approval for
those as well.

The patches  cause no regressions on 3.3 branch with i386-pc-mingw32
but I am unable to test other targets.

(This does not include my recent dllexport vs MI-thunk patch to trunk,
which has been approved for trunk and branch by Chris, pending no
further objection).

Danny


ChangeLog

2003-07-11  Danny Smith  <dannysmith@users.sourceforge.net>

	Backport from trunk

	2003-05-13  Richard Henderson  <rth@redhat.com>

	* c-decl.c (duplicate_decls): Re-invoke make_decl_rtl if
	the old decl had instantiated DECL_RTL.

	2003-05-21  Danny Smith  <dannysmith@users.sourceforge.net>

	PR c++/9738
	* config/i386/winnt.c (i386_pe_encode_section_info): Enable
	even if not first.

	2003-07-04  Danny Smith  <dannysmith@users.sourceforge.net>

	PR c++/5287, PR c++/7910, PR c++/11021
	* config/i386/winnt.c (ix86_handle_dll_attribute): Don't add
	dllimport attribute if function is defined at declaration, but
	report error instead. Likewise for dllimport'd variable
	definitions.  Set implicit TREE_PUBLIC for dllimport'd variables
	declared within functions, Report 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. Don't allow definition
	of static data members of C++ classes. Don't dllimport virtual
	methods.
	(i386_pe_mark_dllexport): Warn about inconsistent dll attributes.
	(i386_pe_mark_dllimport): Remove unnecessary checks.
	(i386_pe_encode_section_info): Warn if the dllimport attribute
	and symbol prefix have been instantiated and then overridden.

	* doc/extend.texi: Document dllimport and dllexport attributes.

cp/ChangeLog

2003-07-11  Danny Smith  <dannysmith@users.sourceforge.net>

	Backport from trunk

	2003-05-21  Danny Smith  <dannysmith@users.sourceforge.net>

	PR c++/9738
	* decl.c (duplicate_decls): Re-invoke make_decl_rtl
	if the old decl had instantiated DECL_RTL.
	(Base on Richard Henderson 2003-05-13 patch to c-decl.c).


testsuite/ChangeLog

2003-07-11  Danny Smith  <dannysmith@users.sourceforge.net>

	2003-05-21  Danny Smith  <dannysmith@users.sourceforge.net>

	PR c++/9738
	* g++.dg/ext/dllimport2.C: New file.
	* g++.dg/ext/dllimport3.C: New file.

	2003-07-04  Danny Smith  <dannysmith@users.sourceforge.net>

	PR c++/5287, PR c++/7910,  PR c++/11021
	* testsuite/g++.dg/ext/dllimport1.C: Add mingw32 as target. Add
	tests for warnings.
	* testsuite/g++.dg/ext/dllimport2.C: Add tests for warnings.
	* testsuite/g++.dg/ext/dllimport3.C: Likewise.
	* testsuite/g++.dg/ext/dllimport4.C: New file.
	* testsuite/g++.dg/ext/dllimport5.C: New file.
	* testsuite/g++.dg/ext/dllimport6.C: New file.
	* testsuite/g++.dg/ext/dllimport7.C: New file.
	* testsuite/g++.dg/ext/dllimport8.C: New file.
	* testsuite/g++.dg/ext/dllimport9.C: New file.
	* testsuite/g++.dg/ext/dllimport10.C: New file.
	* testsuite/g++.dg/ext/dllexport1.C: New file.


http://mobile.yahoo.com.au - Yahoo! Mobile
- Check & compose your email via SMS on your Telstra or Vodafone mobile.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.356.2.10
diff -c -3 -p -r1.356.2.10 c-decl.c
*** c-decl.c	12 Jun 2003 14:38:09 -0000	1.356.2.10
--- c-decl.c	10 Jul 2003 23:36:25 -0000
*************** duplicate_decls (newdecl, olddecl, diffe
*** 1578,1583 ****
--- 1578,1592 ----
       Update OLDDECL to be the same.  */
    DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
  
+  /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
+      so that encode_section_info has a chance to look at the new decl
+      flags and attributes.  */
+   if (DECL_RTL_SET_P (olddecl)
+       && (TREE_CODE (olddecl) == FUNCTION_DECL
+ 	  || (TREE_CODE (olddecl) == VAR_DECL
+ 	      && TREE_STATIC (olddecl))))
+     make_decl_rtl (olddecl, NULL);
+ 
    return 1;
  }
  
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.965.2.53
diff -c -3 -p -r1.965.2.53 decl.c
*** cp/decl.c	27 Jun 2003 21:28:13 -0000	1.965.2.53
--- cp/decl.c	10 Jul 2003 23:36:58 -0000
*************** duplicate_decls (newdecl, olddecl)
*** 4039,4044 ****
--- 4039,4053 ----
       Update OLDDECL to be the same.  */
    DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
  
+   /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
+      so that encode_section_info has a chance to look at the new decl
+      flags and attributes.  */
+   if (DECL_RTL_SET_P (olddecl)
+       && (TREE_CODE (olddecl) == FUNCTION_DECL
+ 	  || (TREE_CODE (olddecl) == VAR_DECL
+ 	      && TREE_STATIC (olddecl))))
+     make_decl_rtl (olddecl, NULL);
+ 
    return 1;
  }
  
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.109.2.17
diff -c -3 -p -r1.109.2.17 extend.texi
*** doc/extend.texi	23 Jun 2003 16:02:42 -0000	1.109.2.17
--- doc/extend.texi	11 Jul 2003 00:40:32 -0000
*************** contents of that register.   The @code{s
*** 2432,2451 ****
  the offset to the function from the call site into the @samp{BL}
  instruction directly.
  
- @item dllimport
- @cindex functions which are imported from a dll on PowerPC Windows NT
- On the PowerPC running Windows NT, the @code{dllimport} attribute causes
- the compiler to call the function via a global pointer to the function
- pointer that is set up by the Windows NT dll library.  The pointer name
- is formed by combining @code{__imp_} and the function name.
- 
- @item dllexport
- @cindex functions which are exported from a dll on PowerPC Windows NT
- On the PowerPC running Windows NT, the @code{dllexport} attribute causes
- the compiler to provide a global pointer to the function pointer, so
- that it can be called with the @code{dllimport} attribute.  The pointer
- name is formed by combining @code{__imp_} and the function name.
- 
  @item exception (@var{except-func} [, @var{except-arg}])
  @cindex functions which specify exception handling on PowerPC Windows NT
  On the PowerPC running Windows NT, the @code{exception} attribute causes
--- 2432,2437 ----
*************** use the normal calling convention based 
*** 2589,2594 ****
--- 2575,2639 ----
  This attribute can be used to cancel the effect of the @option{-mlong-calls}
  option.
  
+ @item dllimport
+ @cindex @code{__declspec(dllimport)}
+ On Windows targets, the @code{dllimport} attribute causes the compiler
+ to reference a function or variable via a global pointer to a pointer
+ that is set up by the Windows dll library. The pointer name is formed by
+ combining @code{_imp__} and the function or variable name. The attribute
+ implies @code{extern} storage.
+ 
+ Currently, the attribute is ignored for inlined functions. If the
+ attribute is applied to a symbol @emph{definition}, an error is emitted.
+ If a symbol previousy declared @code{dllimport} is later defined, the
+ attribute is ignored in subsequent references, and a warning is emitted.
+ The attribute is also overriden by a subsequent declaration as
+ @code{dllexport}. 
+ 
+ When applied to C++ classes, the attribute marks non-inlined
+ member functions and static data members as imports.
+ 
+ On cygwin, mingw and arm-pe targets, @code{__declspec(dllimport)} is
+ recognized as a synonym for @code{__attribute__ ((dllimport))} for
+ compatibility with other Windows compilers.
+ 
+ The use of the @code{dllimport} attribute on functions is not necessary,
+ but provides a small performance benefit by eliminating a thunk in the
+ dll. The use of the @code{dllimport} attribute on imported variables was
+ required on older versions of GNU ld, but can now be avoided by passing
+ the @option{--enable-auto-import} switch to ld. As with functions, using
+ the attribute for a variable eliminates a thunk in the dll. 
+ 
+ One drawback to using this attribute is that a pointer to a function or
+ variable marked as dllimport cannot be used as a constant address. The
+ attribute can be disabled for functions by setting the
+ @option{-mnop-fun-dllimport} flag.
+ 
+ @item dllexport
+ @cindex @code{__declspec(dllexport)}
+ On Windows targets the @code{dllexport} attribute causes the compiler to
+ provide a global pointer to a pointer in a dll, so that it can be
+ referenced with the @code{dllimport} attribute. The pointer name is
+ formed by combining @code{_imp__} and the function or variable name.
+ 
+ Currently, the @code{dllexport}attribute is ignored for inlined
+ functions, but export can be forced by using the
+ @option{-fkeep-inline-functions} flag. The attribute is also ignored
+ for undefined symbols.
+ 
+ When applied to C++ classes. the attribute marks non-inlined
+ member functions and static data members as exports.  Static consts
+ initialized in-class are not marked unless they are also defined
+ out-of-class.
+ 
+ On cygwin, mingw and arm-pe targets, @code{__declspec(dllexport)} is
+ recognized as a synonym for @code{__attribute__ ((dllexport))} for
+ compatibility with other Windows compilers.
+ 
+ Alternative methods for including the symbol in the dll's export table
+ are to use a .def file with an @code{EXPORTS} section, or with GNU ld,
+ using the @option{--export-all} linker flag.
+ 
  @end table
  
  You can specify multiple attributes in a declaration by separating them
*************** addresses can be loaded with the @code{l
*** 3271,3276 ****
--- 3316,3327 ----
  Medium and large model objects may live anywhere in the 32-bit address space
  (the compiler will generate @code{seth/add3} instructions to load their
  addresses).
+ 
+ @item dllimport
+ The @code{dllimport} attribute is described in @xref{Function Attributes}.
+ 
+ @item dlexport
+ The @code{dllexport} attribute is described in @xref{Function Attributes}.
  
  @end table
  
Index: config/i386/winnt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/winnt.c,v
retrieving revision 1.37.2.3
diff -c -3 -p -r1.37.2.3 winnt.c
*** config/i386/winnt.c	21 Apr 2003 23:25:55 -0000	1.37.2.3
--- config/i386/winnt.c	10 Jul 2003 23:36:58 -0000
***************
*** 1,24 ****
  /* Subroutines for insn-output.c for Windows NT.
     Contributed by Douglas Rupp (drupp@cs.washington.edu)
!    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002
     Free Software Foundation, Inc.
  
! This file is part of GNU CC.
  
! GNU CC is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 2, or (at your option)
! any later version.
! 
! GNU CC is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
! along with GNU CC; see the file COPYING.  If not, write to
! the Free Software Foundation, 59 Temple Place - Suite 330,
! Boston, MA 02111-1307, USA.  */
  
  #include "config.h"
  #include "system.h"
--- 1,24 ----
  /* Subroutines for insn-output.c for Windows NT.
     Contributed by Douglas Rupp (drupp@cs.washington.edu)
!    Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
     Free Software Foundation, Inc.
  
! This file is part of GCC.
  
! GCC is free software; you can redistribute it and/or modify it under
! the terms of the GNU General Public License as published by the Free
! Software Foundation; either version 2, or (at your option) any later
! version.
! 
! GCC is distributed in the hope that it will be useful, but WITHOUT ANY
! WARRANTY; without even the implied warranty of MERCHANTABILITY or
! FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
! for more details.
  
  You should have received a copy of the GNU General Public License
! along with GCC; see the file COPYING.  If not, write to the Free
! Software Foundation, 59 Temple Place - Suite 330, Boston, MA
! 02111-1307, USA.  */
  
  #include "config.h"
  #include "system.h"
*************** void i386_pe_mark_dllimport PARAMS ((tre
*** 54,69 ****
  /* 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))
--- 54,71 ----
  /* 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
*** 71,90 ****
  	  *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;
--- 73,128 ----
  	  *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;
+     }
+ 
+   /* Report error 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_with_decl (node, "function `%s' definition is marked dllimport.");
+ 	  *no_add_attrs = true;
+ 	}
+ 
+       else if (TREE_CODE (node) == VAR_DECL)
+ 	{
+ 	  if (DECL_INITIAL (node))
+ 	    {
+ 	      error_with_decl (node,"variable `%s' definition is marked dllimport.");
+ 	      *no_add_attrs = true;
+ 	    }
+ 
+ 	  /* `extern' needn't be specified with dllimport.
+ 	     Specify `extern' now and hope for the best.  Sigh.  */
+ 	  DECL_EXTERNAL (node) = 1; 
+ 	  /* Also, implicitly give dllimport'd variables declared within
+ 	     a function global scope, unless declared static.  */
+ 	  if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
+   	    TREE_PUBLIC (node) = 1;
+ 	}
      }
  
!   /*  Report error if symbol is not accessible at global scope. */
!   if (!TREE_PUBLIC (node)
!       && (TREE_CODE (node) == VAR_DECL
! 	  || TREE_CODE (node) == FUNCTION_DECL)) 
      {
!       error_with_decl (node, "external linkage required for symbol '%s' because of '%s' attribute.",
! 		       IDENTIFIER_POINTER (name));
!       *no_add_attrs = true;
      }
  
    return NULL_TREE;
*************** i386_pe_dllimport_p (decl)
*** 169,174 ****
--- 207,213 ----
       tree decl;
  {
    tree imp;
+   int context_imp = 0;
  
    if (TREE_CODE (decl) == FUNCTION_DECL
        && TARGET_NOP_FUN_DLLIMPORT)
*************** i386_pe_dllimport_p (decl)
*** 177,193 ****
    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;
--- 216,277 ----
    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, than ix86_handle_dll_attribute
! 	 reports an error. This handles the case when the definition
! 	 overrides an earlier declaration.  */
!       if (TREE_CODE (decl) ==  FUNCTION_DECL && DECL_INITIAL (decl)
! 	  && !DECL_INLINE (decl))
! 	{
! 	   /* Don't warn about artificial methods.  */
! 	  if (!DECL_ARTIFICIAL (decl))
! 	    warning_with_decl (decl,"function '%s' is defined after prior declaration as dllimport: attribute ignored.");
! 	  return 0;
! 	}
! 
!       /* We ignore the dllimport attribute for inline member 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_with_decl (decl, "inline function '%s' is declared as dllimport: attribute ignored.");
! 	  return 0;
! 	}
! 
!       /*  Don't allow definitions of static data members in dllimport class,
! 	  Just ignore attribute for vtable data.  */
!       else if (TREE_CODE (decl) == VAR_DECL
! 	       && TREE_STATIC (decl) && TREE_PUBLIC (decl)
! 	       && !DECL_EXTERNAL (decl) && context_imp)
! 	{
! 	  if (!DECL_VIRTUAL_P (decl))
! 	      error_with_decl (decl, "definition of static data member '%s' of dllimport'd class.");
!            return 0;
! 	}
! 
!       /* Since we can't treat a pointer to a dllimport'd symbol as a
! 	 constant address, we turn off the attribute on C++ virtual
! 	 methods to allow creation of vtables using thunks. */
!       else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
! 	       && (DECL_VIRTUAL_P (decl)))
!            return 0;
! 
!       return 1;
      }
  
    return 0;
*************** i386_pe_mark_dllexport (decl)
*** 234,240 ****
    else
      abort ();
    if (i386_pe_dllimport_name_p (oldname))
!     oldname += 9;
    else if (i386_pe_dllexport_name_p (oldname))
      return; /* already done */
  
--- 318,329 ----
    else
      abort ();
    if (i386_pe_dllimport_name_p (oldname))
!     {
!       warning_with_decl (decl,"inconsistent dll linkage for '%s': dllexport assumed.");
!      /* Remove DLL_IMPORT_PREFIX.  */
!       oldname += 9;
!       DECL_NON_ADDR_CONST_P (decl) = 0;
!     }
    else if (i386_pe_dllexport_name_p (oldname))
      return; /* already done */
  
*************** i386_pe_mark_dllimport (decl)
*** 278,316 ****
      }
    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 (oldname) + 11);
--- 367,379 ----
      }
    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_with_decl (decl, "failure in redeclaration of '%s': dllimport'd symbol lacks external linkage.");
! 	  abort();
  	}
!     return;
      }
  
    newname = alloca (strlen (oldname) + 11);
*************** gen_stdcall_suffix (decl)
*** 372,382 ****
  void
  i386_pe_encode_section_info (decl, first)
       tree decl;
!      int first;
  {
-   if (!first)
-     return;
- 
    /* This bit is copied from i386.h.  */
    if (optimize > 0 && TREE_CONSTANT (decl)
        && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
--- 435,442 ----
  void
  i386_pe_encode_section_info (decl, first)
       tree decl;
!      int first ATTRIBUTE_UNUSED;
  {
    /* This bit is copied from i386.h.  */
    if (optimize > 0 && TREE_CONSTANT (decl)
        && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
*************** i386_pe_encode_section_info (decl, first
*** 393,399 ****
  	gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
  
    /* Mark the decl so we can tell from the rtl whether the object is
!      dllexport'd or dllimport'd.  */
  
    if (i386_pe_dllexport_p (decl))
      i386_pe_mark_dllexport (decl);
--- 453,460 ----
  	gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
  
    /* 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, first
*** 415,420 ****
--- 476,485 ----
        tree idp = get_identifier (oldname + 9);
        rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
  
+       warning_with_decl (decl, "'%s' %s after being referenced with dllimport linkage.",
+ 	         	 (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
+ 			 ? "defined locally" : "redeclared without dllimport attribute");
+ 
        XEXP (DECL_RTL (decl), 0) = newrtl;
  
        DECL_NON_ADDR_CONST_P (decl) = 0;
*************** i386_pe_asm_file_end (file)
*** 698,701 ****
  	}
      }
  }
- 
--- 763,765 ----
Index: testsuite/g++.dg/ext/dllimport1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/dllimport1.C,v
retrieving revision 1.1.2.1
diff -c -3 -p -r1.1.2.1 dllimport1.C
*** testsuite/g++.dg/ext/dllimport1.C	12 Apr 2003 20:03:12 -0000	1.1.2.1
--- testsuite/g++.dg/ext/dllimport1.C	10 Jul 2003 23:36:58 -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" }
!   void Foo::dummy_foo_fun2();
!   virtual ~Foo();  //  avoid warning  
  };
  
+ void Foo::dummy_foo_fun2()
+ {	//  { dg-warning "defined" }
+ }
+ 
  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" } }
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllexport1.C	Wed Jun  4 09:36:10 2003
***************
*** 0 ****
--- 1,23 ----
+ // 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:
+     Bar(){};
+     int inline_bar(int a) {return a;}
+     int outline_bar(int a); 
+ };
+ 
+ int Bar::outline_bar(int a) {return foo (a);}
+ 
+ 
+ Bar abar;
+ 
+ // { dg-final { scan-assembler "\.section\[ \t\]*.drectve\n.*_ZN3Bar11outline_barEi" } }
+ // { dg-final { scan-assembler " -export:_ZN3Bar10inline_barEi" } }
+ // { dg-final { scan-assembler " -export:_Z3fooi" } }
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport10.C	Wed Jun 11 11:45:02 2003
***************
*** 0 ****
--- 1,16 ----
+ // PR c++/5287, c++/11021
+ // Inherit a virtual method from a dllimport'd base class.
+ 
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ 
+ struct __attribute__((dllimport)) A
+ {
+   virtual void vfunc(void);
+ };
+ 
+ struct B : public A
+ {
+ };
+ 
+ 
+ B aB;
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport2.C	Sun Jun 15 22:05:27 2003
***************
*** 0 ****
--- 1,29 ----
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ 
+ // PR c++/9738  Dllimport attribute is overriden by later definition/redeclaration
+ 
+ void __attribute__((dllimport)) Bar(void);
+ void __attribute__((dllimport)) Baz(void);
+ __attribute__((dllimport)) int Biz;
+ __attribute__((dllimport)) int Boz;
+ 
+ void Foo(void)
+   {
+     Bar();
+     Baz();
+     Biz++;	 
+     Boz++;	 
+   }
+  
+ void Bar(void)
+   {			// { dg-warning "defined" }
+   }
+ 
+ void Baz(void);		// { dg-warning "redeclared" }
+ extern int Biz;		// { dg-warning "redeclared" }
+ int Boz;		// { dg-warning "defined" }
+ 
+ void foo()
+ {
+   Biz++;
+ }
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport3.C	Sun Jun 15 09:54:46 2003
***************
*** 0 ****
--- 1,25 ----
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ 
+ // PR 10148  Dllimport attribute of object is overriden by later
+ // redefinition without attribute.
+  
+ struct Foo
+  {
+      int a;
+  };
+ 
+  __attribute__((dllimport)) struct Foo f;
+ 
+  void Bar(void)
+  {
+      void* dummy = &f;
+  }
+ 
+  struct Foo f;	// { dg-warning "defined" }
+ 
+ // Dllimport sets DECL_NON_ADDR_CONST_P to 1, so following
+ // assignment would require static_initialization_and_destruction
+ // if attribute is retained. 
+ 
+  void* dummy = &f;
+  
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport4.C	Sat Jun 14 12:27:05 2003
***************
*** 0 ****
--- 1,6 ----
+ //  Report error if 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 Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport5.C	Thu Jul  3 23:12:19 2003
***************
*** 0 ****
--- 1,28 ----
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ //  Report error if static symbol definition has dllimport attribute.
+ 
+ __attribute__((dllimport))
+  int impvar;			// OK,  implicit "extern"
+ 
+  static __attribute__((dllimport))
+  int static_impvar;	// { dg-error "external linkage" }
+ 
+  static  __attribute__((dllexport))
+ int static_expvar;	// { dg-error "external linkage" }
+ 
+ static __attribute__((dllimport))
+ void static_impfun(void);	// { dg-error "external linkage" }
+ 
+ void foo()
+ {
+   __attribute__((dllimport))
+   int foovar;	// OK,  implicit "extern" 
+   foovar++;
+ }
+ 
+ void bar()
+ {
+   __attribute__((dllexport))
+   int barvar;	// { dg-error "external linkage" }
+   barvar++;
+ }
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport6.C	Sun Jun 15 10:39:04 2003
***************
*** 0 ****
--- 1,30 ----
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ //  Mark class static members as dllimport.
+ 
+ struct Baz
+ {
+   Baz(int a_ =0) : a(a_) {}; 
+   int a;
+ };
+ 
+ class  __attribute__ ((dllimport)) Bar
+ {
+   public:
+     static const int two = 2;
+     static const int three;
+     static const Baz null_baz;
+ };
+ 
+ int foo()
+ {
+   Bar foobar;
+   const int* baz = &Bar::two; 
+   int a = foobar.two;
+   int b = foobar.three;
+   int c = foobar.null_baz.a;
+   return (a + b + c + *baz);
+ }
+ 
+ // { dg-final { scan-assembler __imp___ZN3Bar3twoE } }
+ // { dg-final { scan-assembler __imp___ZN3Bar5threeE } }
+ // { dg-final { scan-assembler __imp___ZN3Bar8null_bazE } }
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport7.C	Sun Jun 15 10:00:27 2003
***************
*** 0 ****
--- 1,33 ----
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ 
+ //  Report errors on definition of dllimport'd static data member . 
+ 
+ 
+ struct Baz
+ {
+   Baz(int a_ =0) : a(a_) {}; 
+   int a;
+ };
+ 
+ class  __declspec(dllimport) Bar
+ {
+   public:
+     enum {one = 1};
+     static const int two = 2;
+     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" }
+ 
+ 
+ int foo()
+ {
+   Bar foobar;
+   const int* baz = &Bar::two; 
+   int a = foobar.two;
+   int b = foobar.three;
+   int c = foobar.null_baz.a;
+   return (a + b + c + *baz);
+ }
*** /dev/null	Fri Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport8.C	Wed Jun 11 12:08:08 2003
***************
*** 0 ****
--- 1,29 ----
+ //  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 "defined" }
+   }
+ 
+ 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 Jul 11 01:23:15 2003
--- testsuite/g++.dg/ext/dllimport9.C	Sun Jun 15 11:19:22 2003
***************
*** 0 ****
--- 1,23 ----
+ //  Handle dllimport attribute for functions declared inline.
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ // { dg-options { -W } }
+ 
+ inline __attribute__((dllimport)) void bar() { }	// { dg-warning "inline" }
+ 
+ struct __attribute__ ((dllimport)) Blah	
+ {
+   void in_blah () { }				// { dg-warning "inline" }
+   void out_blah ();
+ };
+ 
+ inline void Blah::out_blah(){ }			// { dg-warning "inline" }
+ 
+ void use_inlines()
+ {
+   Blah aBlah;
+   bar();
+   aBlah.in_blah ();
+   aBlah.out_blah ();
+ }
+ 
+ // { dg-final { scan-assembler-not "__imp__" } }

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