On 10/24/19 5:50 PM, Marek Polacek wrote:
I noticed that for code like
struct S {
int *foo : 3;
};
we generate nonsensical
r.C:2:8: error: function definition does not declare parameters
2 | int *foo : 3;
It talks about a function because after parsing the declspecs of 'foo' we don't
see either ':' or "name :", so we think it's not a bit-field decl. So we parse
the declarator and since a ctor-initializer begins with a ':', we try to parse
it as a function body, generating the awful diagnostic. With this patch, we
issue:
r.C:2:8: error: bit-field ‘foo’ has non-integral type ‘int*’
2 | int *foo : 3;
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2019-10-24 Marek Polacek <pola...@redhat.com>
PR c++/92215 - flawed diagnostic for bit-field with non-integral type.
* parser.c (cp_parser_member_declaration): Add a diagnostic for
bit-fields with non-integral types.
* g++.dg/diagnostic/bitfld4.C: New test.
diff --git gcc/cp/parser.c gcc/cp/parser.c
index 3857fe47d67..84d2121cae2 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -24971,6 +24971,29 @@ cp_parser_member_declaration (cp_parser* parser)
else
initializer = cp_parser_initializer (parser, &x, &x);
}
+ /* Detect invalid bit-field cases such as
+
+ int *p : 4;
+ int &&r : 3;
+
+ and similar. */
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
+ && decl_specifiers.any_type_specifiers_p)
Please add a comment that you're checking any_type_specifiers_p to
exclude constructors. OK with that change.
+ {
+ /* This is called for a decent diagnostic only. */
+ tree d = grokdeclarator (declarator, &decl_specifiers,
+ BITFIELD, /*initialized=*/false,
+ &attributes);
+ error_at (DECL_SOURCE_LOCATION (d),
+ "bit-field %qD has non-integral type %qT",
+ d, TREE_TYPE (d));
+ cp_parser_skip_to_end_of_statement (parser);
+ /* Avoid "extra ;" pedwarns. */
+ if (cp_lexer_next_token_is (parser->lexer,
+ CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ goto out;
+ }
/* Otherwise, there is no initializer. */
else
initializer = NULL_TREE;
diff --git gcc/testsuite/g++.dg/diagnostic/bitfld4.C
gcc/testsuite/g++.dg/diagnostic/bitfld4.C
new file mode 100644
index 00000000000..d6aa9a5513c
--- /dev/null
+++ gcc/testsuite/g++.dg/diagnostic/bitfld4.C
@@ -0,0 +1,16 @@
+// PR c++/92215 - flawed diagnostic for bit-field with non-integral type.
+// { dg-do compile { target c++11 } }
+
+struct S {
+ int *f1 : 3; // { dg-error "bit-field .f1. has non-integral type .int\\*." }
+ int &f2 : 3; // { dg-error "bit-field .f2. has non-integral type .int&." }
+ int &&f3 : 3; // { dg-error "bit-field .f3. has non-integral type .int&&." }
+ int f4[1] : 3; // { dg-error "bit-field .f4. has non-integral type .int
\\\[1\\\]." }
+ int *f5 __attribute__((deprecated)) : 3; // { dg-error "bit-field .f5. has
non-integral type .int\\*." }
+ int f6[1] __attribute__((deprecated)) : 3; // { dg-error "bit-field .f6. has
non-integral type .int \\\[1\\\]." }
+ int &f7 __attribute__((deprecated)): 3; // { dg-error "bit-field .f7. has
non-integral type .int&." }
+ int ****: 3; // { dg-error "expected" }
+ int *f9[1] : 3; // { dg-error "bit-field .f9. has non-integral type .int\\*
\\\[1\\\]." }
+ int (*f10)() : 3; // { dg-error "bit-field .f10. has non-integral type .int
\\(\\*\\)\\(\\)." }
+ int [][2] : 3; // { dg-error "expected" }
+};