[Committed] RE: [Patch]: PR target/27789 attribute handling fallout from DECL_INITIAL changes
Danny Smith
dannysmith@clear.net.nz
Fri Jun 23 09:39:00 GMT 2006
> -----Original Message-----
> From: Danny Smith
>
> > -----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
>
I have committed the patch.
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: cp/decl.c
===================================================================
*** cp/decl.c (revision 114912)
--- cp/decl.c (working copy)
*************** start_decl (const cp_declarator *declara
*** 3873,3878 ****
--- 3873,3888 ----
/* 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: config/i386/winnt.c
===================================================================
*** config/i386/winnt.c (revision 114912)
--- 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: testsuite/g++.dg/ext/dllimport4.C
===================================================================
*** testsuite/g++.dg/ext/dllimport4.C (revision 114912)
--- 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" }
+
More information about the Gcc-patches
mailing list