aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-06-02 00:03:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2012-06-02 00:03:51 -0400
commite3c888eb0e3923981bcb914f818c29a054843d9e (patch)
treea1f209f8b5712f177fbfcf89cb917f57e6dea548 /gcc
parentb691f14cc4a69541ff6915b8d0d102bb5f0b3451 (diff)
downloadgcc-e3c888eb0e3923981bcb914f818c29a054843d9e.zip
gcc-e3c888eb0e3923981bcb914f818c29a054843d9e.tar.gz
gcc-e3c888eb0e3923981bcb914f818c29a054843d9e.tar.bz2
re PR c++/52973 (visibility attribute for class is not passed to its members)
PR c++/52973 * parser.c (cp_parser_class_head): Apply attributes here. * semantics.c (begin_class_definition): Not here. * cp-tree.h: Adjust. From-SVN: r188137
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/parser.c15
-rw-r--r--gcc/cp/semantics.c7
-rw-r--r--gcc/objcp/ChangeLog5
-rw-r--r--gcc/objcp/objcp-decl.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib14.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/template12.C13
9 files changed, 43 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ba5937a..b094504 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2012-06-01 Jason Merrill <jason@redhat.com>
+ PR c++/52973
+ * parser.c (cp_parser_class_head): Apply attributes here.
+ * semantics.c (begin_class_definition): Not here.
+ * cp-tree.h: Adjust.
+
PR c++/52725
* parser.c (cp_parser_binary_expression): Bail early if we're parsing
tentatively and the LHS has a parse error.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 626c61f..d21c2bf 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5585,7 +5585,7 @@ extern tree finish_fname (tree);
extern void finish_translation_unit (void);
extern tree finish_template_type_parm (tree, tree);
extern tree finish_template_template_parm (tree, tree);
-extern tree begin_class_definition (tree, tree);
+extern tree begin_class_definition (tree);
extern void finish_template_decl (tree);
extern tree finish_template_type (tree, tree, int);
extern tree finish_base_specifier (tree, tree, bool);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7f9a94b..16139d6 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2008,7 +2008,7 @@ static tree cp_parser_class_name
static tree cp_parser_class_specifier
(cp_parser *);
static tree cp_parser_class_head
- (cp_parser *, bool *, tree *, tree *);
+ (cp_parser *, bool *, tree *);
static enum tag_types cp_parser_class_key
(cp_parser *);
static void cp_parser_member_specification_opt
@@ -17908,7 +17908,6 @@ cp_parser_class_specifier_1 (cp_parser* parser)
/* Parse the class-head. */
type = cp_parser_class_head (parser,
&nested_name_specifier_p,
- &attributes,
&bases);
/* If the class-head was a semantic disaster, skip the entire body
of the class. */
@@ -17967,7 +17966,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
old_scope = push_inner_scope (scope);
}
- type = begin_class_definition (type, attributes);
+ type = begin_class_definition (type);
if (type == error_mark_node)
/* If the type is erroneous, skip the entire body of the class. */
@@ -18224,7 +18223,6 @@ cp_parser_class_specifier (cp_parser* parser)
static tree
cp_parser_class_head (cp_parser* parser,
bool* nested_name_specifier_p,
- tree *attributes_p,
tree *bases)
{
tree nested_name_specifier;
@@ -18592,6 +18590,14 @@ cp_parser_class_head (cp_parser* parser,
else if (type == error_mark_node)
type = NULL_TREE;
+ if (type)
+ {
+ /* Apply attributes now, before any use of the class as a template
+ argument in its base list. */
+ cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
+ fixup_attribute_variants (type);
+ }
+
/* We will have entered the scope containing the class; the names of
base classes should be looked up in that context. For example:
@@ -18618,7 +18624,6 @@ cp_parser_class_head (cp_parser* parser,
if (type)
DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
- *attributes_p = attributes;
if (type && (virt_specifiers & VIRT_SPEC_FINAL))
CLASSTYPE_FINAL (type) = 1;
out:
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 263ebc2..8fefce0 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2516,7 +2516,7 @@ check_template_template_default_arg (tree argument)
/* Begin a class definition, as indicated by T. */
tree
-begin_class_definition (tree t, tree attributes)
+begin_class_definition (tree t)
{
if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
return error_mark_node;
@@ -2573,9 +2573,6 @@ begin_class_definition (tree t, tree attributes)
pushclass (t);
TYPE_BEING_DEFINED (t) = 1;
- cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
- fixup_attribute_variants (t);
-
if (flag_pack_struct)
{
tree v;
@@ -8696,7 +8693,7 @@ begin_lambda_type (tree lambda)
xref_basetypes (type, /*bases=*/NULL_TREE);
/* Start the class. */
- type = begin_class_definition (type, /*attributes=*/NULL_TREE);
+ type = begin_class_definition (type);
if (type == error_mark_node)
return error_mark_node;
diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog
index bed3b9d..28b52e8 100644
--- a/gcc/objcp/ChangeLog
+++ b/gcc/objcp/ChangeLog
@@ -1,3 +1,8 @@
+2012-06-02 Jason Merrill <jason@redhat.com>
+
+ * objcp-decl.c (objcp_start_struct): Adjust for change in
+ begin_class_definition prototype.
+
2011-10-14 Nicola Pero <nicola.pero@meta-innovation.com>
* Make-lang.in (OBJCXX_OBJS): Added objc-map.o.
diff --git a/gcc/objcp/objcp-decl.c b/gcc/objcp/objcp-decl.c
index ecc2b2b..8040469 100644
--- a/gcc/objcp/objcp-decl.c
+++ b/gcc/objcp/objcp-decl.c
@@ -49,7 +49,7 @@ objcp_start_struct (location_t loc ATTRIBUTE_UNUSED,
CLASSTYPE_DECLARED_CLASS (s) = 0; /* this is a 'struct', not a 'class'. */
xref_basetypes (s, NULL_TREE); /* no base classes here! */
- return begin_class_definition (s, NULL_TREE);
+ return begin_class_definition (s);
}
tree
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dd1c651..3d0b249 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2012-06-01 Jason Merrill <jason@redhat.com>
+ PR c++/52973
+ * g++.dg/ext/visibility/template12.C: New.
+ * g++.dg/ext/attrib14.C: Adjust warning line.
+
PR c++/52725
* g++.dg/parse/new6.C: New.
* g++.dg/template/sizeof-template-argument.C: Adjust error message.
diff --git a/gcc/testsuite/g++.dg/ext/attrib14.C b/gcc/testsuite/g++.dg/ext/attrib14.C
index c7e5f7a..ebe0456 100644
--- a/gcc/testsuite/g++.dg/ext/attrib14.C
+++ b/gcc/testsuite/g++.dg/ext/attrib14.C
@@ -2,8 +2,8 @@
// The bogus attribute is ignored, but was in TYPE_ATTRIBUTES during
// parsing of the class, causing some variants to have it and some not.
-struct __attribute__((bogus)) A
-{ // { dg-warning "ignored" "" }
+struct __attribute__((bogus)) A // { dg-warning "ignored" "" }
+{
virtual ~A();
void foo(const A&);
void bar(const A&);
diff --git a/gcc/testsuite/g++.dg/ext/visibility/template12.C b/gcc/testsuite/g++.dg/ext/visibility/template12.C
new file mode 100644
index 0000000..b9219d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/template12.C
@@ -0,0 +1,13 @@
+// { dg-require-visibility "" }
+// { dg-options "-fvisibility=hidden" }
+// { dg-final { scan-not-hidden "_ZN1aI1bE1cE" } }
+
+template <class T> class __attribute__((visibility("default"))) a
+{
+public:
+ /* A */ static int c;
+};
+
+class __attribute__((visibility("default"))) b : a <b> {};
+
+template<> /* B */ int a<b>::c = 0;