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]

RE: [Patch]: PR target/27789 attribute handling fallout from DECL_INITIAL changes



> -----Original Message-----
> From: Mark Mitchell  Sent: Friday, June 09, 2006 6:19 AM
> 
> Danny Smith wrote:
> 
> 
> > if we wait until then In order to ensure that the 
> initialization of a 
> > dllmport always outputs an error message, I have added a check for 
> > initialization in cp/decl.c:start_decl, right after we 
> handle the decl 
> > attributes.
> 
> Will this cause problems with the static data member case you 
> mentioned earlier?  Or, do those go through grokfield, rather 
> than start_decl?

It does not cause problems for the reason you indicate. I have added a
comment
to start_decl to that effect.

I have also commented the addition to g++.dg/ext/dllimport4.C testcase
which
checks the static member case.

> 
> > +  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl)
> > +      && initialized)
> 
> Why check TARGET_DLLIMPORT_DECL_ATTRIBUTES here?  I would just say
> 
>   (initialized && DECL_DLLIMPORT_P (decl))
> 

OK

> With that minor tweak, and assuming static data members work, 
> the C++ change is OK.

Chris, do you have any concerns about the changes to winnt.c?


> 
> -- 
> Mark Mitchell

Danny

Changelog

	PR target/27789

	* config/i386/winnt.c (ix86_handle_selectany_attribute): Move
check
        for initialization and setting of one_only flag to ...
	(i386_pe_encode_section_info): ...here.
	(i386_pe_dllimport_p): Check for DECL_DLLIMPORT_P also.
	Recheck that the symbol has not been defined.

cp/Changelog

	* decl.c (start_decl): Check that dllimports are not
initialized.


testsuite/Changelog

	* g++.dg/ext/dllimport4.C. Add more tests for invalid
initialization.


Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c	(revision 114499)
--- gcc/cp/decl.c	(working copy)
*************** start_decl (const cp_declarator *declara
*** 3850,3855 ****
--- 3850,3865 ----
    /* Set attributes here so if duplicate decl, will have proper
attributes.  */
    cplus_decl_attributes (&decl, attributes, 0);
  
+   /* Dllimported symbols cannot be defined.  Static data members
(which
+      can be initialized in-class and dllimported) go through
grokfield,
+      not here, so we don't need to exclude those decls when checking
for
+      a definition.  */
+   if (initialized && DECL_DLLIMPORT_P (decl))
+     {
+       error ("definition of %q#D is marked %<dllimport%>", decl);
+       DECL_DLLIMPORT_P (decl) = 0;
+     }
+ 
    /* If #pragma weak was used, mark the decl weak now.  */
    maybe_apply_pragma_weak (decl);
Index: gcc/config/i386/winnt.c
===================================================================
*** gcc/config/i386/winnt.c	(revision 114499)
--- gcc/config/i386/winnt.c	(working copy)
***************
*** 1,7 ****
  /* 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, 2004,
2005
!    Free Software Foundation, Inc.
  
  This file is part of GCC.
  
--- 1,7 ----
  /* 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, 2004,
!    2005, 2006  Free Software Foundation, Inc.
  
  This file is part of GCC.
  
*************** ix86_handle_selectany_attribute (tree *n
*** 88,104 ****
  				 bool *no_add_attrs)
  {
    /* The attribute applies only to objects that are initialized and
have
!      external linkage,  */	
!   if (TREE_CODE (*node) == VAR_DECL && TREE_PUBLIC (*node)
!       && (DECL_INITIAL (*node)
!           /* If an object is initialized with a ctor, the static
! 	     initialization and destruction code for it is present in
! 	     each unit defining the object.  The code that calls the
! 	     ctor is protected by a link-once guard variable, so that
! 	     the object still has link-once semantics,  */
!     	  || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (*node))))
!     make_decl_one_only (*node);
!   else
      {	
        error ("%qs attribute applies only to initialized variables"
         	     " with external linkage",  IDENTIFIER_POINTER
(name));
--- 88,97 ----
  				 bool *no_add_attrs)
  {
    /* The attribute applies only to objects that are initialized and
have
!      external linkage.  However, we may not know about initialization
!      until the language frontend has processed the decl. We'll check
for
!      initialization later in encode_section_info.  */	
!   if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
      {	
        error ("%qs attribute applies only to initialized variables"
         	     " with external linkage",  IDENTIFIER_POINTER
(name));
*************** i386_pe_dllimport_p (tree decl)
*** 148,165 ****
         && TREE_CODE (decl) != FUNCTION_DECL)
      return false;
  
!   /* Lookup the attribute rather than rely on the DECL_DLLIMPORT_P
flag.
       We may need to override an earlier decision.  */
!   if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)))
!     return true;
! 
    /* The DECL_DLLIMPORT_P flag was set for decls in the class
definition
       by  targetm.cxx.adjust_class_at_definition.  Check again to emit
       warnings if the class attribute has been overridden by an
       out-of-class definition.  */
