[C++] Fix -Weffc++ warning on return in assignment op in templates (PR c++/84364)

Message ID 20180213211129.GV5867@tucnak
State New
Headers show
Series
  • [C++] Fix -Weffc++ warning on return in assignment op in templates (PR c++/84364)
Related show

Commit Message

Jakub Jelinek Feb. 13, 2018, 9:11 p.m.
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  <jakub@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.


	Jakub

Patch

--- 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" }
+  }
+};