This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)
- From: Bernd Schmidt <bernds_cb1 at t-online dot de>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Bernd Schmidt <bschmidt at redhat dot com>, "Joseph S. Myers" <joseph at codesourcery dot com>, Jason Merrill <jason at redhat dot com>
- Date: Fri, 22 Apr 2016 15:26:47 +0200
- Subject: C, C++: Fix PR 69733 (bad location for ignored qualifiers warning)
- Authentication-results: sourceware.org; auth=none
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 "" } */
+