This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] [PR16169] Improve -Weffc++ item 15
- From: "Giovanni Bajo" <giovannibajo at libero dot it>
- To: <gcc-patches at gcc dot gnu dot org>
- Cc: "Jason Merrill" <jason at redhat dot com>,"Benjamin Kosnik" <bkoz at redhat dot com>
- Date: Thu, 8 Jul 2004 04:48:28 +0200
- Subject: [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" }
};