This is the mail archive of the gcc-bugs@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]
Other format: [Raw text]

Re: va_arg regression from 2.95.2 to 3.1


On Wed, Mar 27, 2002 at 05:24:07PM +0000, Nathan Sidwell wrote:
> "Joseph S. Myers" wrote:
> 
> > I think the argument is correct, and that this call to va_arg should be
> > considered the same as a call where the types turn out to be incompatible
> > at runtime (except here, the runtime type cannot be compatible).  It ought
> > to be a mandatory warning (not pedwarn, not error); and should either be
> > compiled into a call to abort() or be treated as a call to va_arg with the
> > promoted type followed by conversion to the type specified.
> I agree.

Ok, two's good enough.  Addressed as follows.


r~


        * builtins.c (expand_builtin_va_arg): Give warnings not errors for
        promoted argument types; build trap.
        (expand_builtin_trap): New.
        (expand_builtin): Use it.
        * stmt.c (expand_nl_goto_receivers): Likewise.
        * expr.h (expand_builtin_trap): Declare.
        * libfuncs.h (LTI_abort, abort_libfunc): New.
        * optabs.c (init_optabs): Init abort_libfunc.

        * gcc.dg/va-arg-1.c: Expect warnings, not errors.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.142.2.1
diff -c -p -d -r1.142.2.1 builtins.c
*** builtins.c	2002/03/08 13:39:50	1.142.2.1
--- builtins.c	2002/03/31 09:36:28
*************** expand_builtin_va_arg (valist, type)
*** 3081,3087 ****
    else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
      {
        const char *name = "<anonymous type>", *pname = 0;
!       static int gave_help;
  
        if (TYPE_NAME (type))
  	{
--- 3081,3087 ----
    else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
      {
        const char *name = "<anonymous type>", *pname = 0;
!       static bool gave_help;
  
        if (TYPE_NAME (type))
  	{
*************** expand_builtin_va_arg (valist, type)
*** 3100,3112 ****
  	    pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
  	}
  
!       error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
        if (! gave_help)
  	{
! 	  gave_help = 1;
! 	  error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
  	}
  
        addr = const0_rtx;
      }
    else
--- 3100,3123 ----
  	    pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
  	}
  
!       /* Unfortunately, this is merely undefined, rather than a constraint
! 	 violation, so we cannot make this an error.  If this call is never
! 	 executed, the program is still strictly conforming.  */
!       warning ("`%s' is promoted to `%s' when passed through `...'",
! 	       name, pname);
        if (! gave_help)
  	{
! 	  gave_help = true;
! 	  warning ("(so you should pass `%s' not `%s' to `va_arg')",
! 		   pname, name);
  	}
  
+       /* We can, however, treat "undefined" any way we please.
+ 	 Call abort to encourage the user to fix the program.  */
+       expand_builtin_trap ();
+ 
+       /* This is dead code, but go ahead and finish so that the
+ 	 mode of the result comes out right.  */
        addr = const0_rtx;
      }
    else
*************** expand_builtin_expect_jump (exp, if_fals
*** 3558,3563 ****
--- 3569,3586 ----
  
    return ret;
  }
+ 
+ void
+ expand_builtin_trap ()
+ {
+ #ifdef HAVE_trap
+   if (HAVE_trap)
+     emit_insn (gen_trap ());
+   else
+ #endif
+     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
+   emit_barrier ();
+ }
  
  /* Expand an expression EXP that calls a built-in function,
     with result going to TARGET if that's convenient
*************** expand_builtin (exp, target, subtarget, 
*** 3892,3904 ****
  	}
  
      case BUILT_IN_TRAP:
! #ifdef HAVE_trap
!       if (HAVE_trap)
! 	emit_insn (gen_trap ());
!       else
! #endif
! 	error ("__builtin_trap not supported by this target");
!       emit_barrier ();
        return const0_rtx;
  
      case BUILT_IN_PUTCHAR:
--- 3915,3921 ----
  	}
  
      case BUILT_IN_TRAP:
!       expand_builtin_trap ();
        return const0_rtx;
  
      case BUILT_IN_PUTCHAR:
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.110.2.2
diff -c -p -d -r1.110.2.2 expr.h
*** expr.h	2002/03/26 22:21:59	1.110.2.2
--- expr.h	2002/03/31 09:36:28
*************** extern rtx get_condition PARAMS ((rtx, r
*** 340,346 ****
  extern rtx gen_cond_trap PARAMS ((enum rtx_code, rtx, rtx, rtx));
  
  /* Functions from builtins.c:  */
- #ifdef TREE_CODE
  extern rtx expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
  extern void std_expand_builtin_va_start PARAMS ((int, tree, rtx));
  extern rtx std_expand_builtin_va_arg PARAMS ((tree, tree));
