Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-10-07 Thread Bernd Schmidt

On 07/21/2016 08:39 PM, Jeff Law wrote:

On 07/15/2016 07:04 AM, Bernd Schmidt wrote:

c/
PR c++/69733
* c-decl.c (smallest_type_quals_location): New static function.
(grokdeclarator): Try to find the correct location for an ignored
qualifier.
cp/
PR c++/69733
* decl.c (grokdeclarator): Try to find the correct location for an
ignored qualifier.
testsuite/
PR c++/69733
* c-c++-common/pr69733.c: New test.
* gcc.dg/pr69733.c: New test.
* gcc.target/i386/pr69733.c: New test.

Yes, this version is OK too.


It fell through the cracks for a while - now committed.


Bernd



Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-07-21 Thread Jeff Law

On 07/15/2016 07:04 AM, Bernd Schmidt wrote:

On 06/22/2016 05:37 AM, Jeff Law wrote:

It looks like this stalled...

Anyway, it's fine for the trunk.


Some of the surrounding code was changed a bit to produce different
errors for different C standards, so I had to make an adjustment to the
patch. While I was here, I added cdw_atomic to the list of qualifiers to
look for, and added a C-specific testcase for that case.

Retested as before. Ok for this version too?


Bernd

declspecs-v3.diff


c/
PR c++/69733
* c-decl.c (smallest_type_quals_location): New static function.
(grokdeclarator): Try to find the correct location for an ignored
qualifier.
cp/
PR c++/69733
* decl.c (grokdeclarator): Try to find the correct location for an
ignored qualifier.
testsuite/
PR c++/69733
* c-c++-common/pr69733.c: New test.
* gcc.dg/pr69733.c: New test.
* gcc.target/i386/pr69733.c: New test.

Yes, this version is OK too.

jeff


Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-07-15 Thread Bernd Schmidt

On 06/22/2016 05:37 AM, Jeff Law wrote:

It looks like this stalled...

Anyway, it's fine for the trunk.


Some of the surrounding code was changed a bit to produce different 
errors for different C standards, so I had to make an adjustment to the 
patch. While I was here, I added cdw_atomic to the list of qualifiers to 
look for, and added a C-specific testcase for that case.


Retested as before. Ok for this version too?


Bernd
c/
	PR c++/69733
	* c-decl.c (smallest_type_quals_location): New static function.
	(grokdeclarator): Try to find the correct location for an ignored
	qualifier.
cp/
	PR c++/69733
	* decl.c (grokdeclarator): Try to find the correct location for an
	ignored qualifier.
testsuite/
	PR c++/69733
	* c-c++-common/pr69733.c: New test.
	* gcc.dg/pr69733.c: New test.
	* gcc.target/i386/pr69733.c: New test.

Index: gcc/c/c-decl.c
===
--- gcc/c/c-decl.c	(revision 238040)
+++ gcc/c/c-decl.c	(working copy)
@@ -5463,6 +5463,27 @@ warn_defaults_to (location_t location, i
   va_end (ap);
 }
 
