summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-29 07:49:15 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-29 07:49:15 +0000
commit6d8d47f68385ff6412b43a210e5672c844d6f946 (patch)
tree40968ed42dfe1d67b0df42c1ad2ffb77fa8ddcd2
parente786f4523119cfbda81da83fde7720ed6a83bdca (diff)
downloadgcc-6d8d47f68385ff6412b43a210e5672c844d6f946.tar.gz
cp/
* parser.c (cp_parser_member_declaration): Parse attributes before colon of a bitfield in addition to after colon. testsuite/ * g++.dg/ext/bitfield7.C: New test. * g++.dg/ext/bitfield8.C: New test. * g++.dg/ext/bitfield9.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253281 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/parser.c55
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/ext/bitfield7.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/bitfield8.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/bitfield9.C10
6 files changed, 85 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6a4d28315e9..95110b87c3c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2017-09-29 Jakub Jelinek <jakub@redhat.com>
+ * parser.c (cp_parser_member_declaration): Parse attributes before
+ colon of a bitfield in addition to after colon.
+
* Make-lang.in (check-c++-all): Test also c++2a.
2017-09-28 Jason Merrill <jason@redhat.com>
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f22c2c091dc..71c27a40ce2 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -23445,35 +23445,68 @@ cp_parser_member_declaration (cp_parser* parser)
{
tree attributes = NULL_TREE;
tree first_attribute;
+ bool is_bitfld = false;
+ bool named_bitfld = false;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
+ /* The following code wants to know early if it is a bit-field
+ or some other declaration. Attributes can appear before
+ the `:' token, but are hopefully rare enough that the
+ simplicity of the tentative lookup pays off. */
+ if (cp_next_tokens_can_be_attribute_p (parser)
+ || (token->type == CPP_NAME
+ && cp_nth_tokens_can_be_attribute_p (parser, 2)
+ && (named_bitfld = true)))
+ {
+ cp_parser_parse_tentatively (parser);
+ if (named_bitfld)
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_attributes_opt (parser);
+ token = cp_lexer_peek_token (parser->lexer);
+ is_bitfld = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
+ cp_parser_abort_tentative_parse (parser);
+ }
+
/* Check for a bitfield declaration. */
- if (token->type == CPP_COLON
+ if (is_bitfld
+ || token->type == CPP_COLON
|| (token->type == CPP_NAME
- && cp_lexer_peek_nth_token (parser->lexer, 2)->type
- == CPP_COLON))
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON)
+ && (named_bitfld = true)))
{
tree identifier;
tree width;
+ tree late_attributes = NULL_TREE;
- /* Get the name of the bitfield. Note that we cannot just
- check TOKEN here because it may have been invalidated by
- the call to cp_lexer_peek_nth_token above. */
- if (cp_lexer_peek_token (parser->lexer)->type != CPP_COLON)
+ if (named_bitfld)
identifier = cp_parser_identifier (parser);
else
identifier = NULL_TREE;
+ /* Look for attributes that apply to the bitfield. */
+ attributes = cp_parser_attributes_opt (parser);
+
/* Consume the `:' token. */
cp_lexer_consume_token (parser->lexer);
+
/* Get the width of the bitfield. */
- width
- = cp_parser_constant_expression (parser);
+ width = cp_parser_constant_expression (parser);
+
+ /* Look for attributes that apply to the bitfield after
+ the `:' token and width. This is where GCC used to
+ parse attributes in the past, pedwarn if there is
+ a std attribute. */
+ if (cp_next_tokens_can_be_std_attribute_p (parser))
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ allows bit-field attributes only before "
+ "the %<:%> token");
+
+ late_attributes = cp_parser_attributes_opt (parser);
+
+ attributes = chainon (attributes, late_attributes);
- /* Look for attributes that apply to the bitfield. */
- attributes = cp_parser_attributes_opt (parser);
/* Remember which attributes are prefix attributes and
which are not. */
first_attribute = attributes;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e0eade336b3..0d637c8deab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2017-09-29 Jakub Jelinek <jakub@redhat.com>
+ * g++.dg/ext/bitfield7.C: New test.
+ * g++.dg/ext/bitfield8.C: New test.
+ * g++.dg/ext/bitfield9.C: New test.
+
PR c/82340
* gcc.dg/tree-ssa/pr82340.c: New test.
diff --git a/gcc/testsuite/g++.dg/ext/bitfield7.C b/gcc/testsuite/g++.dg/ext/bitfield7.C
new file mode 100644
index 00000000000..4efc9bf2d04
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/bitfield7.C
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target { i?86-*-mingw* x86_64-*-mingw* } } } */
+
+struct t /* { dg-message "note: offset of packed bit-field 't::b' has changed in GCC 4.4" "" { target pcc_bitfield_type_matters } } */
+{
+ char a:4;
+ char b __attribute__ ((packed)) : 8;
+ char c:4;
+};
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/g++.dg/ext/bitfield8.C b/gcc/testsuite/g++.dg/ext/bitfield8.C
new file mode 100644
index 00000000000..688b28988f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/bitfield8.C
@@ -0,0 +1,12 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "" } */
+/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target { i?86-*-mingw* x86_64-*-mingw* } } } */
+
+struct t /* { dg-message "note: offset of packed bit-field 't::b' has changed in GCC 4.4" "" { target pcc_bitfield_type_matters } } */
+{
+ char a:4;
+ char b [[gnu::packed]] : 8;
+ char c:4;
+};
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/g++.dg/ext/bitfield9.C b/gcc/testsuite/g++.dg/ext/bitfield9.C
new file mode 100644
index 00000000000..4a4ebf23c1f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/bitfield9.C
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic" }
+
+struct S
+{
+ char a:4;
+ char b:8 alignas(int); // { dg-warning "ISO C\\+\\+ allows bit-field attributes only before the ':' token" }
+ char c:8 [[gnu::aligned(8)]]; // { dg-warning "ISO C\\+\\+ allows bit-field attributes only before the ':' token" }
+ // { dg-error "two consecutive '\\\[' shall only introduce an attribute before '\\\[' token" "" { target *-*-* } .-1 }
+};