Message ID | YZ1l7igXPj76+xy/@redhat.com |
---|---|
State | New |
Headers | show |
Series | [v2] c++: Fix missing NSDMI diagnostic in C++98 [PR103347] | expand |
On 11/23/21 17:06, Marek Polacek wrote: > On Tue, Nov 23, 2021 at 02:42:12PM -0500, Jason Merrill wrote: >> On 11/22/21 17:17, Marek Polacek wrote: >>> Here the problem is that we aren't detecting a NSDMI in C++98: >>> >>> struct A { >>> void *x = NULL; >>> }; >>> >>> because maybe_warn_cpp0x uses input_location and that happens to point >>> to NULL which comes from a system header. Jakub suggested changing the >>> location to the '=', thereby avoiding the system header problem. To >>> that end, I've added a new location_t member into cp_declarator. This >>> member is used when this declarator is part of an init-declarator. The >>> rest of the changes is obvious. I've also taken the liberty of adding >>> loc_or_input_loc, since I want to avoid checking for UNKNOWN_LOCATION. >>> >>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? >>> >>> PR c++/103347 >>> >>> gcc/cp/ChangeLog: >>> >>> * cp-tree.h (struct cp_declarator): Add a location_t member. >>> (maybe_warn_cpp0x): Add a location_t parameter with a default argument. >>> (loc_or_input_loc): New. >>> * decl.c (grokdeclarator): Use loc_or_input_loc. Pass init_loc down >>> to maybe_warn_cpp0x. >>> * error.c (maybe_warn_cpp0x): Add a location_t parameter. Use it. >>> * parser.c (make_declarator): Initialize init_loc. >>> (cp_parser_member_declaration): Set init_loc. >>> >>> gcc/testsuite/ChangeLog: >>> >>> * g++.dg/cpp0x/nsdmi-warn1.C: New test. >>> * g++.dg/cpp0x/nsdmi-warn1.h: New file. >>> --- >>> gcc/cp/cp-tree.h | 16 +++++++++--- >>> gcc/cp/decl.c | 22 +++++++++------- >>> gcc/cp/error.c | 32 ++++++++++++------------ >>> gcc/cp/parser.c | 2 ++ >>> gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C | 10 ++++++++ >>> gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h | 2 ++ >>> 6 files changed, 55 insertions(+), 29 deletions(-) >>> create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C >>> create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h >>> >>> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h >>> index 3f56cb90d14..2037082b0c7 100644 >>> --- a/gcc/cp/cp-tree.h >>> +++ b/gcc/cp/cp-tree.h >>> @@ -6231,9 +6231,11 @@ struct cp_declarator { >>> /* If this declarator is parenthesized, this the open-paren. It is >>> UNKNOWN_LOCATION when not parenthesized. */ >>> location_t parenthesized; >>> - >>> - location_t id_loc; /* Currently only set for cdk_id, cdk_decomp and >>> - cdk_function. */ >>> + /* Currently only set for cdk_id, cdk_decomp and cdk_function. */ >>> + location_t id_loc; >>> + /* If this declarator is part of an init-declarator, the location of the >>> + initializer. */ >> >> Currently this comment is inaccurate because we don't set it for all >> init-declarators. That should be pretty trivial to do, even if we don't use >> the location yet in other contexts. > > The following patch sets ->init_loc in a few more spots. I've looked > at every cp_parser_declarator call and if it's followed by a =/{, I > set ->init_loc. Pedantically, it's also an init-declarator if the > declarator is followed by a requires-clause, but I've not looked for > those cases. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? OK. > -- >8 -- > Here the problem is that we aren't detecting a NSDMI in C++98: > > struct A { > void *x = NULL; > }; > > because maybe_warn_cpp0x uses input_location and that happens to point > to NULL which comes from a system header. Jakub suggested changing the > location to the '=', thereby avoiding the system header problem. To > that end, I've added a new location_t member into cp_declarator. This > member is used when this declarator is part of an init-declarator. The > rest of the changes is obvious. I've also taken the liberty of adding > loc_or_input_loc, since I want to avoid checking for UNKNOWN_LOCATION. > > PR c++/103347 > > gcc/cp/ChangeLog: > > * cp-tree.h (struct cp_declarator): Add a location_t member. > (maybe_warn_cpp0x): Add a location_t parameter with a default argument. > (loc_or_input_loc): New. > * decl.c (grokdeclarator): Use loc_or_input_loc. Pass init_loc down > to maybe_warn_cpp0x. > * error.c (maybe_warn_cpp0x): Add a location_t parameter. Use it. > * parser.c (make_declarator): Initialize init_loc. > (cp_parser_member_declaration): Set init_loc. > (cp_parser_condition): Likewise. > (cp_parser_init_declarator): Likewise. > (cp_parser_parameter_declaration): Likewise. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/nsdmi-warn1.C: New test. > * g++.dg/cpp0x/nsdmi-warn1.h: New file. > --- > gcc/cp/cp-tree.h | 16 +++++++++--- > gcc/cp/decl.c | 22 +++++++++------- > gcc/cp/error.c | 32 ++++++++++++------------ > gcc/cp/parser.c | 8 ++++++ > gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C | 10 ++++++++ > gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h | 2 ++ > 6 files changed, 61 insertions(+), 29 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C > create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 3f56cb90d14..2037082b0c7 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -6231,9 +6231,11 @@ struct cp_declarator { > /* If this declarator is parenthesized, this the open-paren. It is > UNKNOWN_LOCATION when not parenthesized. */ > location_t parenthesized; > - > - location_t id_loc; /* Currently only set for cdk_id, cdk_decomp and > - cdk_function. */ > + /* Currently only set for cdk_id, cdk_decomp and cdk_function. */ > + location_t id_loc; > + /* If this declarator is part of an init-declarator, the location of the > + initializer. */ > + location_t init_loc; > /* GNU Attributes that apply to this declarator. If the declarator > is a pointer or a reference, these attribute apply to the type > pointed to. */ > @@ -6878,7 +6880,8 @@ extern const char *lang_decl_dwarf_name (tree, int, bool); > extern const char *language_to_string (enum languages); > extern const char *class_key_or_enum_as_string (tree); > extern void maybe_warn_variadic_templates (void); > -extern void maybe_warn_cpp0x (cpp0x_warn_str str); > +extern void maybe_warn_cpp0x (cpp0x_warn_str str, > + location_t = input_location); > extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); > extern location_t location_of (tree); > extern void qualified_name_lookup_error (tree, tree, tree, > @@ -7996,6 +7999,11 @@ extern bool decl_in_std_namespace_p (tree); > extern void require_complete_eh_spec_types (tree, tree); > extern void cxx_incomplete_type_diagnostic (location_t, const_tree, > const_tree, diagnostic_t); > +inline location_t > +loc_or_input_loc (location_t loc) > +{ > + return loc == UNKNOWN_LOCATION ? input_location : loc; > +} > > inline location_t > cp_expr_loc_or_loc (const_tree t, location_t or_loc) > diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c > index 9f68d1a5590..ae0e0bae9cc 100644 > --- a/gcc/cp/decl.c > +++ b/gcc/cp/decl.c > @@ -11522,14 +11522,18 @@ grokdeclarator (const cp_declarator *declarator, > if (initialized == SD_DEFAULTED || initialized == SD_DELETED) > funcdef_flag = true; > > - location_t typespec_loc = smallest_type_location (type_quals, > - declspecs->locations); > - if (typespec_loc == UNKNOWN_LOCATION) > - typespec_loc = input_location; > - > - location_t id_loc = declarator ? declarator->id_loc : input_location; > - if (id_loc == UNKNOWN_LOCATION) > - id_loc = input_location; > + location_t typespec_loc = loc_or_input_loc (smallest_type_location > + (type_quals, > + declspecs->locations)); > + location_t id_loc; > + location_t init_loc; > + if (declarator) > + { > + id_loc = loc_or_input_loc (declarator->id_loc); > + init_loc = loc_or_input_loc (declarator->init_loc); > + } > + else > + init_loc = id_loc = input_location; > > /* Look inside a declarator for the name being declared > and get it as a string, for an error message. */ > @@ -14042,7 +14046,7 @@ grokdeclarator (const cp_declarator *declarator, > { > /* An attempt is being made to initialize a non-static > member. This is new in C++11. */ > - maybe_warn_cpp0x (CPP0X_NSDMI); > + maybe_warn_cpp0x (CPP0X_NSDMI, init_loc); > > /* If this has been parsed with static storage class, but > errors forced staticp to be cleared, ensure NSDMI is > diff --git a/gcc/cp/error.c b/gcc/cp/error.c > index 872479369ab..98c1f0e4bdf 100644 > --- a/gcc/cp/error.c > +++ b/gcc/cp/error.c > @@ -4428,84 +4428,84 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec, > > /* Warn about the use of C++0x features when appropriate. */ > void > -maybe_warn_cpp0x (cpp0x_warn_str str) > +maybe_warn_cpp0x (cpp0x_warn_str str, location_t loc/*=input_location*/) > { > if (cxx_dialect == cxx98) > switch (str) > { > case CPP0X_INITIALIZER_LISTS: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "extended initializer lists " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_EXPLICIT_CONVERSION: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "explicit conversion operators " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_VARIADIC_TEMPLATES: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "variadic templates " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_LAMBDA_EXPR: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "lambda expressions " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_AUTO: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "C++11 auto only available with %<-std=c++11%> or " > "%<-std=gnu++11%>"); > break; > case CPP0X_SCOPED_ENUMS: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "scoped enums only available with %<-std=c++11%> or " > "%<-std=gnu++11%>"); > break; > case CPP0X_DEFAULTED_DELETED: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "defaulted and deleted functions " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_INLINE_NAMESPACES: > if (pedantic) > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "inline namespaces " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_OVERRIDE_CONTROLS: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "override controls (override/final) " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_NSDMI: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "non-static data member initializers " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_USER_DEFINED_LITERALS: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "user-defined literals " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_DELEGATING_CTORS: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "delegating constructors " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_INHERITING_CTORS: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "inheriting constructors " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_ATTRIBUTES: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "C++11 attributes " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > case CPP0X_REF_QUALIFIER: > - pedwarn (input_location, OPT_Wc__11_extensions, > + pedwarn (loc, OPT_Wc__11_extensions, > "ref-qualifiers " > "only available with %<-std=c++11%> or %<-std=gnu++11%>"); > break; > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > index e2b5d6842fc..7a6a30208ef 100644 > --- a/gcc/cp/parser.c > +++ b/gcc/cp/parser.c > @@ -1542,6 +1542,7 @@ make_declarator (cp_declarator_kind kind) > declarator->declarator = NULL; > declarator->parameter_pack_p = false; > declarator->id_loc = UNKNOWN_LOCATION; > + declarator->init_loc = UNKNOWN_LOCATION; > > return declarator; > } > @@ -13286,6 +13287,7 @@ cp_parser_condition (cp_parser* parser) > attributes, prefix_attributes, > &pushed_scope); > > + declarator->init_loc = cp_lexer_peek_token (parser->lexer)->location; > /* Parse the initializer. */ > if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) > { > @@ -22492,6 +22494,7 @@ cp_parser_init_declarator (cp_parser* parser, > { > is_initialized = SD_INITIALIZED; > initialization_kind = token->type; > + declarator->init_loc = token->location; > if (maybe_range_for_decl) > *maybe_range_for_decl = error_mark_node; > tmp_init_loc = token->location; > @@ -24751,6 +24754,8 @@ cp_parser_parameter_declaration (cp_parser *parser, > { > tree type = decl_specifiers.type; > token = cp_lexer_peek_token (parser->lexer); > + if (declarator) > + declarator->init_loc = token->location; > /* If we are defining a class, then the tokens that make up the > default argument must be saved and processed later. */ > if (!template_parm_p && at_class_scope_p () > @@ -27143,6 +27148,7 @@ cp_parser_member_declaration (cp_parser* parser) > constant-initializer. When we call `grokfield', it will > perform more stringent semantics checks. */ > initializer_token_start = cp_lexer_peek_token (parser->lexer); > + declarator->init_loc = initializer_token_start->location; > if (function_declarator_p (declarator) > || (decl_specifiers.type > && TREE_CODE (decl_specifiers.type) == TYPE_DECL > @@ -27171,6 +27177,8 @@ cp_parser_member_declaration (cp_parser* parser) > && !function_declarator_p (declarator)) > { > bool x; > + declarator->init_loc > + = cp_lexer_peek_token (parser->lexer)->location; > if (decl_specifiers.storage_class != sc_static) > initializer = cp_parser_save_nsdmi (parser); > else > diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C > new file mode 100644 > index 00000000000..aacc8b28255 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C > @@ -0,0 +1,10 @@ > +// PR c++/103347 > +// { dg-do compile { target c++11_down } } > + > +#include "nsdmi-warn1.h" > + > +struct A { > + void *x = NULL; // { dg-error "11:only available" "" { target c++98_only } } > + void *y{NULL}; // { dg-error "only available|extended initializer" "" { target c++98_only } } > + int z = 1 + 2; // { dg-error "9:only available" "" { target c++98_only } } > +}; > diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h > new file mode 100644 > index 00000000000..ee5be5a2478 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h > @@ -0,0 +1,2 @@ > +#pragma GCC system_header > +#define NULL (void *)0 > > base-commit: c59ec55c3459fba619e05ee7f59480b71e85ffd7 >
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3f56cb90d14..2037082b0c7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6231,9 +6231,11 @@ struct cp_declarator { /* If this declarator is parenthesized, this the open-paren. It is UNKNOWN_LOCATION when not parenthesized. */ location_t parenthesized; - - location_t id_loc; /* Currently only set for cdk_id, cdk_decomp and - cdk_function. */ + /* Currently only set for cdk_id, cdk_decomp and cdk_function. */ + location_t id_loc; + /* If this declarator is part of an init-declarator, the location of the + initializer. */ + location_t init_loc; /* GNU Attributes that apply to this declarator. If the declarator is a pointer or a reference, these attribute apply to the type pointed to. */ @@ -6878,7 +6880,8 @@ extern const char *lang_decl_dwarf_name (tree, int, bool); extern const char *language_to_string (enum languages); extern const char *class_key_or_enum_as_string (tree); extern void maybe_warn_variadic_templates (void); -extern void maybe_warn_cpp0x (cpp0x_warn_str str); +extern void maybe_warn_cpp0x (cpp0x_warn_str str, + location_t = input_location); extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern location_t location_of (tree); extern void qualified_name_lookup_error (tree, tree, tree, @@ -7996,6 +7999,11 @@ extern bool decl_in_std_namespace_p (tree); extern void require_complete_eh_spec_types (tree, tree); extern void cxx_incomplete_type_diagnostic (location_t, const_tree, const_tree, diagnostic_t); +inline location_t +loc_or_input_loc (location_t loc) +{ + return loc == UNKNOWN_LOCATION ? input_location : loc; +} inline location_t cp_expr_loc_or_loc (const_tree t, location_t or_loc) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9f68d1a5590..ae0e0bae9cc 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11522,14 +11522,18 @@ grokdeclarator (const cp_declarator *declarator, if (initialized == SD_DEFAULTED || initialized == SD_DELETED) funcdef_flag = true; - location_t typespec_loc = smallest_type_location (type_quals, - declspecs->locations); - if (typespec_loc == UNKNOWN_LOCATION) - typespec_loc = input_location; - - location_t id_loc = declarator ? declarator->id_loc : input_location; - if (id_loc == UNKNOWN_LOCATION) - id_loc = input_location; + location_t typespec_loc = loc_or_input_loc (smallest_type_location + (type_quals, + declspecs->locations)); + location_t id_loc; + location_t init_loc; + if (declarator) + { + id_loc = loc_or_input_loc (declarator->id_loc); + init_loc = loc_or_input_loc (declarator->init_loc); + } + else + init_loc = id_loc = input_location; /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ @@ -14042,7 +14046,7 @@ grokdeclarator (const cp_declarator *declarator, { /* An attempt is being made to initialize a non-static member. This is new in C++11. */ - maybe_warn_cpp0x (CPP0X_NSDMI); + maybe_warn_cpp0x (CPP0X_NSDMI, init_loc); /* If this has been parsed with static storage class, but errors forced staticp to be cleared, ensure NSDMI is diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 872479369ab..98c1f0e4bdf 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -4428,84 +4428,84 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec, /* Warn about the use of C++0x features when appropriate. */ void -maybe_warn_cpp0x (cpp0x_warn_str str) +maybe_warn_cpp0x (cpp0x_warn_str str, location_t loc/*=input_location*/) { if (cxx_dialect == cxx98) switch (str) { case CPP0X_INITIALIZER_LISTS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "extended initializer lists " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_EXPLICIT_CONVERSION: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "explicit conversion operators " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_VARIADIC_TEMPLATES: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "variadic templates " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_LAMBDA_EXPR: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "lambda expressions " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_AUTO: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "C++11 auto only available with %<-std=c++11%> or " "%<-std=gnu++11%>"); break; case CPP0X_SCOPED_ENUMS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "scoped enums only available with %<-std=c++11%> or " "%<-std=gnu++11%>"); break; case CPP0X_DEFAULTED_DELETED: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "defaulted and deleted functions " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_INLINE_NAMESPACES: if (pedantic) - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "inline namespaces " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_OVERRIDE_CONTROLS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "override controls (override/final) " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_NSDMI: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "non-static data member initializers " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_USER_DEFINED_LITERALS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "user-defined literals " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_DELEGATING_CTORS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "delegating constructors " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_INHERITING_CTORS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "inheriting constructors " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_ATTRIBUTES: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "C++11 attributes " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_REF_QUALIFIER: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "ref-qualifiers " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e2b5d6842fc..7a6a30208ef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1542,6 +1542,7 @@ make_declarator (cp_declarator_kind kind) declarator->declarator = NULL; declarator->parameter_pack_p = false; declarator->id_loc = UNKNOWN_LOCATION; + declarator->init_loc = UNKNOWN_LOCATION; return declarator; } @@ -13286,6 +13287,7 @@ cp_parser_condition (cp_parser* parser) attributes, prefix_attributes, &pushed_scope); + declarator->init_loc = cp_lexer_peek_token (parser->lexer)->location; /* Parse the initializer. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { @@ -22492,6 +22494,7 @@ cp_parser_init_declarator (cp_parser* parser, { is_initialized = SD_INITIALIZED; initialization_kind = token->type; + declarator->init_loc = token->location; if (maybe_range_for_decl) *maybe_range_for_decl = error_mark_node; tmp_init_loc = token->location; @@ -24751,6 +24754,8 @@ cp_parser_parameter_declaration (cp_parser *parser, { tree type = decl_specifiers.type; token = cp_lexer_peek_token (parser->lexer); + if (declarator) + declarator->init_loc = token->location; /* If we are defining a class, then the tokens that make up the default argument must be saved and processed later. */ if (!template_parm_p && at_class_scope_p () @@ -27143,6 +27148,7 @@ cp_parser_member_declaration (cp_parser* parser) constant-initializer. When we call `grokfield', it will perform more stringent semantics checks. */ initializer_token_start = cp_lexer_peek_token (parser->lexer); + declarator->init_loc = initializer_token_start->location; if (function_declarator_p (declarator) || (decl_specifiers.type && TREE_CODE (decl_specifiers.type) == TYPE_DECL @@ -27171,6 +27177,8 @@ cp_parser_member_declaration (cp_parser* parser) && !function_declarator_p (declarator)) { bool x; + declarator->init_loc + = cp_lexer_peek_token (parser->lexer)->location; if (decl_specifiers.storage_class != sc_static) initializer = cp_parser_save_nsdmi (parser); else diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C new file mode 100644 index 00000000000..aacc8b28255 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C @@ -0,0 +1,10 @@ +// PR c++/103347 +// { dg-do compile { target c++11_down } } + +#include "nsdmi-warn1.h" + +struct A { + void *x = NULL; // { dg-error "11:only available" "" { target c++98_only } } + void *y{NULL}; // { dg-error "only available|extended initializer" "" { target c++98_only } } + int z = 1 + 2; // { dg-error "9:only available" "" { target c++98_only } } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h new file mode 100644 index 00000000000..ee5be5a2478 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h @@ -0,0 +1,2 @@ +#pragma GCC system_header +#define NULL (void *)0