+/* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
+   considering only those c_declspec_words found in LIST, which
+   must be terminated by cdw_number_of_elements.  */
+
+static location_t
+smallest_type_quals_location (const location_t *locations,
+			  const c_declspec_word *list)
+{
+  location_t loc = UNKNOWN_LOCATION;
+  while (*list != cdw_number_of_elements)
+{
+  location_t newloc = locations[*list];
+  if (loc == UNKNOWN_LOCATION
+	  || (newloc != UNKNOWN_LOCATION && newloc < loc))
+	loc = newloc;
+  list++;
+}
+
+  return loc;
+}
+
 /* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@@ -6277,7 +6298,19 @@ grokdeclarator (const struct c_declarato
 	   qualify the return type, not the function type.  */
 	if (type_quals)
 	  {
-		int quals_used = type_quals;
+		const enum c_declspec_word ignored_quals_list[] =
+		  {
+		cdw_const, cdw_volatile, cdw_restrict, cdw_address_space,
+		cdw_atomic, cdw_number_of_elements
+		  };
+		location_t specs_loc
+		  = smallest_type_quals_location (declspecs->locations,
+		  ignored_quals_list);
+		if (specs_loc == UNKNOWN_LOCATION)
+		  specs_loc = declspecs->locations[cdw_typedef];
+		if (specs_loc == UNKNOWN_LOCATION)
+		  specs_loc = loc;
+
 		/* Type qualifiers on a function return type are
 		   normally permitted by the standard but have no
 		   effect, so give a warning at -Wreturn-type.
@@ -6287,13 +6320,14 @@ grokdeclarator (const struct c_declarato
 		   DR#423 means qualifiers (other than _Atomic) are
 		   actually removed from the return type when
 		   determining the function type.  */
+		int quals_used = type_quals;
 		if (flag_isoc11)
 		  quals_used &= TYPE_QUAL_ATOMIC;
 		if (quals_used && VOID_TYPE_P (type) && really_funcdef)
-		  pedwarn (loc, 0,
+		  pedwarn (specs_loc, 0,
 			   "function definition has qualified void return type");
 		else
-		  warning_at (loc, OPT_Wignored_qualifiers,
+		  warning_at (specs_loc, OPT_Wignored_qualifiers,
 			   "type qualifiers ignored on function return type");
 
 		/* Ensure an error for restrict on invalid types; the
Index: gcc/cp/decl.c
===
--- gcc/cp/decl.c	(revision 238040)
+++ gcc/cp/decl.c	(working copy)
@@ -10089,8 +10089,15 @@ grokdeclarator (const cp_declarator *dec
 	if (type_quals != TYPE_UNQUALIFIED)
 	  {
 		if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
-		  warning (OPT_Wignored_qualifiers,
-			   "type qualifiers ignored on function return type");
+		  {
+		location_t loc;
+		loc = smallest_type_quals_location (type_quals,
+			declspecs->locations);
+		if (loc == UNKNOWN_LOCATION)
+		  loc = declspecs->locations[ds_type_spec];
+		warning_at (loc, OPT_Wignored_qualifiers, "type "
+"qualifiers ignored on function return type");
+		  }
 		/* We now know that the TYPE_QUALS don't apply to the
 		   decl, but to its return type.  */
 		type_quals = TYPE_UNQUALIFIED;
Index: gcc/testsuite/c-c++-common/pr69733.c
===
--- gcc/testsuite/c-c++-common/pr69733.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr69733.c	(working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-W -fdiagnostics-show-caret" } */
+
+typedef const double cd;
+double val;
+
+const double val0() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ const double val0() {return val;}
+ ^
+{ dg-end-multiline-output "" } */
+
+volatile double val1() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ volatile double val1() {return val;}
+ ^~~~
+{ dg-end-multiline-output "" } */
+
+cd val2() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { 

Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-06-21 Thread Jeff Law

On 05/04/2016 09:17 AM, Bernd Schmidt wrote:

On 04/25/2016 10:18 PM, Joseph Myers wrote:

On Fri, 22 Apr 2016, Bernd Schmidt wrote:


+/* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
+   considering only those c_declspec_words found in LIST, which
+   must be terminated by cdw_number_of_elements.  */
+
+static location_t
+smallest_type_quals_location (const location_t* locations,
+  c_declspec_word *list)


I'd expect list to be a pointer to const...


@@ -6101,6 +6122,18 @@ grokdeclarator (const struct c_declarato
 qualify the return type, not the function type.  */
  if (type_quals)
{
+enum c_declspec_word ignored_quals_list[] =
+  {
+cdw_const, cdw_volatile, cdw_restrict, cdw_address_space,
+cdw_number_of_elements
+  };


  ... and ignored_quals_list to be static const here.


How's this? Fully retested on x86_64-linux.


Bernd

declspecs-v2.diff


c/
PR c++/69733
* c-decl.c (smallest_type_quals_location): New static function.
(grokdeclarator): Try to find the correct location for an ignored
qualifier.
cp/
PR c++/69733
* decl.c (grokdeclarator): Try to find the correct location for an
ignored qualifier.
testsuite/
PR c++/69733
* c-c++-common/pr69733.c: New test.
* gcc.target/i386/pr69733.c: New test.

It looks like this stalled...

Anyway, it's fine for the trunk.

Thanks,
Jeff


Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-06-02 Thread Bernd Schmidt

On 05/04/2016 05:17 PM, Bernd Schmidt wrote:

How's this? Fully retested on x86_64-linux.


Ping.


Bernd




Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-05-04 Thread Bernd Schmidt

On 04/25/2016 10:18 PM, Joseph Myers wrote:

On Fri, 22 Apr 2016, Bernd Schmidt wrote:


+/* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
+   considering only those c_declspec_words found in LIST, which
+   must be terminated by cdw_number_of_elements.  */
+
+static location_t
+smallest_type_quals_location (const location_t* locations,
+ c_declspec_word *list)


I'd expect list to be a pointer to const...


@@ -6101,6 +6122,18 @@ grokdeclarator (const struct c_declarato
   qualify the return type, not the function type.  */
if (type_quals)
  {
+   enum c_declspec_word ignored_quals_list[] =
+ {
+   cdw_const, cdw_volatile, cdw_restrict, cdw_address_space,
+   cdw_number_of_elements
+ };


  ... and ignored_quals_list to be static const here.


How's this? Fully retested on x86_64-linux.


Bernd
c/
	PR c++/69733
	* c-decl.c (smallest_type_quals_location): New static function.
	(grokdeclarator): Try to find the correct location for an ignored
	qualifier.
cp/
	PR c++/69733
	* decl.c (grokdeclarator): Try to find the correct location for an
	ignored qualifier.
testsuite/
	PR c++/69733
	* c-c++-common/pr69733.c: New test.
	* gcc.target/i386/pr69733.c: New test.

Index: gcc/c/c-decl.c
===
--- gcc/c/c-decl.c	(revision 235808)
+++ gcc/c/c-decl.c	(working copy)
@@ -5321,6 +5321,27 @@ warn_defaults_to (location_t location, i
   va_end (ap);
 }
 
+/* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
+   considering only those c_declspec_words found in LIST, which
+   must be terminated by cdw_number_of_elements.  */
+
+static location_t
+smallest_type_quals_location (const location_t* locations,
+			  const c_declspec_word *list)
+{
+  location_t loc = UNKNOWN_LOCATION;
+  while (*list != cdw_number_of_elements)
+{
+  location_t newloc = locations[*list];
+  if (loc == UNKNOWN_LOCATION
+	  || (newloc != UNKNOWN_LOCATION && newloc < loc))
+	loc = newloc;
+  list++;
+}
+
+  return loc;
+}
+
 /* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@@ -6142,6 +6163,18 @@ grokdeclarator (const struct c_declarato
 	   qualify the return type, not the function type.  */
 	if (type_quals)
 	  {
+		const enum c_declspec_word ignored_quals_list[] =
+		  {
+		cdw_const, cdw_volatile, cdw_restrict, cdw_address_space,
+		cdw_number_of_elements
+		  };
+		location_t specs_loc
+		  = smallest_type_quals_location (declspecs->locations,
+		  ignored_quals_list);
+		if (specs_loc == UNKNOWN_LOCATION)
+		  specs_loc = declspecs->locations[cdw_typedef];
+		if (specs_loc == UNKNOWN_LOCATION)
+		  specs_loc = loc;
 		/* Type qualifiers on a function return type are
 		   normally permitted by the standard but have no
 		   effect, so give a warning at -Wreturn-type.
@@ -6149,10 +6182,10 @@ grokdeclarator (const struct c_declarato
 		   function definitions in ISO C; GCC used to used
 		   them for noreturn functions.  */
 		if (VOID_TYPE_P (type) && really_funcdef)
-		  pedwarn (loc, 0,
+		  pedwarn (specs_loc, 0,
 			   "function definition has qualified void return type");
 		else
-		  warning_at (loc, OPT_Wignored_qualifiers,
+		  warning_at (specs_loc, OPT_Wignored_qualifiers,
 			   "type qualifiers ignored on function return type");
 
 		type = c_build_qualified_type (type, type_quals);
Index: gcc/cp/decl.c
===
--- gcc/cp/decl.c	(revision 235808)
+++ gcc/cp/decl.c	(working copy)
@@ -10065,8 +10065,15 @@ grokdeclarator (const cp_declarator *dec
 	if (type_quals != TYPE_UNQUALIFIED)
 	  {
 		if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
-		  warning (OPT_Wignored_qualifiers,
-			   "type qualifiers ignored on function return type");
+		  {
+		location_t loc;
+		loc = smallest_type_quals_location (type_quals,
+			declspecs->locations);
+		if (loc == UNKNOWN_LOCATION)
+		  loc = declspecs->locations[ds_type_spec];
+		warning_at (loc, OPT_Wignored_qualifiers, "type "
+"qualifiers ignored on function return type");
+		  }
 		/* We now know that the TYPE_QUALS don't apply to the
 		   decl, but to its return type.  */
 		type_quals = TYPE_UNQUALIFIED;
Index: gcc/testsuite/c-c++-common/pr69733.c
===
--- gcc/testsuite/c-c++-common/pr69733.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr69733.c	(working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-W -fdiagnostics-show-caret" } */
+
+typedef const double cd;
+double val;
+
+const double val0() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ const double val0() {return val;}
+ ^
+{ 

Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-04-25 Thread Joseph Myers
On Fri, 22 Apr 2016, Bernd Schmidt wrote:

> +/* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
> +   considering only those c_declspec_words found in LIST, which
> +   must be terminated by cdw_number_of_elements.  */
> +
> +static location_t
> +smallest_type_quals_location (const location_t* locations,
> +   c_declspec_word *list)

I'd expect list to be a pointer to const...

> @@ -6101,6 +6122,18 @@ grokdeclarator (const struct c_declarato
>  qualify the return type, not the function type.  */
>   if (type_quals)
> {
> + enum c_declspec_word ignored_quals_list[] =
> +   {
> + cdw_const, cdw_volatile, cdw_restrict, cdw_address_space,
> + cdw_number_of_elements
> +   };

 ... and ignored_quals_list to be static const here.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-04-22 Thread Jason Merrill
The C++ change is OK.

Jason


C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)

2016-04-22 Thread Bernd Schmidt

The PR is for a C++ form of the form

const double val() const { ... }

where the warning location is at the second const (by accident, in 
reality it's just past the function's declarator), while the first const 
is the one that we are warning about.


This patch adds some logic to the C and C++ frontends to look for the 
qualifier, or a typedef name, and point the warning there. C needs a 
little more work because the ignored qualifier could also be an address 
space.


Bootstrapped and tested on x86_64-linux (a while ago, will retest). Ok 
for trunk?



Bernd
c/
	PR c++/69733
	* c-decl.c (smallest_type_quals_location): New static function.
	(grokdeclarator): Try to find the correct location for an ignored
	qualifier.
cp/
	PR c++/69733
	* decl.c (grokdeclarator): Try to find the correct location for an
	ignored qualifier.
testsuite/
	PR c++/69733
	* c-c++-common/pr69733.c: New test.
	* gcc.target/i386/pr69733.c: New test.

Index: gcc/c/c-decl.c
===
--- gcc/c/c-decl.c	(revision 234183)
+++ gcc/c/c-decl.c	(working copy)
@@ -5291,6 +5291,27 @@ warn_defaults_to (location_t location, i
   va_end (ap);
 }
 
+/* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
+   considering only those c_declspec_words found in LIST, which
+   must be terminated by cdw_number_of_elements.  */
+
+static location_t
+smallest_type_quals_location (const location_t* locations,
+			  c_declspec_word *list)
+{
+  location_t loc = UNKNOWN_LOCATION;
+  while (*list != cdw_number_of_elements)
+{
+  location_t newloc = locations[*list];
+  if (loc == UNKNOWN_LOCATION
+	  || (newloc != UNKNOWN_LOCATION && newloc < loc))
+	loc = newloc;
+  list++;
+}
+
+  return loc;
+}
+
 /* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@@ -6101,6 +6122,18 @@ grokdeclarator (const struct c_declarato
 	   qualify the return type, not the function type.  */
 	if (type_quals)
 	  {
+		enum c_declspec_word ignored_quals_list[] =
+		  {
+		cdw_const, cdw_volatile, cdw_restrict, cdw_address_space,
+		cdw_number_of_elements
+		  };
+		location_t specs_loc
+		= smallest_type_quals_location (declspecs->locations,
+		ignored_quals_list);
+		if (specs_loc == UNKNOWN_LOCATION)
+		  specs_loc = declspecs->locations[cdw_typedef];
+		if (specs_loc == UNKNOWN_LOCATION)
+		  specs_loc = loc;
 		/* Type qualifiers on a function return type are
 		   normally permitted by the standard but have no
 		   effect, so give a warning at -Wreturn-type.
@@ -6108,10 +6141,10 @@ grokdeclarator (const struct c_declarato
 		   function definitions in ISO C; GCC used to used
 		   them for noreturn functions.  */
 		if (VOID_TYPE_P (type) && really_funcdef)
-		  pedwarn (loc, 0,
+		  pedwarn (specs_loc, 0,
 			   "function definition has qualified void return type");
 		else
-		  warning_at (loc, OPT_Wignored_qualifiers,
+		  warning_at (specs_loc, OPT_Wignored_qualifiers,
 			   "type qualifiers ignored on function return type");
 
 		type = c_build_qualified_type (type, type_quals);
Index: gcc/cp/decl.c
===
--- gcc/cp/decl.c	(revision 234183)
+++ gcc/cp/decl.c	(working copy)
@@ -10010,8 +10010,15 @@ grokdeclarator (const cp_declarator *dec
 	if (type_quals != TYPE_UNQUALIFIED)
 	  {
 		if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
-		  warning (OPT_Wignored_qualifiers,
-			   "type qualifiers ignored on function return type");
+		  {
+		location_t loc;
+		loc = smallest_type_quals_location (type_quals,
+			declspecs->locations);
+		if (loc == UNKNOWN_LOCATION)
+		  loc = declspecs->locations[ds_type_spec];
+		warning_at (loc, OPT_Wignored_qualifiers, "type "
+"qualifiers ignored on function return type");
+		  }
 		/* We now know that the TYPE_QUALS don't apply to the
 		   decl, but to its return type.  */
 		type_quals = TYPE_UNQUALIFIED;
Index: gcc/testsuite/c-c++-common/pr69733.c
===
--- gcc/testsuite/c-c++-common/pr69733.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr69733.c	(working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-W -fdiagnostics-show-caret" } */
+
+typedef const double cd;
+double val;
+
+const double val0() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ const double val0() {return val;}
+ ^
+{ dg-end-multiline-output "" } */
+
+volatile double val1() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ volatile double val1() {return val;}
+ ^~~~
+{ dg-end-multiline-output "" } */
+
+cd val2() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ cd val2() {return val;}
+ ^~
+{ dg-end-multiline-output "" } */
+
Index: