diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6756a73fc78..8406d5f6062 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2007-06-23 Mark Mitchell + + * doc/extend.texi: Document that dllimport and dllexport imply + default visibility. + * tree.c (handle_dll_attribute): Set DECL_VISIBILITY on the + imported or exported declaration, including type declarations. + * c-common.c (handle_visibility_attribute): Check for conflicts + with dllimport/dllexport. + (c_determine_visibility): Handle dllimport/dllexport as an + explicit visibility atttribute. + 2007-06-23 Richard Guenther PR tree-optimization/16876 diff --git a/gcc/c-common.c b/gcc/c-common.c index 9bad32d637a..e1c38750204 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -5419,11 +5419,22 @@ handle_visibility_attribute (tree *node, tree name, tree args, } if (DECL_VISIBILITY_SPECIFIED (decl) - && vis != DECL_VISIBILITY (decl) - && lookup_attribute ("visibility", (TYPE_P (*node) - ? TYPE_ATTRIBUTES (*node) - : DECL_ATTRIBUTES (decl)))) - error ("%qD redeclared with different visibility", decl); + && vis != DECL_VISIBILITY (decl)) + { + tree attributes = (TYPE_P (*node) + ? TYPE_ATTRIBUTES (*node) + : DECL_ATTRIBUTES (decl)); + if (lookup_attribute ("visibility", attributes)) + error ("%qD redeclared with different visibility", decl); + else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES + && lookup_attribute ("dllimport", attributes)) + error ("%qD was declared %qs which implies default visibility", + decl, "dllimport"); + else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES + && lookup_attribute ("dllexport", attributes)) + error ("%qD was declared %qs which implies default visibility", + decl, "dllexport"); + } DECL_VISIBILITY (decl) = vis; DECL_VISIBILITY_SPECIFIED (decl) = 1; @@ -5456,18 +5467,12 @@ c_determine_visibility (tree decl) to distinguish the use of an attribute from the use of a "#pragma GCC visibility push(...)"; in the latter case we still want other considerations to be able to overrule the #pragma. */ - if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl))) + if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)) + || (TARGET_DLLIMPORT_DECL_ATTRIBUTES + && (lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)) + || lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))))) return true; - /* Anything that is exported must have default visibility. */ - if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) - { - DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; - DECL_VISIBILITY_SPECIFIED (decl) = 1; - return true; - } - /* Set default visibility to whatever the user supplied with visibility_specified depending on #pragma GCC visibility. */ if (!DECL_VISIBILITY_SPECIFIED (decl)) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 609b80cb31d..951faf4af49 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2007-06-23 Mark Mitchell + + * decl2.c (determine_visibility): Don't look for dllexport here. + (determine_visibility_from_class): Tidy. + 2007-06-18 Simon Baldwin PR c++/31923 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 52953b2fa0c..b745183f1af 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1684,17 +1684,6 @@ determine_visibility (tree decl) else use_template = 0; - /* Anything that is exported must have default visibility. */ - if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && lookup_attribute ("dllexport", - TREE_CODE (decl) == TYPE_DECL - ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) - : DECL_ATTRIBUTES (decl))) - { - DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; - DECL_VISIBILITY_SPECIFIED (decl) = 1; - } - /* If DECL is a member of a class, visibility specifiers on the class can influence the visibility of the DECL. */ if (DECL_CLASS_SCOPE_P (decl)) @@ -1796,18 +1785,20 @@ determine_visibility (tree decl) static void determine_visibility_from_class (tree decl, tree class_type) { + if (DECL_VISIBILITY_SPECIFIED (decl)) + return; + if (visibility_options.inlines_hidden /* Don't do this for inline templates; specializations might not be inline, and we don't want them to inherit the hidden visibility. We'll set it here for all inline instantiations. */ && !processing_template_decl - && ! DECL_VISIBILITY_SPECIFIED (decl) && TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) && (! DECL_LANG_SPECIFIC (decl) || ! DECL_EXPLICIT_INSTANTIATION (decl))) DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; - else if (!DECL_VISIBILITY_SPECIFIED (decl)) + else { /* Default to the class visibility. */ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); @@ -1826,7 +1817,6 @@ determine_visibility_from_class (tree decl, tree class_type) && !DECL_CONSTRUCTION_VTABLE_P (decl))) && TREE_PUBLIC (decl) && !DECL_REALLY_EXTERN (decl) - && !DECL_VISIBILITY_SPECIFIED (decl) && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)) targetm.cxx.determine_class_data_visibility (decl); } diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index c957757be10..76cc546fac6 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1782,10 +1782,8 @@ You can use @code{__declspec(dllexport)} as a synonym for compilers. On systems that support the @code{visibility} attribute, this -attribute also implies ``default'' visibility, unless a -@code{visibility} attribute is explicitly specified. You should avoid -the use of @code{dllexport} with ``hidden'' or ``internal'' -visibility; in the future GCC may issue an error for those cases. +attribute also implies ``default'' visibility. It is an error to +explicitly specify any other visibility. Currently, the @code{dllexport} attribute is ignored for inlined functions, unless the @option{-fkeep-inline-functions} flag has been @@ -1806,14 +1804,18 @@ the @option{--export-all} linker flag. On Microsoft Windows and Symbian OS 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 DLL exporting the -symbol. The attribute implies @code{extern} storage. On Microsoft -Windows targets, the pointer name is formed by combining @code{_imp__} -and the function or variable name. +symbol. The attribute implies @code{extern}. On Microsoft Windows +targets, the pointer name is formed by combining @code{_imp__} and the +function or variable name. You can use @code{__declspec(dllimport)} as a synonym for @code{__attribute__ ((dllimport))} for compatibility with other compilers. +On systems that support the @code{visibility} attribute, this +attribute also implies ``default'' visibility. It is an error to +explicitly specify any other visibility. + Currently, the attribute is ignored for inlined functions. If the attribute is applied to a symbol @emph{definition}, an error is reported. If a symbol previously declared @code{dllimport} is later defined, the diff --git a/gcc/fold-const.c b/gcc/fold-const.c index eaf637cc02c..cd8d386e11f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14237,9 +14237,9 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) return constant_boolean_node (result, type); } -/* Build an expression for the a clean point containing EXPR with type TYPE. - Don't build a cleanup point expression for EXPR which don't have side - effects. */ +/* If necessary, return a CLEANUP_POINT_EXPR for EXPR with the + indicated TYPE. If no CLEANUP_POINT_EXPR is necessary, return EXPR + itself. */ tree fold_build_cleanup_point_expr (tree type, tree expr) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index abdb62fa634..5fbc1331cb2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2007-06-23 Mark Mitchell + + * gcc.dg/visibility-12.c: New test. + * gcc.dg/visibility-13.c: Likewise. + * g++.dg/ext/visibility-9.C: Likewise. + * g++.dg/ext/visibility-10.C: Likewise. + 2007-06-23 Richard Guenther PR tree-optimization/16876 diff --git a/gcc/tree.c b/gcc/tree.c index 45e53ccda4b..f70a3073a21 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4001,18 +4001,25 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags, *no_add_attrs = true; return tree_cons (name, args, NULL_TREE); } - if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE) + if (TREE_CODE (node) == RECORD_TYPE + || TREE_CODE (node) == UNION_TYPE) + { + node = TYPE_NAME (node); + if (!node) + return NULL_TREE; + } + else { warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name)); *no_add_attrs = true; + return NULL_TREE; } - - return NULL_TREE; } if (TREE_CODE (node) != FUNCTION_DECL - && TREE_CODE (node) != VAR_DECL) + && TREE_CODE (node) != VAR_DECL + && TREE_CODE (node) != TYPE_DECL) { *no_add_attrs = true; warning (OPT_Wattributes, "%qs attribute ignored", @@ -4075,6 +4082,22 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags, *no_add_attrs = true; } + /* A dllexport'd entity must have default visibility so that other + program units (shared libraries or the main executable) can see + it. A dllimport'd entity must have default visibility so that + the linker knows that undefined references within this program + unit can be resolved by the dynamic linker. */ + if (!*no_add_attrs) + { + if (DECL_VISIBILITY_SPECIFIED (node) + && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT) + error ("%qs implies default visibility, but %qD has already " + "been declared with a different visibility", + IDENTIFIER_POINTER (name), node); + DECL_VISIBILITY (node) = VISIBILITY_DEFAULT; + DECL_VISIBILITY_SPECIFIED (node) = 1; + } + return NULL_TREE; }