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)
+               {
+                 /* 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" }
+};

Reply via email to