From: Marek Polacek Date: Fri, 8 Nov 2019 21:48:47 +0000 (+0000) Subject: PR c++/92215 - flawed diagnostic for bit-field with non-integral type. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=65471f09e9f0b192927ca980c2676044209adbba;p=gcc.git PR c++/92215 - flawed diagnostic for bit-field with non-integral type. 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2104a750f08..170ce30e7a5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-11-08 Marek Polacek + + 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 * init.c (build_vec_delete_1): Fix a comment typo - mist -> must. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7138aebebce..1c95d7e9a5a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cafb7814f74..83145ae6805 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-11-08 Marek Polacek + + PR c++/92215 - flawed diagnostic for bit-field with non-integral type. + * g++.dg/diagnostic/bitfld4.C: New test. + 2019-11-08 Marek Polacek 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 index 00000000000..d6aa9a5513c --- /dev/null +++ b/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" } +};