This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Fix PR middle end/21275 dllimport bug


PRS 21081, 21275, 21766 result from the decl flag DECL_NON_ADDR_CONST_P
being set too late on dllimported symbols. Dllimports need the flag
since they are resolved by an indirect reference to the real symbol in
the dll.
ie.,
 __declspec (dllimport) int foo,

effectively does same as this:

extern int* _imp__foo;
#define foo *_imp__foo

Setting the DECL_NON_ADDR_CONST_P flag when the attribute is first
handled (and unsetting later, in merge_dllimport_decl_attributes
if the attribute is overriden by a definition) is only a partial fix,
In C++, adding the attribute to a class type implicitly cause
static data members and non-inline member functions to be treated as
dllimports. Thus in C++, we would need a target hook to propagate the
class type attribute to class member decls (similar to the way
visibility is handled in C++ FE now). That works, if I call such a target
hook wherever C++ FE calls determine_visibility() now.

The following proposes an alternative fix, which simply replaces
DECL_NON_ADDR_CONST_P and the tree_decl.non_addr_const_p bitfield
(currently only used by dllimport targets) with a target hook that for
these targets just reuses the existing dllimport_p functions that are
currently invoked when we make_decl_rtl.

While doing this I noticed that the i386_pe_dllimport_p code in winnt.c
needs a bit of a cleanup, but that is orthogonal to this amd will be
submitted separately
 
Bootstrapped & regtested i686-pc-mingw32 (c,c++,objc,f95)

I haven't been able to test the sh-symbian port which is also affected
by this.

ChangeLog

	from Danny Smith <dannysmith@users.sourceforge.net>

	PR middle end/21275
	* target.h (struct gcc_target): Add decl_non_addr_const_p. 
	* target-def.h (TARGET_INITIALIZER): Add TARGET_DECL_NON_ADDR_CONST_P. 
	 (TARGET_DECL_NON_ADDR_CONST_P): Define default hook as hook_bool_tree_false.
	* tree.h (DECL_NON_ADDR_CONST_P): Remove.
	(struct tree_decl): Remove non_addr_const_p bitfield.
	* tree.c (staticp): Replace DECL_NON_ADDR_CONST_P with
	 targetm.decl_non_addr_const_p.
	* varasm.c (initializer_constant_valid_p): Likewise.
	* doc/tm.texi (TARGET_DECL_NON_ADDR_CONST_P): Document)

	* config/i386/i386-protos.h (i386_pe_decl_non_addr_const_p): Declare.
	* config/i386/winnt.c (i386_pe_decl_non_addr_const_p): Define as wrapper
	for i386_pe_dllimport_p.
	(i386_pe_mark_dllexport): Remove reference to DECL_NON_ADDR_CONST_P.
	(i386_pe_mark_dllimport): Likewise.
	(i386_pe_encode_section_info): Likewise.
	* config/i386/cygming.h (TARGET_DECL_NON_ADDR_CONST_P): Define.

	* config/sh/sh-protos.h (sh_symbian_decl_non_addr_const_p): Declare.
	* config/sh/symbian.c (sh_symbian_decl_non_addr_const_p): Define as wrapper
	for sh_symbian_dllimport_p.
	(sh_symbian_mark_dllexport): Remove reference to DECL_NON_ADDR_CONST_P.
	(sh_symbian_encode_section_info): Likewise.
	* config/sh/symbian-post.h (TARGET_DECL_NON_ADDR_CONST_P): Define.



Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.134
diff -c -3 -p -r1.134 target.h
*** target.h	25 May 2005 11:52:10 -0000	1.134
--- target.h	26 May 2005 06:58:37 -0000
*************** struct gcc_target
*** 523,528 ****
--- 523,532 ----
    /* Returns true if target supports the insn within a doloop block.  */
    bool (*insn_valid_within_doloop) (rtx);
      
