From 8a14afd0657b21e1de31fd1b2146056b09dbab5b Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Fri, 7 Oct 2016 12:21:55 +0000 Subject: [PATCH] re PR c++/69733 (-Wignored-qualifiers points to wrong const) 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 | 7 +++++ gcc/c/c-decl.c | 40 +++++++++++++++++++++++-- gcc/cp/ChangeLog | 6 ++++ gcc/cp/decl.c | 11 +++++-- gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/c-c++-common/pr69733.c | 24 +++++++++++++++ gcc/testsuite/gcc.dg/pr69733.c | 11 +++++++ gcc/testsuite/gcc.target/i386/pr69733.c | 30 +++++++++++++++++++ 8 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr69733.c create mode 100644 gcc/testsuite/gcc.dg/pr69733.c create mode 100644 gcc/testsuite/gcc.target/i386/pr69733.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 642c20ca553..c5dd848a3e0 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2016-10-07 Bernd Schmidt + + 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 PR c/7652 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 9e32be2e8ed..136f304ca30 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a719f5b6471..f88e16da05a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-10-07 Bernd Schmidt + + PR c++/69733 + * decl.c (grokdeclarator): Try to find the correct location for an + ignored qualifier. + 2016-10-07 Martin Liska * lambda.c (maybe_add_lambda_conv_op): Set default value. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6a08d8f8729..2d11aefbd69 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 49ad223b5f1..f8769a7421c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-10-07 Bernd Schmidt + + 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 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 index 00000000000..57ec1eccb9f --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr69733.c @@ -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 index 00000000000..b4f4621a524 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69733.c @@ -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 index 00000000000..acaf4008a10 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr69733.c @@ -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 "" } */ + -- 2.30.2