+ 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..162aff73f91 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;
}
@@ -27143,6 +27144,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
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: a944b5dec3adb28ed199234d2116145ca9010d6a