+   /* Return true if the pointer to a DECL cannot be treated as
+      an address constant.  */
+   bool (* decl_non_addr_const_p) (tree decl);
+ 
    /* Functions relating to calls - argument passing, returns, etc.  */
    struct calls {
      bool (*promote_function_args) (tree fntype);
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.122
diff -c -3 -p -r1.122 target-def.h
*** target-def.h	25 May 2005 11:52:11 -0000	1.122
--- target-def.h	26 May 2005 06:58:37 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 392,397 ****
--- 392,401 ----
  
  #define TARGET_STDARG_OPTIMIZE_HOOK 0
  
+ #ifndef TARGET_DECL_NON_ADDR_CONST_P
+ #define TARGET_DECL_NON_ADDR_CONST_P hook_bool_tree_false
+ #endif
+ 
  #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_false
  #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_false
  #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
*************** Foundation, 59 Temple Place - Suite 330,
*** 558,563 ****
--- 562,568 ----
    TARGET_DWARF_HANDLE_FRAME_UNSPEC,		\
    TARGET_STDARG_OPTIMIZE_HOOK,			\
    TARGET_INSN_VALID_WITHIN_DOLOOP,		\
+   TARGET_DECL_NON_ADDR_CONST_P,			\
    TARGET_CALLS,					\
    TARGET_CXX,					\
    TARGET_HAVE_NAMED_SECTIONS,			\
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.729
diff -c -3 -p -r1.729 tree.h
*** tree.h	24 May 2005 20:19:13 -0000	1.729
--- tree.h	26 May 2005 06:59:05 -0000
*************** struct tree_binfo GTY (())
*** 2295,2304 ****
  #define DECL_LANG_FLAG_6(NODE) (DECL_CHECK (NODE)->decl.lang_flag_6)
  #define DECL_LANG_FLAG_7(NODE) (DECL_CHECK (NODE)->decl.lang_flag_7)
  
- /* Used to indicate that the pointer to this DECL cannot be treated as
-    an address constant.  */
- #define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
- 
  /* Used in a FIELD_DECL to indicate that we cannot form the address of
     this component.  */
  #define DECL_NONADDRESSABLE_P(NODE) \
--- 2295,2300 ----
*************** struct tree_decl GTY(())
*** 2381,2403 ****
    unsigned artificial_flag : 1;
    unsigned weak_flag : 1;
  
-   unsigned non_addr_const_p : 1;
    unsigned no_instrument_function_entry_exit : 1;
    unsigned comdat_flag : 1;
    unsigned malloc_flag : 1;
    unsigned no_limit_stack : 1;
    ENUM_BITFIELD(built_in_class) built_in_class : 2;
    unsigned pure_flag : 1;
- 
    unsigned non_addressable : 1;
    unsigned user_align : 1;
    unsigned uninlinable : 1;
    unsigned thread_local_flag : 1;
    unsigned declared_inline_flag : 1;
    ENUM_BITFIELD(symbol_visibility) visibility : 2;
    unsigned visibility_specified : 1;
- 
    unsigned lang_flag_0 : 1;
    unsigned lang_flag_1 : 1;
    unsigned lang_flag_2 : 1;
    unsigned lang_flag_3 : 1;
--- 2377,2398 ----
    unsigned artificial_flag : 1;
    unsigned weak_flag : 1;
  
    unsigned no_instrument_function_entry_exit : 1;
    unsigned comdat_flag : 1;
    unsigned malloc_flag : 1;
    unsigned no_limit_stack : 1;
    ENUM_BITFIELD(built_in_class) built_in_class : 2;
    unsigned pure_flag : 1;
    unsigned non_addressable : 1;
+ 
    unsigned user_align : 1;
    unsigned uninlinable : 1;
    unsigned thread_local_flag : 1;
    unsigned declared_inline_flag : 1;
    ENUM_BITFIELD(symbol_visibility) visibility : 2;
    unsigned visibility_specified : 1;
    unsigned lang_flag_0 : 1;
+ 
    unsigned lang_flag_1 : 1;
    unsigned lang_flag_2 : 1;
    unsigned lang_flag_3 : 1;
*************** struct tree_decl GTY(())
*** 2405,2419 ****
    unsigned lang_flag_5 : 1;
    unsigned lang_flag_6 : 1;
    unsigned lang_flag_7 : 1;
- 
    unsigned possibly_inlined : 1;
    unsigned preserve_flag: 1;
    unsigned gimple_formal_temp : 1;
    unsigned debug_expr_is_from : 1;
    unsigned returns_twice_flag : 1;
    unsigned seen_in_bind_expr : 1;
    unsigned novops_flag : 1;
!   /* 9 unused bits.  */
  
    union tree_decl_u1 {
      /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
--- 2400,2414 ----
    unsigned lang_flag_5 : 1;
    unsigned lang_flag_6 : 1;
    unsigned lang_flag_7 : 1;
    unsigned possibly_inlined : 1;
+ 
    unsigned preserve_flag: 1;
    unsigned gimple_formal_temp : 1;
    unsigned debug_expr_is_from : 1;
    unsigned returns_twice_flag : 1;
    unsigned seen_in_bind_expr : 1;
    unsigned novops_flag : 1;
!   /* 10 unused bits.  */
  
    union tree_decl_u1 {
      /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.481
diff -c -3 -p -r1.481 tree.c
*** tree.c	25 May 2005 04:16:39 -0000	1.481
--- tree.c	26 May 2005 06:58:53 -0000
*************** staticp (tree arg)
*** 1614,1620 ****
      case VAR_DECL:
        return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
  	      && ! DECL_THREAD_LOCAL (arg)
! 	      && ! DECL_NON_ADDR_CONST_P (arg)
  	      ? arg : NULL);
  
      case CONST_DECL:
--- 1614,1620 ----
      case VAR_DECL:
        return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
  	      && ! DECL_THREAD_LOCAL (arg)
! 	      && ! targetm.decl_non_addr_const_p (arg)
  	      ? arg : NULL);
  
      case CONST_DECL:
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.428
diff -c -3 -p -r1.428 tm.texi
*** doc/tm.texi	25 May 2005 11:52:13 -0000	1.428
--- doc/tm.texi	26 May 2005 06:59:41 -0000
*************** This macro determines whether to use the
*** 9699,9701 ****
--- 9699,9709 ----
  classes. By default, TARGET_USE_JCR_SECTION is defined to 1 if both
  SUPPORTS_WEAK and TARGET_HAVE_NAMED_SECTIONS are true, else 0.
  @end defmac
+ 
+ @deftypefn {Target Hook} bool TARGET_DECL_NON_ADDR_CONST_P (tree@var{decl})
+ This target hook should return @code{true} if the pointer to the
+ function or variable @var{decl} cannot be treated as an address
+ constant.  On MS Windows targets, this returns @code{true} for symbols
+ that are imported from a dll via an indirect reference.  The default
+ version of this hook always returns @code{false}.
+ @end deftypefn
Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.138
diff -c -3 -p -r1.138 i386-protos.h
*** config/i386/i386-protos.h	24 Apr 2005 07:59:17 -0000	1.138
--- config/i386/i386-protos.h	26 May 2005 06:59:44 -0000
*************** extern void i386_pe_encode_section_info 
*** 244,251 ****
  extern const char *i386_pe_strip_name_encoding (const char *);
  extern const char *i386_pe_strip_name_encoding_full (const char *);
  extern void i386_pe_output_labelref (FILE *, const char *);
! extern rtx maybe_get_pool_constant (rtx);
  
  extern char internal_label_prefix[16];
  extern int internal_label_prefix_len;
  
--- 244,252 ----
  extern const char *i386_pe_strip_name_encoding (const char *);
  extern const char *i386_pe_strip_name_encoding_full (const char *);
  extern void i386_pe_output_labelref (FILE *, const char *);
! extern bool i386_pe_decl_non_addr_const_p (tree);
  
+ extern rtx maybe_get_pool_constant (rtx);
  extern char internal_label_prefix[16];
  extern int internal_label_prefix_len;
  
Index: config/i386/winnt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/winnt.c,v
retrieving revision 1.82
diff -c -3 -p -r1.82 winnt.c
*** config/i386/winnt.c	25 May 2005 04:16:57 -0000	1.82
--- config/i386/winnt.c	26 May 2005 06:59:44 -0000
*************** i386_pe_file_end (void)
*** 802,805 ****
--- 802,811 ----
      }
  }
  
