diff options
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/effc2.C | 39 |
4 files changed, 73 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8b0bc21..8aa6b1c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-07-08 Giovanni Bajo <giovannibajo@gcc.gnu.org> + + PR c++/16169 + * typeck.c (check_return_expr): Improve -Weffc++ warning: handle + returning CALL_EXPR, and non-reference return type. + 2004-07-08 Nathan Sidwell <nathan@codesourcery.com> * name-lookup.c (push_binding): Use VEC_reserve. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1588cbc..55b3ef3 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5989,9 +5989,29 @@ check_return_expr (tree retval) /* 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'"); + && 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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 54be7f9..1a3e2c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-07-08 Giovanni Bajo <giovannibajo@gcc.gnu.org> + + PR c++/16169 + * g++.dg/warn/effc2.C: New test. + 2004-07-08 Joseph S. Myers <jsm@polyomino.org.uk> * gcc.c-torture/execute/bitfld-1.x: Remove. diff --git a/gcc/testsuite/g++.dg/warn/effc2.C b/gcc/testsuite/g++.dg/warn/effc2.C new file mode 100644 index 0000000..fb765f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/effc2.C @@ -0,0 +1,39 @@ +// { 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" } +}; |