This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] [PR16169] Improve -Weffc++ item 15


Hello,

this patch improves the diagnostic of -Weffc++ item #15 ("operator= should
return a reference to this") in the following ways:

- Before, we were only checking if the return statement was returning "*this",
but not that the return type was of reference type. Now, we always check if the
return type is a (possibly cv-qualified) reference to the current class.

- To turn off false positives, we shut the warning off if we are returning a
value from a function call: in this case, we are currently unable to check
whether the called function return "*this" (to do this properly, we would need
to move the whole warning handling to the middle-end, in a late tree pass), and
Benjamin Kosnik suggested it is better to not warn at all in this case. I
strongly agree.

Tested by me and Benjamin on i686-pc-linux-gnu, OK for mainline?

Giovanni Bajo


cp/
        * typeck.c (check_return_expr): Improve -Weffc++ warning: handle
        returning CALL_EXPR, and non-reference return type.

testsuite/
        * g++.dg/warn/effc2.C: New test.


Index: typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.553
diff -c -3 -p -r1.553 typeck.c
*** typeck.c 24 Jun 2004 05:26:04 -0000 1.553
--- typeck.c 29 Jun 2004 13:27:44 -0000
*************** check_return_expr (tree retval)
*** 5988,5996 ****

    /* Effective C++ rule 15.  See also start_function.  */
    if (warn_ecpp
!       && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR)
!       && retval != current_class_ref)
!     warning ("`operator=' should return a reference to `*this'");

    /* The fabled Named Return Value optimization, as per [class.copy]/15:

--- 5988,6016 ----

    /* Effective C++ rule 15.  See also start_function.  */
    if (warn_ecpp
!       && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR))
!     {
!       bool warn = true;
!
!       /* The function return type must be a reference to the current
!  class.  */
!       if (TREE_CODE (valtype) == REFERENCE_TYPE
!    && same_type_ignoring_top_level_qualifiers_p
!        (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
!  {
!    /* Returning '*this' is obviously OK.  */
!    if (retval == current_class_ref)
!      warn = false;
!    /* If we are calling a function whose return type is the same of
!       the current class reference, it is ok.  */
!    else if (TREE_CODE (retval) == INDIRECT_REF
!      && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
!      warn = false;
!  }
!
!       if (warn)
!  warning ("`operator=' should return a reference to `*this'");
!     }

    /* The fabled Named Return Value optimization, as per [class.copy]/15:




// { dg-do compile }
// { dg-options "-Weffc++" }
// Contributed by Benjamin Kosnik <bkoz at redhat dot com>
// PR c++/16169 : Improve -Weffc++ rule 15

struct A {
 const A& foo();
 const A& operator=(int)
 { return foo(); }
};

struct B {
  B& foo();
  B& operator=(int)
  { return foo(); }
};

struct C {
  C& operator=(int)
  { return *this; }
};

struct D {
  D operator=(int)
  { return *this; }      // { dg-warning "should return a reference" }
};

struct E {
  E& foo();
  E operator=(int)
  { return foo(); }      // { dg-warning "should return a reference" }
};

struct F
{
  operator float();
  float operator=(int)
  { return *this; }      // { dg-warning "should return a reference" }
};




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]