+ bool
+ i386_pe_decl_non_addr_const_p (tree decl)
+ {
+   return  i386_pe_dllimport_p (decl);
+ }
+ 
  #include "gt-winnt.h"
Index: config/i386/cygming.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/cygming.h,v
retrieving revision 1.29
diff -c -3 -p -r1.29 cygming.h
*** config/i386/cygming.h	28 Apr 2005 05:38:37 -0000	1.29
--- config/i386/cygming.h	26 May 2005 06:59:46 -0000
*************** extern int i386_pe_dllimport_name_p (con
*** 403,408 ****
--- 403,411 ----
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ \
    { "selectany", 0, 0, true, false, false, ix86_handle_selectany_attribute }
  
+ #undef TARGET_DECL_NON_ADDR_CONST_P
+ #define TARGET_DECL_NON_ADDR_CONST_P i386_pe_decl_non_addr_const_p
+ 
  #undef TREE
  
  #ifndef BUFSIZ
Index: config/sh/sh-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh-protos.h,v
retrieving revision 1.62
diff -c -3 -p -r1.62 sh-protos.h
*** config/sh/sh-protos.h	13 May 2005 03:19:57 -0000	1.62
--- config/sh/sh-protos.h	26 May 2005 06:59:46 -0000
*************** extern int          symbian_import_expor
*** 178,183 ****
--- 178,184 ----
  #ifdef TREE_CODE
  extern bool         sh_symbian_dllexport_p            (tree);
  extern tree         sh_symbian_handle_dll_attribute   (tree *, tree, tree, int, bool *);
+ extern bool 	      sh_symbian_decl_non_addr_const_p  (tree);
  #ifdef RTX_CODE
  extern void         sh_symbian_encode_section_info    (tree, rtx, int);
  #endif
Index: config/sh/symbian.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/symbian.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 symbian.c
*** config/sh/symbian.c	25 May 2005 04:17:20 -0000	1.10
--- config/sh/symbian.c	26 May 2005 06:59:48 -0000
*************** sh_symbian_mark_dllexport (tree decl)
*** 233,239 ****
  	unit which has included the header in order to ensure argument
  	correctness.  */
        oldname += strlen (DLL_IMPORT_PREFIX);
-       DECL_NON_ADDR_CONST_P (decl) = 0;
      }
    else if (sh_symbian_dllexport_name_p (oldname))
      return; /* Already done.  */