!   if (associated_type (decl)
!       && lookup_attribute ("dllimport",
! 			    TYPE_ATTRIBUTES (associated_type (decl))))
      return i386_pe_type_dllimport_p (decl);
  
    return false;
--- 141,168 ----
         && TREE_CODE (decl) != FUNCTION_DECL)
      return false;
  
!   /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P
flag.
       We may need to override an earlier decision.  */
!   if (DECL_DLLIMPORT_P (decl)
!       && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)))
!     {
!        /* Make a final check to see if this is a definition before we
generate
!           RTL for an indirect reference.  */   
!        if (!DECL_EXTERNAL (decl))
! 	{
! 	  error ("%q+D: definition is marked as dllimport", decl);
! 	  DECL_DLLIMPORT_P (decl) = 0;
!           return false;
!         }
!       return true;
!     }
    /* The DECL_DLLIMPORT_P flag was set for decls in the class
definition
       by  targetm.cxx.adjust_class_at_definition.  Check again to emit
       warnings if the class attribute has been overridden by an
       out-of-class definition.  */
!   else if (associated_type (decl)
!            && lookup_attribute ("dllimport",
! 				TYPE_ATTRIBUTES (associated_type
(decl))))
      return i386_pe_type_dllimport_p (decl);
  
    return false;
*************** i386_pe_encode_section_info (tree decl, 
*** 362,367 ****
--- 365,386 ----
  	}
      }
  
+   else if (TREE_CODE (decl) == VAR_DECL
+            && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
+     {
+       if (DECL_INITIAL (decl)
+  	  /* If an object is initialized with a ctor, the static
+ 	     initialization and destruction code for it is present in
+ 	     each unit defining the object.  The code that calls the
+ 	     ctor is protected by a link-once guard variable, so that
+ 	     the object still has link-once semantics,  */
+     	   || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
+ 	make_decl_one_only (decl);
+       else
+ 	error ("%q+D:'selectany' attribute applies only to initialized
objects",
+ 	       decl);
+     }
+ 
    /* Mark the decl so we can tell from the rtl whether the object is
       dllexport'd or dllimport'd.  tree.c:
merge_dllimport_decl_attributes
       handles dllexport/dllimport override semantics.  */
Index: gcc/testsuite/g++.dg/ext/dllimport4.C
===================================================================
*** gcc/testsuite/g++.dg/ext/dllimport4.C	(revision 114499)
--- gcc/testsuite/g++.dg/ext/dllimport4.C	(working copy)
***************
*** 4,6 ****
--- 4,38 ----
  __attribute__((dllimport))  void bar () { }	// { dg-error
"definition" }
  
  __attribute__((dllimport))  int foo = 1;	// { dg-error
"definition" }
+ 
+ void faz()
+ {
+   __attribute__((dllimport)) int faa = 1;	// { dg-error
"definition" }
+   faa++; 
+ }
+ 
+ __attribute__((dllimport)) int fee (1);		// { dg-error
"definition" }
+ 
+ 
+ // In-class initialization of a static data member is not a
definition.  
+ struct  F
+ {
+   __attribute__ ((dllimport)) static const int i = 1;  // OK
+ };
+ 
+ // Reference the dllimport'd static data member.
+ void f ()
+ {
+   const int* j = &F::i;
+ }
+ 
+ struct  G
+ {
+   __attribute__ ((dllimport)) static const int i = 1;
+ };
+ 
+ // Define the static data member _without_ the dllimport.
+ // This should override the prior declaration with dllimport.
+ 
+ const int G::i;		//  { dg-warning "dllimport ignored" }
+ 


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