Message ID | 20200803141451.867700-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Member initializer list diagnostic locations [PR94024] | expand |
On 8/3/20 10:14 AM, Patrick Palka wrote: > This patch preserves the source locations of each node in a member > initializer list so that during processing of the list we can set > input_location appropriately for generally more accurate diagnostic > locations. Since TREE_LIST nodes are tcc_exceptional, they can't have > source locations, so we instead store the location in a dummy > tcc_expression node within the TREE_TYPE of the list node. > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to > commit? > > gcc/cp/ChangeLog: > > PR c++/94024 > * init.c (sort_mem_initializers): Preserve TREE_TYPE of the > member initializer list node. > (emit_mem_initializers): Set input_location when performing each > member initialization. > * parser.c (cp_parser_mem_initializer_list): Attach the source > location of this initializer to a dummy EMPTY_CLASS_EXPR within > the TREE_TYPE of the list node. > * pt.c (tsubst_initializer_list): Preserve TREE_TYPE of the > member initializer list node. > > gcc/testsuite/ChangeLog: > > PR c++/94024 > * g++.dg/diagnostic/mem-init1.C: New test. > --- > gcc/cp/init.c | 6 +++++ > gcc/cp/parser.c | 8 ++++++ > gcc/cp/pt.c | 3 +++ > gcc/testsuite/g++.dg/diagnostic/mem-init1.C | 29 +++++++++++++++++++++ > 4 files changed, 46 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/diagnostic/mem-init1.C > > diff --git a/gcc/cp/init.c b/gcc/cp/init.c > index cb9bd2dbfba..3f089404cf2 100644 > --- a/gcc/cp/init.c > +++ b/gcc/cp/init.c > @@ -1151,6 +1151,8 @@ sort_mem_initializers (tree t, tree mem_inits) > > /* Record the initialization. */ > TREE_VALUE (subobject_init) = TREE_VALUE (init); > + /* Carry over the dummy TREE_TYPE node containing the source location. */ > + TREE_TYPE (subobject_init) = TREE_TYPE (init); > next_subobject = subobject_init; > } > > @@ -1367,6 +1369,10 @@ emit_mem_initializers (tree mem_inits) > /* Initialize the data members. */ > while (mem_inits) > { > + /* If this initializer was explicitly provided, then the dummy TREE_TYPE > + node contains the source location. */ > + iloc_sentinel ils (EXPR_LOCATION (TREE_TYPE (mem_inits))); > + > perform_member_init (TREE_PURPOSE (mem_inits), > TREE_VALUE (mem_inits)); > mem_inits = TREE_CHAIN (mem_inits); > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > index ab088874ba7..2f9b8786121 100644 > --- a/gcc/cp/parser.c > +++ b/gcc/cp/parser.c > @@ -15326,6 +15326,14 @@ cp_parser_mem_initializer_list (cp_parser* parser) > { > TREE_CHAIN (mem_initializer) = mem_initializer_list; > mem_initializer_list = mem_initializer; > + > + /* We can't attach the source location of this initializer directly to > + the list node, so we instead attach it to a dummy EMPTY_CLASS_EXPR > + within the TREE_TYPE of the list node. */ > + TREE_TYPE (mem_initializer) = build0 (EMPTY_CLASS_EXPR, NULL_TREE); > + SET_EXPR_LOCATION (TREE_TYPE (mem_initializer), > + make_location (token->location, > + token->location, input_location)); Why not do this in cp_parser_mem_initializer? Also, use parser->lexer for the last argument to make_location. > } > /* If the next token is not a `,', we're done. */ > if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index 3a168d506cf..bed1a3532e7 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -26014,6 +26014,9 @@ tsubst_initializer_list (tree t, tree argvec) > if (decl) > { > init = build_tree_list (decl, init); > + /* Carry over the dummy TREE_TYPE node containing the source > + location. */ > + TREE_TYPE (init) = TREE_TYPE (t); > TREE_CHAIN (init) = inits; > inits = init; > } > diff --git a/gcc/testsuite/g++.dg/diagnostic/mem-init1.C b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C > new file mode 100644 > index 00000000000..b749c72cd8b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C > @@ -0,0 +1,29 @@ > +// PR c++/94024 > +// { dg-do compile } > + > +struct A { > + A() > + : a() // { dg-error "reference type" } > + , b(1) // { dg-error "incompatible" } > + , c(0) // { dg-bogus "" } > + {} > + > + int &a; > + int b[1]; > + char c; > +}; > + > +template<typename T, typename U> > +struct B { > + B() > + : a() // { dg-error "reference type" } > + , b(1) // { dg-error "incompatible" } > + , c(0) // { dg-bogus "" } > + {} > + > + T a; > + U b; > + char c; > +}; > + > +B<int&, int[1]> b; >
On Mon, 3 Aug 2020, Jason Merrill wrote: > On 8/3/20 10:14 AM, Patrick Palka wrote: > > This patch preserves the source locations of each node in a member > > initializer list so that during processing of the list we can set > > input_location appropriately for generally more accurate diagnostic > > locations. Since TREE_LIST nodes are tcc_exceptional, they can't have > > source locations, so we instead store the location in a dummy > > tcc_expression node within the TREE_TYPE of the list node. > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to > > commit? > > > > gcc/cp/ChangeLog: > > > > PR c++/94024 > > * init.c (sort_mem_initializers): Preserve TREE_TYPE of the > > member initializer list node. > > (emit_mem_initializers): Set input_location when performing each > > member initialization. > > * parser.c (cp_parser_mem_initializer_list): Attach the source > > location of this initializer to a dummy EMPTY_CLASS_EXPR within > > the TREE_TYPE of the list node. > > * pt.c (tsubst_initializer_list): Preserve TREE_TYPE of the > > member initializer list node. > > > > gcc/testsuite/ChangeLog: > > > > PR c++/94024 > > * g++.dg/diagnostic/mem-init1.C: New test. > > --- > > gcc/cp/init.c | 6 +++++ > > gcc/cp/parser.c | 8 ++++++ > > gcc/cp/pt.c | 3 +++ > > gcc/testsuite/g++.dg/diagnostic/mem-init1.C | 29 +++++++++++++++++++++ > > 4 files changed, 46 insertions(+) > > create mode 100644 gcc/testsuite/g++.dg/diagnostic/mem-init1.C > > > > diff --git a/gcc/cp/init.c b/gcc/cp/init.c > > index cb9bd2dbfba..3f089404cf2 100644 > > --- a/gcc/cp/init.c > > +++ b/gcc/cp/init.c > > @@ -1151,6 +1151,8 @@ sort_mem_initializers (tree t, tree mem_inits) > > /* Record the initialization. */ > > TREE_VALUE (subobject_init) = TREE_VALUE (init); > > + /* Carry over the dummy TREE_TYPE node containing the source > > location. */ > > + TREE_TYPE (subobject_init) = TREE_TYPE (init); > > next_subobject = subobject_init; > > } > > @@ -1367,6 +1369,10 @@ emit_mem_initializers (tree mem_inits) > > /* Initialize the data members. */ > > while (mem_inits) > > { > > + /* If this initializer was explicitly provided, then the dummy > > TREE_TYPE > > + node contains the source location. */ > > + iloc_sentinel ils (EXPR_LOCATION (TREE_TYPE (mem_inits))); > > + > > perform_member_init (TREE_PURPOSE (mem_inits), > > TREE_VALUE (mem_inits)); > > mem_inits = TREE_CHAIN (mem_inits); > > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > > index ab088874ba7..2f9b8786121 100644 > > --- a/gcc/cp/parser.c > > +++ b/gcc/cp/parser.c > > @@ -15326,6 +15326,14 @@ cp_parser_mem_initializer_list (cp_parser* parser) > > { > > TREE_CHAIN (mem_initializer) = mem_initializer_list; > > mem_initializer_list = mem_initializer; > > + > > + /* We can't attach the source location of this initializer directly > > to > > + the list node, so we instead attach it to a dummy > > EMPTY_CLASS_EXPR > > + within the TREE_TYPE of the list node. */ > > + TREE_TYPE (mem_initializer) = build0 (EMPTY_CLASS_EXPR, NULL_TREE); > > + SET_EXPR_LOCATION (TREE_TYPE (mem_initializer), > > + make_location (token->location, > > + token->location, input_location)); > > Why not do this in cp_parser_mem_initializer? > > Also, use parser->lexer for the last argument to make_location. That's a much better spot for it :) Done and done. Does the following look OK after testing completes? -- >8 -- Subject: [PATCH] c++: Member initializer list diagnostic locations [PR94024] This patch preserves the source locations of each node in a member initializer list so that during processing of the list we can set input_location appropriately for generally more accurate diagnostic locations. Since TREE_LIST nodes are tcc_exceptional, they can't have source locations, so we instead store the location in a dummy tcc_expression node within the TREE_TYPE of the list node. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to commit? gcc/cp/ChangeLog: PR c++/94024 * init.c (sort_mem_initializers): Preserve TREE_TYPE of the member initializer list node. (emit_mem_initializers): Set input_location when performing each member initialization. * parser.c (cp_parser_mem_initializer): Attach the source location of this initializer to a dummy EMPTY_CLASS_EXPR within the TREE_TYPE of the list node. * pt.c (tsubst_initializer_list): Preserve TREE_TYPE of the member initializer list node. gcc/testsuite/ChangeLog: PR c++/94024 * g++.dg/diagnostic/mem-init1.C: New test. --- gcc/cp/init.c | 6 +++++ gcc/cp/parser.c | 13 ++++++++- gcc/cp/pt.c | 3 +++ gcc/testsuite/g++.dg/diagnostic/mem-init1.C | 29 +++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/diagnostic/mem-init1.C diff --git a/gcc/cp/init.c b/gcc/cp/init.c index cb9bd2dbfba..3f089404cf2 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1151,6 +1151,8 @@ sort_mem_initializers (tree t, tree mem_inits) /* Record the initialization. */ TREE_VALUE (subobject_init) = TREE_VALUE (init); + /* Carry over the dummy TREE_TYPE node containing the source location. */ + TREE_TYPE (subobject_init) = TREE_TYPE (init); next_subobject = subobject_init; } @@ -1367,6 +1369,10 @@ emit_mem_initializers (tree mem_inits) /* Initialize the data members. */ while (mem_inits) { + /* If this initializer was explicitly provided, then the dummy TREE_TYPE + node contains the source location. */ + iloc_sentinel ils (EXPR_LOCATION (TREE_TYPE (mem_inits))); + perform_member_init (TREE_PURPOSE (mem_inits), TREE_VALUE (mem_inits)); mem_inits = TREE_CHAIN (mem_inits); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ab088874ba7..8b11e478c83 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15411,7 +15411,18 @@ cp_parser_mem_initializer (cp_parser* parser) in_base_initializer = 0; - return member ? build_tree_list (member, expression_list) : error_mark_node; + if (!member) + return error_mark_node; + + tree node = build_tree_list (member, expression_list); + /* We can't attach the source location of this initializer directly to + the list node, so we instead attach it to a dummy EMPTY_CLASS_EXPR + within the TREE_TYPE of the list node. */ + TREE_TYPE (node) = build0 (EMPTY_CLASS_EXPR, NULL_TREE); + SET_EXPR_LOCATION (TREE_TYPE (node), + make_location (token->location, + token->location, parser->lexer)); + return node; } /* Parse a mem-initializer-id. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 524c0bfe2d6..721eb5262d6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -26014,6 +26014,9 @@ tsubst_initializer_list (tree t, tree argvec) if (decl) { init = build_tree_list (decl, init); + /* Carry over the dummy TREE_TYPE node containing the source + location. */ + TREE_TYPE (init) = TREE_TYPE (t); TREE_CHAIN (init) = inits; inits = init; } diff --git a/gcc/testsuite/g++.dg/diagnostic/mem-init1.C b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C new file mode 100644 index 00000000000..b749c72cd8b --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C @@ -0,0 +1,29 @@ +// PR c++/94024 +// { dg-do compile } + +struct A { + A() + : a() // { dg-error "reference type" } + , b(1) // { dg-error "incompatible" } + , c(0) // { dg-bogus "" } + {} + + int &a; + int b[1]; + char c; +}; + +template<typename T, typename U> +struct B { + B() + : a() // { dg-error "reference type" } + , b(1) // { dg-error "incompatible" } + , c(0) // { dg-bogus "" } + {} + + T a; + U b; + char c; +}; + +B<int&, int[1]> b;
On 8/3/20 2:49 PM, Patrick Palka wrote: > On Mon, 3 Aug 2020, Jason Merrill wrote: > >> On 8/3/20 10:14 AM, Patrick Palka wrote: >>> This patch preserves the source locations of each node in a member >>> initializer list so that during processing of the list we can set >>> input_location appropriately for generally more accurate diagnostic >>> locations. Since TREE_LIST nodes are tcc_exceptional, they can't have >>> source locations, so we instead store the location in a dummy >>> tcc_expression node within the TREE_TYPE of the list node. >> >>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to >>> commit? >>> >>> gcc/cp/ChangeLog: >>> >>> PR c++/94024 >>> * init.c (sort_mem_initializers): Preserve TREE_TYPE of the >>> member initializer list node. >>> (emit_mem_initializers): Set input_location when performing each >>> member initialization. >>> * parser.c (cp_parser_mem_initializer_list): Attach the source >>> location of this initializer to a dummy EMPTY_CLASS_EXPR within >>> the TREE_TYPE of the list node. >>> * pt.c (tsubst_initializer_list): Preserve TREE_TYPE of the >>> member initializer list node. >>> >>> gcc/testsuite/ChangeLog: >>> >>> PR c++/94024 >>> * g++.dg/diagnostic/mem-init1.C: New test. >>> --- >>> gcc/cp/init.c | 6 +++++ >>> gcc/cp/parser.c | 8 ++++++ >>> gcc/cp/pt.c | 3 +++ >>> gcc/testsuite/g++.dg/diagnostic/mem-init1.C | 29 +++++++++++++++++++++ >>> 4 files changed, 46 insertions(+) >>> create mode 100644 gcc/testsuite/g++.dg/diagnostic/mem-init1.C >>> >>> diff --git a/gcc/cp/init.c b/gcc/cp/init.c >>> index cb9bd2dbfba..3f089404cf2 100644 >>> --- a/gcc/cp/init.c >>> +++ b/gcc/cp/init.c >>> @@ -1151,6 +1151,8 @@ sort_mem_initializers (tree t, tree mem_inits) >>> /* Record the initialization. */ >>> TREE_VALUE (subobject_init) = TREE_VALUE (init); >>> + /* Carry over the dummy TREE_TYPE node containing the source >>> location. */ >>> + TREE_TYPE (subobject_init) = TREE_TYPE (init); >>> next_subobject = subobject_init; >>> } >>> @@ -1367,6 +1369,10 @@ emit_mem_initializers (tree mem_inits) >>> /* Initialize the data members. */ >>> while (mem_inits) >>> { >>> + /* If this initializer was explicitly provided, then the dummy >>> TREE_TYPE >>> + node contains the source location. */ >>> + iloc_sentinel ils (EXPR_LOCATION (TREE_TYPE (mem_inits))); >>> + >>> perform_member_init (TREE_PURPOSE (mem_inits), >>> TREE_VALUE (mem_inits)); >>> mem_inits = TREE_CHAIN (mem_inits); >>> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c >>> index ab088874ba7..2f9b8786121 100644 >>> --- a/gcc/cp/parser.c >>> +++ b/gcc/cp/parser.c >>> @@ -15326,6 +15326,14 @@ cp_parser_mem_initializer_list (cp_parser* parser) >>> { >>> TREE_CHAIN (mem_initializer) = mem_initializer_list; >>> mem_initializer_list = mem_initializer; >>> + >>> + /* We can't attach the source location of this initializer directly >>> to >>> + the list node, so we instead attach it to a dummy >>> EMPTY_CLASS_EXPR >>> + within the TREE_TYPE of the list node. */ >>> + TREE_TYPE (mem_initializer) = build0 (EMPTY_CLASS_EXPR, NULL_TREE); >>> + SET_EXPR_LOCATION (TREE_TYPE (mem_initializer), >>> + make_location (token->location, >>> + token->location, input_location)); >> >> Why not do this in cp_parser_mem_initializer? >> >> Also, use parser->lexer for the last argument to make_location. > > That's a much better spot for it :) Done and done. Does the following > look OK after testing completes? OK. > -- >8 -- > > Subject: [PATCH] c++: Member initializer list diagnostic locations [PR94024] > > This patch preserves the source locations of each node in a member > initializer list so that during processing of the list we can set > input_location appropriately for generally more accurate diagnostic > locations. Since TREE_LIST nodes are tcc_exceptional, they can't have > source locations, so we instead store the location in a dummy > tcc_expression node within the TREE_TYPE of the list node. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to > commit? > > gcc/cp/ChangeLog: > > PR c++/94024 > * init.c (sort_mem_initializers): Preserve TREE_TYPE of the > member initializer list node. > (emit_mem_initializers): Set input_location when performing each > member initialization. > * parser.c (cp_parser_mem_initializer): Attach the source > location of this initializer to a dummy EMPTY_CLASS_EXPR > within the TREE_TYPE of the list node. > * pt.c (tsubst_initializer_list): Preserve TREE_TYPE of the > member initializer list node. > > gcc/testsuite/ChangeLog: > > PR c++/94024 > * g++.dg/diagnostic/mem-init1.C: New test. > --- > gcc/cp/init.c | 6 +++++ > gcc/cp/parser.c | 13 ++++++++- > gcc/cp/pt.c | 3 +++ > gcc/testsuite/g++.dg/diagnostic/mem-init1.C | 29 +++++++++++++++++++++ > 4 files changed, 50 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/diagnostic/mem-init1.C > > diff --git a/gcc/cp/init.c b/gcc/cp/init.c > index cb9bd2dbfba..3f089404cf2 100644 > --- a/gcc/cp/init.c > +++ b/gcc/cp/init.c > @@ -1151,6 +1151,8 @@ sort_mem_initializers (tree t, tree mem_inits) > > /* Record the initialization. */ > TREE_VALUE (subobject_init) = TREE_VALUE (init); > + /* Carry over the dummy TREE_TYPE node containing the source location. */ > + TREE_TYPE (subobject_init) = TREE_TYPE (init); > next_subobject = subobject_init; > } > > @@ -1367,6 +1369,10 @@ emit_mem_initializers (tree mem_inits) > /* Initialize the data members. */ > while (mem_inits) > { > + /* If this initializer was explicitly provided, then the dummy TREE_TYPE > + node contains the source location. */ > + iloc_sentinel ils (EXPR_LOCATION (TREE_TYPE (mem_inits))); > + > perform_member_init (TREE_PURPOSE (mem_inits), > TREE_VALUE (mem_inits)); > mem_inits = TREE_CHAIN (mem_inits); > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > index ab088874ba7..8b11e478c83 100644 > --- a/gcc/cp/parser.c > +++ b/gcc/cp/parser.c > @@ -15411,7 +15411,18 @@ cp_parser_mem_initializer (cp_parser* parser) > > in_base_initializer = 0; > > - return member ? build_tree_list (member, expression_list) : error_mark_node; > + if (!member) > + return error_mark_node; > + > + tree node = build_tree_list (member, expression_list); > + /* We can't attach the source location of this initializer directly to > + the list node, so we instead attach it to a dummy EMPTY_CLASS_EXPR > + within the TREE_TYPE of the list node. */ > + TREE_TYPE (node) = build0 (EMPTY_CLASS_EXPR, NULL_TREE); > + SET_EXPR_LOCATION (TREE_TYPE (node), > + make_location (token->location, > + token->location, parser->lexer)); > + return node; > } > > /* Parse a mem-initializer-id. > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index 524c0bfe2d6..721eb5262d6 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -26014,6 +26014,9 @@ tsubst_initializer_list (tree t, tree argvec) > if (decl) > { > init = build_tree_list (decl, init); > + /* Carry over the dummy TREE_TYPE node containing the source > + location. */ > + TREE_TYPE (init) = TREE_TYPE (t); > TREE_CHAIN (init) = inits; > inits = init; > } > diff --git a/gcc/testsuite/g++.dg/diagnostic/mem-init1.C b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C > new file mode 100644 > index 00000000000..b749c72cd8b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C > @@ -0,0 +1,29 @@ > +// PR c++/94024 > +// { dg-do compile } > + > +struct A { > + A() > + : a() // { dg-error "reference type" } > + , b(1) // { dg-error "incompatible" } > + , c(0) // { dg-bogus "" } > + {} > + > + int &a; > + int b[1]; > + char c; > +}; > + > +template<typename T, typename U> > +struct B { > + B() > + : a() // { dg-error "reference type" } > + , b(1) // { dg-error "incompatible" } > + , c(0) // { dg-bogus "" } > + {} > + > + T a; > + U b; > + char c; > +}; > + > +B<int&, int[1]> b; >
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index cb9bd2dbfba..3f089404cf2 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1151,6 +1151,8 @@ sort_mem_initializers (tree t, tree mem_inits) /* Record the initialization. */ TREE_VALUE (subobject_init) = TREE_VALUE (init); + /* Carry over the dummy TREE_TYPE node containing the source location. */ + TREE_TYPE (subobject_init) = TREE_TYPE (init); next_subobject = subobject_init; } @@ -1367,6 +1369,10 @@ emit_mem_initializers (tree mem_inits) /* Initialize the data members. */ while (mem_inits) { + /* If this initializer was explicitly provided, then the dummy TREE_TYPE + node contains the source location. */ + iloc_sentinel ils (EXPR_LOCATION (TREE_TYPE (mem_inits))); + perform_member_init (TREE_PURPOSE (mem_inits), TREE_VALUE (mem_inits)); mem_inits = TREE_CHAIN (mem_inits); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ab088874ba7..2f9b8786121 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15326,6 +15326,14 @@ cp_parser_mem_initializer_list (cp_parser* parser) { TREE_CHAIN (mem_initializer) = mem_initializer_list; mem_initializer_list = mem_initializer; + + /* We can't attach the source location of this initializer directly to + the list node, so we instead attach it to a dummy EMPTY_CLASS_EXPR + within the TREE_TYPE of the list node. */ + TREE_TYPE (mem_initializer) = build0 (EMPTY_CLASS_EXPR, NULL_TREE); + SET_EXPR_LOCATION (TREE_TYPE (mem_initializer), + make_location (token->location, + token->location, input_location)); } /* If the next token is not a `,', we're done. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3a168d506cf..bed1a3532e7 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -26014,6 +26014,9 @@ tsubst_initializer_list (tree t, tree argvec) if (decl) { init = build_tree_list (decl, init); + /* Carry over the dummy TREE_TYPE node containing the source + location. */ + TREE_TYPE (init) = TREE_TYPE (t); TREE_CHAIN (init) = inits; inits = init; } diff --git a/gcc/testsuite/g++.dg/diagnostic/mem-init1.C b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C new file mode 100644 index 00000000000..b749c72cd8b --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/mem-init1.C @@ -0,0 +1,29 @@ +// PR c++/94024 +// { dg-do compile } + +struct A { + A() + : a() // { dg-error "reference type" } + , b(1) // { dg-error "incompatible" } + , c(0) // { dg-bogus "" } + {} + + int &a; + int b[1]; + char c; +}; + +template<typename T, typename U> +struct B { + B() + : a() // { dg-error "reference type" } + , b(1) // { dg-error "incompatible" } + , c(0) // { dg-bogus "" } + {} + + T a; + U b; + char c; +}; + +B<int&, int[1]> b;