--- 233,238 ----
*************** sh_symbian_encode_section_info (tree dec
*** 309,315 ****
    /* It might be that DECL has already been marked as dllimport, but a
       subsequent definition nullified that.  The attribute is gone but
       DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
!      that. Ditto for the DECL_NON_ADDR_CONST_P flag.  */
    else if (  (TREE_CODE (decl) == FUNCTION_DECL
  	   || TREE_CODE (decl) == VAR_DECL)
  	   && DECL_RTL (decl) != NULL_RTX
--- 308,314 ----
    /* It might be that DECL has already been marked as dllimport, but a
       subsequent definition nullified that.  The attribute is gone but
       DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
!      that.  */
    else if (  (TREE_CODE (decl) == FUNCTION_DECL
  	   || TREE_CODE (decl) == VAR_DECL)
  	   && DECL_RTL (decl) != NULL_RTX
*************** sh_symbian_encode_section_info (tree dec
*** 330,337 ****
  	       ? "defined locally" : "redeclared without dllimport attribute");
  
        XEXP (DECL_RTL (decl), 0) = newrtl;
- 
-       DECL_NON_ADDR_CONST_P (decl) = 0;
      }
  }
  
--- 329,334 ----
*************** symbian_import_export_class (tree ctype,
*** 872,877 ****
--- 869,882 ----
    return import_export;
  }
  
+ 
+ bool
+ sh_symbian_decl_non_addr_const_p (tree decl)
+ {
+   return sh_symbian_dllimport_p (decl);
+ }
+ 
+ 
  /* Dummy definition of this array for cc1 building purposes.  */
  tree cp_global_trees[CPTI_MAX] __attribute__((weak));
  
Index: config/sh/symbian-post.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/symbian-post.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 symbian-post.h
*** config/sh/symbian-post.h	12 Jul 2004 08:45:00 -0000	1.1
--- config/sh/symbian-post.h	26 May 2005 06:59:48 -0000
***************
*** 87,89 ****
--- 87,92 ----
  		   sh_symbian_strip_name_encoding (NAME));	\
      }								\
    while (0)
+ 
+ #undef TARGET_DECL_NON_ADDR_CONST_P
+ #define TARGET_DECL_NON_ADDR_CONST_P sh_symbian_decl_non_addr_const_p

Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com


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