PR c++/92215 - flawed diagnostic for bit-field with non-integral type.
authorMarek Polacek <polacek@redhat.com>
Fri, 8 Nov 2019 21:48:47 +0000 (21:48 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 8 Nov 2019 21:48:47 +0000 (21:48 +0000)
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;

* parser.c (cp_parser_member_declaration): Add a diagnostic for
bit-fields with non-integral types.

* g++.dg/diagnostic/bitfld4.C: New test.

From-SVN: r277991

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/diagnostic/bitfld4.C [new file with mode: 0644]

index 2104a750f08517425a066eb5f3bf24c2b5e0fde8..170ce30e7a5c7bbeedd4afdaa29a7f20030a2bd2 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-08  Marek Polacek  <polacek@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.
+
 2019-11-08  Jakub Jelinek  <jakub@redhat.com>
 
        * init.c (build_vec_delete_1): Fix a comment typo - mist -> must.
index 7138aebebced53b0d36f00703c66811c02110b8c..1c95d7e9a5aff1085a1654206eb0e5d51ddd7fe2 100644 (file)
@@ -25037,6 +25037,31 @@ 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)
+                      /* If there were no type specifiers, it was a
+                         constructor.  */
+                      && 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;
index cafb7814f744ae12c27787d9d073bf16a84ca896..83145ae68055de64b369d8166a3aac91a973bea3 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-08  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/92215 - flawed diagnostic for bit-field with non-integral type.
+       * g++.dg/diagnostic/bitfld4.C: New test.
+
 2019-11-08  Marek Polacek  <polacek@redhat.com>
 
        PR c++/92058 - constinit malfunction in static data member.
diff --git a/gcc/testsuite/g++.dg/diagnostic/bitfld4.C b/gcc/testsuite/g++.dg/diagnostic/bitfld4.C
new file mode 100644 (file)
index 0000000..d6aa9a5
--- /dev/null
@@ -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" }
+};