This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch applied to cp/typeck.c
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch applied to cp/typeck.c
- From: Bernd Schmidt <bernds at balti dot cygnus dot co dot uk>
- Date: Wed, 1 Mar 2000 17:15:58 +0000 (GMT)
I've committed the following patch, which was approved by Jason Merrill.
It fixes a problem where we could incorrectly warn about returning a
reference to a temporary. The patch also reorganizes this part of the
code a bit.
Bernd
* typeck.c (maybe_warn_about_returning_address_of_local): Reorganize
to merge reference/pointer code and fix incorrect warnings.
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.250
diff -c -p -r1.250 typeck.c
*** typeck.c 2000/02/27 21:39:39 1.250
--- typeck.c 2000/03/01 17:06:45
*************** maybe_warn_about_returning_address_of_lo
*** 6705,6763 ****
tree retval;
{
tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
! if (TREE_CODE (valtype) == REFERENCE_TYPE)
{
- tree whats_returned;
-
- /* Sort through common things to see what it is
- we are returning. */
- whats_returned = retval;
if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
! {
! whats_returned = TREE_OPERAND (whats_returned, 1);
! if (TREE_CODE (whats_returned) == ADDR_EXPR)
! whats_returned = TREE_OPERAND (whats_returned, 0);
! }
! while (TREE_CODE (whats_returned) == CONVERT_EXPR
! || TREE_CODE (whats_returned) == NOP_EXPR)
whats_returned = TREE_OPERAND (whats_returned, 0);
! if (TREE_CODE (whats_returned) == ADDR_EXPR)
{
whats_returned = TREE_OPERAND (whats_returned, 0);
! while (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
! || TREE_CODE (whats_returned) == TARGET_EXPR)
! {
! /* Get the target. */
! whats_returned = TREE_OPERAND (whats_returned, 0);
! warning ("returning reference to temporary");
! }
}
-
if (TREE_CODE (whats_returned) == VAR_DECL
! && DECL_NAME (whats_returned))
{
! if (TEMP_NAME_P (DECL_NAME (whats_returned)))
! warning ("reference to non-lvalue returned");
! else if (TREE_CODE (TREE_TYPE (whats_returned)) != REFERENCE_TYPE
! && DECL_FUNCTION_SCOPE_P (whats_returned)
! && !(TREE_STATIC (whats_returned)
! || TREE_PUBLIC (whats_returned)))
! cp_warning_at ("reference to local variable `%D' returned",
! whats_returned);
}
}
- else if (TREE_CODE (retval) == ADDR_EXPR)
- {
- tree whats_returned = TREE_OPERAND (retval, 0);
! if (TREE_CODE (whats_returned) == VAR_DECL
! && DECL_NAME (whats_returned)
! && DECL_FUNCTION_SCOPE_P (whats_returned)
! && !(TREE_STATIC (whats_returned)
! || TREE_PUBLIC (whats_returned)))
cp_warning_at ("address of local variable `%D' returned",
whats_returned);
}
}
--- 6705,6760 ----
tree retval;
{
tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
+ tree whats_returned = retval;
! for (;;)
{
if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
! whats_returned = TREE_OPERAND (whats_returned, 1);
! else if (TREE_CODE (whats_returned) == CONVERT_EXPR
! || TREE_CODE (whats_returned) == NON_LVALUE_EXPR
! || TREE_CODE (whats_returned) == NOP_EXPR)
whats_returned = TREE_OPERAND (whats_returned, 0);
! else
! break;
! }
!
! if (TREE_CODE (whats_returned) != ADDR_EXPR)
! return;
! whats_returned = TREE_OPERAND (whats_returned, 0);
!
! if (TREE_CODE (valtype) == REFERENCE_TYPE)
! {
! if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
! || TREE_CODE (whats_returned) == TARGET_EXPR)
{
+ /* Get the target. */
whats_returned = TREE_OPERAND (whats_returned, 0);
! warning ("returning reference to temporary");
! return;
}
if (TREE_CODE (whats_returned) == VAR_DECL
! && DECL_NAME (whats_returned)
! && TEMP_NAME_P (DECL_NAME (whats_returned)))
{
! warning ("reference to non-lvalue returned");
! return;
}
}
! if (TREE_CODE (whats_returned) == VAR_DECL
! && DECL_NAME (whats_returned)
! && DECL_FUNCTION_SCOPE_P (whats_returned)
! && !(TREE_STATIC (whats_returned)
! || TREE_PUBLIC (whats_returned)))
! {
! if (TREE_CODE (valtype) == REFERENCE_TYPE)
! cp_warning_at ("reference to local variable `%D' returned",
! whats_returned);
! else
cp_warning_at ("address of local variable `%D' returned",
whats_returned);
+ return;
}
}