diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2017-05-24 23:16:59 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2017-05-24 23:16:59 +0100 |
commit | d4a760d8c43fa10aa5b450b66f2f4bf67f898a8c (patch) | |
tree | 0b9e9d9dadfb3945f1b82de004c3c56971bdf0ed /gcc | |
parent | 3cd211af9989ca33f08c9d9d7c29ba7cb208b645 (diff) | |
download | gcc-d4a760d8c43fa10aa5b450b66f2f4bf67f898a8c.zip gcc-d4a760d8c43fa10aa5b450b66f2f4bf67f898a8c.tar.gz gcc-d4a760d8c43fa10aa5b450b66f2f4bf67f898a8c.tar.bz2 |
PR c++/80544 strip cv-quals from cast results
gcc/cp:
PR c++/80544
* tree.c (reshape_init): Use unqualified type for direct enum init.
* typeck.c (maybe_warn_about_cast_ignoring_quals): New.
(build_static_cast_1, build_reinterpret_cast_1): Strip cv-quals from
non-class destination types.
(build_const_cast_1): Strip cv-quals from destination types.
(build_static_cast, build_reinterpret_cast, build_const_cast)
(cp_build_c_cast): Add calls to maybe_warn_about_cast_ignoring_quals.
gcc/testsuite:
PR c++/80544
* g++.dg/expr/cast11.C: New test.
From-SVN: r248432
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/decl.c | 1 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 50 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/cast11.C | 41 |
5 files changed, 101 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f2828f8..2982ca7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2017-05-24 Jonathan Wakely <jwakely@redhat.com> + + PR c++/80544 + * tree.c (reshape_init): Use unqualified type for direct enum init. + * typeck.c (maybe_warn_about_cast_ignoring_quals): New. + (build_static_cast_1, build_reinterpret_cast_1): Strip cv-quals from + non-class destination types. + (build_const_cast_1): Strip cv-quals from destination types. + (build_static_cast, build_reinterpret_cast, build_const_cast) + (cp_build_c_cast): Add calls to maybe_warn_about_cast_ignoring_quals. + 2017-05-24 Martin Sebor <msebor@redhat.com> PR c/80731 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index afd47bb..3ff0130 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6043,6 +6043,7 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) if (is_direct_enum_init (type, init)) { tree elt = CONSTRUCTOR_ELT (init, 0)->value; + type = cv_unqualified (type); if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain)) return cp_build_c_cast (type, elt, tf_warning_or_error); else diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 13d90a6..b81d6c8 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6655,9 +6655,7 @@ check_for_casting_away_constness (tree src_type, tree dest_type, } } -/* - Warns if the cast from expression EXPR to type TYPE is useless. - */ +/* Warns if the cast from expression EXPR to type TYPE is useless. */ void maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain) { @@ -6673,6 +6671,20 @@ maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain) } } +/* Warns if the cast ignores cv-qualifiers on TYPE. */ +void +maybe_warn_about_cast_ignoring_quals (tree type, tsubst_flags_t complain) +{ + if (warn_ignored_qualifiers + && complain & tf_warning + && !CLASS_TYPE_P (type) + && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))) + { + warning (OPT_Wignored_qualifiers, "type qualifiers ignored on cast " + "result type"); + } +} + /* Convert EXPR (an expression with pointer-to-member type) to TYPE (another pointer-to-member type in the same hierarchy) and return the converted expression. If ALLOW_INVERSE_P is permitted, a @@ -6746,6 +6758,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, /* Save casted types in the function's used types hash table. */ used_types_insert (type); + /* A prvalue of non-class type is cv-unqualified. */ + if (!CLASS_TYPE_P (type)) + type = cv_unqualified (type); + /* [expr.static.cast] An lvalue of type "cv1 B", where B is a class type, can be cast @@ -7035,7 +7051,10 @@ build_static_cast (tree type, tree expr, tsubst_flags_t complain) if (valid_p) { if (result != error_mark_node) - maybe_warn_about_useless_cast (type, expr, complain); + { + maybe_warn_about_useless_cast (type, expr, complain); + maybe_warn_about_cast_ignoring_quals (type, complain); + } return result; } @@ -7108,6 +7127,10 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, /* Save casted types in the function's used types hash table. */ used_types_insert (type); + /* A prvalue of non-class type is cv-unqualified. */ + if (!CLASS_TYPE_P (type)) + type = cv_unqualified (type); + /* [expr.reinterpret.cast] An lvalue expression of type T1 can be cast to the type "reference to T2" if an expression of type "pointer to T1" can be @@ -7289,7 +7312,10 @@ build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain) r = build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false, /*valid_p=*/NULL, complain); if (r != error_mark_node) - maybe_warn_about_useless_cast (type, expr, complain); + { + maybe_warn_about_useless_cast (type, expr, complain); + maybe_warn_about_cast_ignoring_quals (type, complain); + } return r; } @@ -7335,6 +7361,9 @@ build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain, return error_mark_node; } + /* A prvalue of non-class type is cv-unqualified. */ + dst_type = cv_unqualified (dst_type); + /* Save casted types in the function's used types hash table. */ used_types_insert (dst_type); @@ -7455,7 +7484,10 @@ build_const_cast (tree type, tree expr, tsubst_flags_t complain) r = build_const_cast_1 (type, expr, complain, /*valid_p=*/NULL); if (r != error_mark_node) - maybe_warn_about_useless_cast (type, expr, complain); + { + maybe_warn_about_useless_cast (type, expr, complain); + maybe_warn_about_cast_ignoring_quals (type, complain); + } return r; } @@ -7558,7 +7590,10 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain) if (valid_p) { if (result != error_mark_node) - maybe_warn_about_useless_cast (type, value, complain); + { + maybe_warn_about_useless_cast (type, value, complain); + maybe_warn_about_cast_ignoring_quals (type, complain); + } return result; } @@ -7579,6 +7614,7 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain) tree result_type; maybe_warn_about_useless_cast (type, value, complain); + maybe_warn_about_cast_ignoring_quals (type, complain); /* Non-class rvalues always have cv-unqualified type. */ if (!CLASS_TYPE_P (type)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 003dfa1..cc8e09d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-05-24 Jonathan Wakely <jwakely@redhat.com> + + PR c++/80544 + * g++.dg/expr/cast11.C: New test. + 2017-05-24 Martin Sebor <msebor@redhat.com> PR c/80731 diff --git a/gcc/testsuite/g++.dg/expr/cast11.C b/gcc/testsuite/g++.dg/expr/cast11.C new file mode 100644 index 0000000..01d578a --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/cast11.C @@ -0,0 +1,41 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-Wignored-qualifiers" } +// c++/80544 cast expressions returned cv-qualified prvalues + +template<typename T> void f(T&&) { } +template<typename T> void f(T const&&) = delete; + +template<typename T> void g(T&&) = delete; +template<typename T> void g(T const&&) { } + +struct B { int i; const char c; } b = {}; + +void f1() +{ + int i = 0; + f((long const)i); // { dg-warning "qualifiers ignored" } + f((int* const)&i); // { dg-warning "qualifiers ignored" } + f((int const* const)&i); // { dg-warning "qualifiers ignored" } + f((long* const)&i); // { dg-warning "qualifiers ignored" } + + f(static_cast<long const>(i)); // { dg-warning "qualifiers ignored" } + f(reinterpret_cast<long const>(&i)); // { dg-warning "qualifiers ignored" } + + f(static_cast<int* const>(&i)); // { dg-warning "qualifiers ignored" } + f(const_cast<int* const>(&i)); // { dg-warning "qualifiers ignored" } + f(reinterpret_cast<long* const>(&i)); // { dg-warning "qualifiers ignored" } + + using ptrmem = int B::*; + f(static_cast<ptrmem const>(&B::i)); // { dg-warning "qualifiers ignored" } + f(const_cast<ptrmem const>(&B::i)); // { dg-warning "qualifiers ignored" } + f(reinterpret_cast<ptrmem const>(&B::i)); // { dg-warning "qualifiers ignored" } + + // No warnings, not a cv-qualified type: + using ptrmem2 = const char B::*; + f(static_cast<ptrmem2>(&B::c)); + f(const_cast<ptrmem2>(&B::c)); + f(reinterpret_cast<ptrmem2>(&B::c)); + + // prvalue of class type can have cv-quals: + g(static_cast<const B>(b)); +} |