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  <ja...@redhat.com>

        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

Reply via email to