re PR c++/69733 (-Wignored-qualifiers points to wrong const)
authorBernd Schmidt <bernds@redhat.com>
Fri, 7 Oct 2016 12:21:55 +0000 (12:21 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Fri, 7 Oct 2016 12:21:55 +0000 (12:21 +0000)
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.

From-SVN: r240863

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr69733.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr69733.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr69733.c [new file with mode: 0644]

index 642c20ca553e617529c8c99f20634f35a60fd074..c5dd848a3e0a006bd08de4204e7edb0e2f81385a 100644 (file)
@@ -1,3 +1,10 @@
+2016-10-07  Bernd Schmidt  <bschmidt@redhat.com>
+
+       PR c++/69733
+       * c-decl.c (smallest_type_quals_location): New static function.
+       (grokdeclarator): Try to find the correct location for an ignored
+       qualifier.
+
 2016-09-26  Marek Polacek  <polacek@redhat.com>
 
        PR c/7652
index 9e32be2e8ed1be7eab8ab3cf5d86524a6b4913e7..136f304ca309ae202c06b41992e6feed0bd51486 100644 (file)
@@ -5448,6 +5448,27 @@ warn_defaults_to (location_t location, int opt, const char *gmsgid, ...)
   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.
@@ -6262,7 +6283,19 @@ grokdeclarator (const struct c_declarator *declarator,
               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.
@@ -6272,13 +6305,14 @@ grokdeclarator (const struct c_declarator *declarator,
                   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 a719f5b647195cb5a426b309737433c6157ca44d..f88e16da05a1267fe0b0feda72461664c5f3432a 100644 (file)
@@ -1,3 +1,9 @@
+2016-10-07  Bernd Schmidt  <bschmidt@redhat.com>
+
+       PR c++/69733
+       * decl.c (grokdeclarator): Try to find the correct location for an
+       ignored qualifier.
+
 2016-10-07  Martin Liska  <mliska@suse.cz>
 
        * lambda.c (maybe_add_lambda_conv_op): Set default value.
index 6a08d8f8729b545bd4bc5973d39991216bceaf7a..2d11aefbd692815a301c9f517800b7bf7f1cd4a5 100644 (file)
@@ -10154,8 +10154,15 @@ grokdeclarator (const cp_declarator *declarator,
            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 49ad223b5f1646a544c29eb70229a459b4e789a7..f8769a7421c44bffe21b22070beec450bcd39965 100644 (file)
@@ -1,3 +1,10 @@
+2016-10-07  Bernd Schmidt  <bschmidt@redhat.com>
+
+       PR c++/69733
+       * c-c++-common/pr69733.c: New test.
+       * gcc.dg/pr69733.c: New test.
+       * gcc.target/i386/pr69733.c: New test.
+
 2016-10-07  Marek Polacek  <polacek@redhat.com>
 
        PR c++/77803
diff --git a/gcc/testsuite/c-c++-common/pr69733.c b/gcc/testsuite/c-c++-common/pr69733.c
new file mode 100644 (file)
index 0000000..57ec1ec
--- /dev/null
@@ -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 "" } */
+
diff --git a/gcc/testsuite/gcc.dg/pr69733.c b/gcc/testsuite/gcc.dg/pr69733.c
new file mode 100644 (file)
index 0000000..b4f4621
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-W -fdiagnostics-show-caret" } */
+
+double val;
+
+_Atomic double val0() {return val;} /* { dg-warning "qualifiers ignored" } */
+/* { dg-begin-multiline-output "" }
+ _Atomic double val0() {return val;}
+ ^~~~~~~
+{ dg-end-multiline-output "" } */
+
diff --git a/gcc/testsuite/gcc.target/i386/pr69733.c b/gcc/testsuite/gcc.target/i386/pr69733.c
new file mode 100644 (file)
index 0000000..acaf400
--- /dev/null
@@ -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 "" } */
+