Hi, I'm bundling together 3 more. In attachment order:
1- Since we decided to explicitly print the wrong type, I suppose we want to consistently do that in templates too.
2- Unfortunately I have to fix another buglet I recently introduced, completely similar to c++/88222 fixed by Marek. Well, at least we will not print anymore an empty '' when the unqualified_id is null because the field is unnamed.
3- In the non-static case too, when from grokdeclarator we are calling FIELD_DECL and passing the location as first argument, I think we want to likewise pass declarator->id_loc when available.
The added/extended testcase exercise all of the above. Tested x86_64-linux. Thanks, Paolo. ////////////////
/cp 2018-12-06 Paolo Carlini <paolo.carl...@oracle.com> * class.c (check_bitfield_decl): In error message about non-integral type print the type itself too. * decl.c (grokdeclarator): Do not ICE on unnamed bit-fields declared friends; when calling build_decl for a FIELD_DECL possibly pass the declarator->id_loc. /testsuite 2018-12-06 Paolo Carlini <paolo.carl...@oracle.com> * g++.dg/parse/bitfield7.C: New. * g++.dg/other/bitfield2.C: Check location and type. * g++.dg/parse/bitfield1.C: Likewise. * g++.dg/parse/bitfield2.C: Likewise.
Index: cp/class.c =================================================================== --- cp/class.c (revision 266840) +++ cp/class.c (working copy) @@ -3218,7 +3218,8 @@ check_bitfield_decl (tree field) /* Detect invalid bit-field type. */ if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { - error ("bit-field %q+#D with non-integral type", field); + error_at (DECL_SOURCE_LOCATION (field), + "bit-field %q#D with non-integral type %qT", field, type); w = error_mark_node; } else Index: cp/decl.c =================================================================== --- cp/decl.c (revision 266840) +++ cp/decl.c (working copy) @@ -12446,9 +12446,13 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - error_at (declarator->id_loc, - "%qE is neither function nor member function; " - "cannot be declared friend", unqualified_id); + if (unqualified_id && declarator) + error_at (declarator->id_loc, + "%qE is neither function nor member function; " + "cannot be declared friend", unqualified_id); + else + error ("unnamed field is neither function nor member " + "function; cannot be declared friend"); return error_mark_node; } decl = NULL_TREE; @@ -12536,7 +12540,9 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id); constexpr_p = false; } - decl = build_decl (input_location, + decl = build_decl (declarator + ? declarator->id_loc + : input_location, FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; if (bitfield && !unqualified_id) Index: testsuite/g++.dg/other/bitfield2.C =================================================================== --- testsuite/g++.dg/other/bitfield2.C (revision 266840) +++ testsuite/g++.dg/other/bitfield2.C (working copy) @@ -3,7 +3,7 @@ struct A { - double d : 2; // { dg-error "non-integral" } + double d : 2; // { dg-error "10:bit-field .d. with non-integral type .double." } A() {} ~A() {} }; Index: testsuite/g++.dg/parse/bitfield1.C =================================================================== --- testsuite/g++.dg/parse/bitfield1.C (revision 266840) +++ testsuite/g++.dg/parse/bitfield1.C (working copy) @@ -2,7 +2,7 @@ struct A { - double i : 8; // { dg-error "type" } + double i : 8; // { dg-error "10:bit-field .i. with non-integral type .double." } }; void foo(A& a) Index: testsuite/g++.dg/parse/bitfield2.C =================================================================== --- testsuite/g++.dg/parse/bitfield2.C (revision 266840) +++ testsuite/g++.dg/parse/bitfield2.C (working copy) @@ -4,7 +4,7 @@ struct X {}; struct A { - X x : 2; // { dg-error "non-integral type" } + X x : 2; // { dg-error "7:bit-field .x. with non-integral type .X." } }; struct B : A {}; @@ -19,7 +19,7 @@ C<int> c; template <typename T> struct D { - T t : 3; // { dg-error "non-integral type" } + T t : 3; // { dg-error "5:bit-field .double D\\<double\\>::t. with non-integral type .double." } }; D<double> d; // { dg-message "required" } @@ -28,7 +28,7 @@ template <typename T> struct E { typedef T* U; - U t : 3; // { dg-error "non-integral type" } + U t : 3; // { dg-error "5:bit-field .t. with non-integral type .E\\<T\\>::U." } }; E<double> e; Index: testsuite/g++.dg/parse/bitfield7.C =================================================================== --- testsuite/g++.dg/parse/bitfield7.C (nonexistent) +++ testsuite/g++.dg/parse/bitfield7.C (working copy) @@ -0,0 +1,4 @@ +struct A +{ + friend int : 1; // { dg-error "unnamed field" } +};