This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.


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

Re: Problem with Nov 21 1997 valops.c:call_function_by_hand change (revisited)


> Your change causes minimal disturbance, and fixes the PR without
> introducing other problems, but I'm not sure it is the right thing.
> And I do mean "not sure."
> 
> I used value_cast because I wanted to correctly pass arguments to
> prototyped functions whose formal parameters had small integer types.
> The present logic in value_arg_coerce always widens everything to an
> int.  (ANSI C says no promotion should take place, but this isn't a
> standards issue, it's an ABI issue.)  Do all ABI's really specify that
> small integer arguments are always passed as int-sized values?

Would you prefer the following approach to the problem ?

*** gdb/valops.c.orig	Fri Jan 23 16:43:59 1998
--- gdb/valops.c	Tue May 19 17:20:50 1998
***************
*** 47,53 ****
  
  #ifdef CALL_DUMMY
  static CORE_ADDR find_function_addr PARAMS ((value_ptr, struct type **));
! static value_ptr value_arg_coerce PARAMS ((value_ptr, struct type *));
  #endif
  
  
--- 47,53 ----
  
  #ifdef CALL_DUMMY
  static CORE_ADDR find_function_addr PARAMS ((value_ptr, struct type **));
! static value_ptr value_arg_coerce PARAMS ((value_ptr, struct type *, int));
  #endif
  
  
***************
*** 952,963 ****
  /* Perform the standard coercions that are specified
     for arguments to be passed to C functions.
  
!    If PARAM_TYPE is non-NULL, it is the expected parameter type. */
  
  static value_ptr
! value_arg_coerce (arg, param_type)
       value_ptr arg;
       struct type *param_type;
  {
    register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
    register struct type *type
--- 952,965 ----
  /* Perform the standard coercions that are specified
     for arguments to be passed to C functions.
  
!    If PARAM_TYPE is non-NULL, it is the expected parameter type.
!    IS_PROTOTYPED is non-zero if the function declaration is prototyped.  */
  
  static value_ptr
! value_arg_coerce (arg, param_type, is_prototyped)
       value_ptr arg;
       struct type *param_type;
+      int is_prototyped;
  {
    register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
    register struct type *type
***************
*** 977,995 ****
      case TYPE_CODE_CHAR:
      case TYPE_CODE_BOOL:
      case TYPE_CODE_ENUM:
        if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
  	type = builtin_type_int;
        break;
!    case TYPE_CODE_FLT:
!      /* coerce float to double, unless the function prototype specifies float */
!      if (COERCE_FLOAT_TO_DOUBLE)
!        {
! 	 if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
! 	   type = builtin_type_double;
! 	 else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
! 	   type = builtin_type_long_double;
!        }
!      break;
      case TYPE_CODE_FUNC:
        type = lookup_pointer_type (type);
        break;
--- 979,1009 ----
      case TYPE_CODE_CHAR:
      case TYPE_CODE_BOOL:
      case TYPE_CODE_ENUM:
+       /* If we don't have a prototype, coerce to integer type if necessary.  */
+       if (!is_prototyped)
+ 	{
+ 	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ 	    type = builtin_type_int;
+ 	}
+       /* Currently all target ABIs require at least the width of an integer
+ 	 type for an argument.  We may have to conditionalize the following
+ 	 type coercion for future targets.  */
        if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
  	type = builtin_type_int;
        break;
!     case TYPE_CODE_FLT:
!       /* FIXME: We should always convert floats to doubles in the
! 	 non-prototyped case.  As many debugging formats include
! 	 no information about prototyping, we have to live with
! 	 COERCE_FLOAT_TO_DOUBLE for now.  */
!       if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE)
! 	{
! 	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
! 	    type = builtin_type_double;
! 	  else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
! 	    type = builtin_type_long_double;
! 	}
!       break;
      case TYPE_CODE_FUNC:
        type = lookup_pointer_type (type);
        break;
***************
*** 1222,1240 ****
  	 promotions.  FIXME: if we had a prototype, this should only
  	 be allowed if ... were present.  */
        if (i >= TYPE_NFIELDS (ftype))
! 	args[i] = value_arg_coerce (args[i], 0);
  
        else 
  	{
  	  struct type *param_type = TYPE_FIELD_TYPE (ftype, i);
  
! 	  /* If we have a prototype, cast as for assignment.  */
! 	  if (TYPE_FLAGS (ftype) & TYPE_FLAG_PROTOTYPED)
! 	    args[i] = value_cast (param_type, args[i]);
! 
! 	  /* Otherwise, do the standard promotions.  */
! 	  else
! 	    args[i] = value_arg_coerce (args[i], param_type);
  	}
      }
  
--- 1236,1249 ----
  	 promotions.  FIXME: if we had a prototype, this should only
  	 be allowed if ... were present.  */
        if (i >= TYPE_NFIELDS (ftype))
! 	args[i] = value_arg_coerce (args[i], NULL, 0);
  
        else 
  	{
  	  struct type *param_type = TYPE_FIELD_TYPE (ftype, i);
+ 	  int is_prototyped = TYPE_FLAGS (ftype) & TYPE_FLAG_PROTOTYPED;
  
! 	  args[i] = value_arg_coerce (args[i], param_type, is_prototyped);
  	}
      }
  

-- 
Peter Schauer			pes@regent.e-technik.tu-muenchen.de