This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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: gcc/testsuite/gcc.target/i386/pr69733.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr69733.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr69733.c	(working copy)
@@ -0,0 +1,30 @@
+/* { 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 "" } */
+
+__seg_fs int val3() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ __seg_fs int val3() {return val;}
+ ^~~~~~~~
+{ dg-end-multiline-output "" } */
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]