--- 340,345 ----
*************** extern rtx expand_builtin_va_arg PARAMS 
*** 348,359 ****
  extern void default_init_builtins PARAMS ((void));
  extern rtx default_expand_builtin PARAMS ((tree, rtx, rtx,
  					   enum machine_mode, int));
- #endif
- 
  extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
  extern void expand_builtin_setjmp_receiver PARAMS ((rtx));
  extern void expand_builtin_longjmp PARAMS ((rtx, rtx));
  extern rtx expand_builtin_saveregs PARAMS ((void));
  extern HOST_WIDE_INT get_varargs_alias_set PARAMS ((void));
  extern HOST_WIDE_INT get_frame_alias_set PARAMS ((void));
  extern void record_base_value		PARAMS ((unsigned int, rtx, int));
--- 347,357 ----
  extern void default_init_builtins PARAMS ((void));
  extern rtx default_expand_builtin PARAMS ((tree, rtx, rtx,
  					   enum machine_mode, int));
  extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
  extern void expand_builtin_setjmp_receiver PARAMS ((rtx));
  extern void expand_builtin_longjmp PARAMS ((rtx, rtx));
  extern rtx expand_builtin_saveregs PARAMS ((void));
+ extern void expand_builtin_trap PARAMS ((void));
  extern HOST_WIDE_INT get_varargs_alias_set PARAMS ((void));
  extern HOST_WIDE_INT get_frame_alias_set PARAMS ((void));
  extern void record_base_value		PARAMS ((unsigned int, rtx, int));
Index: libfuncs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libfuncs.h,v
retrieving revision 1.3
diff -c -p -d -r1.3 libfuncs.h
*** libfuncs.h	2001/12/05 22:37:29	1.3
--- libfuncs.h	2002/03/31 09:36:28
*************** enum libfunc_index
*** 36,41 ****
--- 36,42 ----
    LTI_truncxfdf2,
    LTI_trunctfdf2,
  
+   LTI_abort,
    LTI_memcpy,
    LTI_memmove,
    LTI_bcopy,
*************** extern rtx libfunc_table[LTI_MAX];
*** 162,167 ****
--- 163,169 ----
  #define truncxfdf2_libfunc	(libfunc_table[LTI_truncxfdf2])
  #define trunctfdf2_libfunc	(libfunc_table[LTI_trunctfdf2])
  
+ #define abort_libfunc	(libfunc_table[LTI_abort])
  #define memcpy_libfunc	(libfunc_table[LTI_memcpy])
  #define memmove_libfunc	(libfunc_table[LTI_memmove])
  #define bcopy_libfunc	(libfunc_table[LTI_bcopy])
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.124
diff -c -p -d -r1.124 optabs.c
*** optabs.c	2002/02/24 21:43:52	1.124
--- optabs.c	2002/03/31 09:36:29
*************** init_optabs ()
*** 4945,4950 ****
--- 4945,4951 ----
    truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
    trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
  
+   abort_libfunc = init_one_libfunc ("abort");
    memcpy_libfunc = init_one_libfunc ("memcpy");
    memmove_libfunc = init_one_libfunc ("memmove");
    bcopy_libfunc = init_one_libfunc ("bcopy");
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.248
diff -c -p -d -r1.248 stmt.c
*** stmt.c	2002/02/22 21:09:07	1.248
--- stmt.c	2002/03/31 09:36:29
*************** expand_nl_goto_receivers (thisblock)
*** 3666,3674 ****
    if (any_invalid)
      {
        expand_nl_goto_receiver ();
!       emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "abort"), LCT_NORETURN,
! 			 VOIDmode, 0);
!       emit_barrier ();
      }
  
    nonlocal_goto_handler_labels = label_list;
--- 3666,3672 ----
    if (any_invalid)
      {
        expand_nl_goto_receiver ();
!       expand_builtin_trap ();
      }
  
    nonlocal_goto_handler_labels = label_list;
Index: testsuite/gcc.dg/va-arg-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/va-arg-1.c,v
retrieving revision 1.1
diff -c -p -d -r1.1 va-arg-1.c
*** testsuite/gcc.dg/va-arg-1.c	1999/09/08 04:51:16	1.1
--- testsuite/gcc.dg/va-arg-1.c	2002/03/31 09:36:29
*************** volatile int i;
*** 7,13 ****
  
  void foo()
  {
!   i = va_arg(v, char); /* { dg-error "is promoted to|so you should" "char" } */
!   i = va_arg(v, short); /* { dg-error "is promoted to" "short" } */
!   i = va_arg(v, float); /* { dg-error "is promoted to" "float" } */
  }
--- 7,13 ----
  
  void foo()
  {
!   i = va_arg(v, char); /* { dg-warning "is promoted to|so you should" "char" } */
!   i = va_arg(v, short); /* { dg-warning "is promoted to" "short" } */
!   i = va_arg(v, float); /* { dg-warning "is promoted to" "float" } */
  }


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