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]

Patch applied to cp/typeck.c


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


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