Hi!
Before r253599 check_return_expr would:
if (WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))
|| (retval != NULL_TREE
&& type_dependent_expression_p (retval)))
return retval;
when processing_template_decl, and thus not issue the warning, but now even
type dependent expressions can make it into the assignment operator -Weffc++
warning checks.
There are multiple problems, e.g. in
template <typename T>
struct A {
T &operator=(T &f) {
return *this; // { dg-bogus "should return a reference to" }
}
};
already the:
if (TREE_CODE (valtype) == REFERENCE_TYPE
&& same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
test will fail, even when one can instantiate it with T = A.
The bigger problem is:
/* Returning '*this' is obviously OK. */
if (retval == current_class_ref)
warn = false;
when retval is type dependent expression, it will be usually? built
with build_min and thus == comparison will not work.
The following patch just does what we used to do, not warn with -Weffc++
for type dependent retval expressions, defer that to instantiation.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2018-02-13 Jakub Jelinek <[email protected]>
PR c++/84364
* typeck.c (check_return_expr): Don't emit -Weffc++ warning
about return other than *this in assignment operators if
retval is type dependent expression.
* g++.dg/warn/effc4.C: New test.
--- gcc/cp/typeck.c.jj 2018-02-10 00:15:36.702163326 +0100
+++ gcc/cp/typeck.c 2018-02-13 16:51:04.570204418 +0100
@@ -9232,7 +9232,8 @@ check_return_expr (tree retval, bool *no
/* Effective C++ rule 15. See also start_function. */
if (warn_ecpp
- && DECL_NAME (current_function_decl) == assign_op_identifier)
+ && DECL_NAME (current_function_decl) == assign_op_identifier
+ && !type_dependent_expression_p (retval))
{
bool warn = true;
--- gcc/testsuite/g++.dg/warn/effc4.C.jj 2018-02-13 16:53:16.399220269
+0100
+++ gcc/testsuite/g++.dg/warn/effc4.C 2018-02-13 16:55:10.472233986 +0100
@@ -0,0 +1,10 @@
+// PR c++/84364
+// { dg-do compile }
+// { dg-options "-Weffc++" }
+
+template <typename T>
+struct A {
+ A &operator=(A<T>& f) {
+ return *this; // { dg-bogus "should return a reference to" }
+ }
+};
Jakub