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]

C++ PATCH for switch-statement bug



We were still converting the conditions in a switch statement at
RTL-generation time, rather than semantic-analysis time.  Here's the
fix.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-12-09  Mark Mitchell  <mark@codesourcery.com>

	* semantics.c (finish_switch_cond): Do conversions here, not ...
	* typeck.c (c_expand_start_case): Here.

Index: semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.112
diff -c -p -r1.112 semantics.c
*** semantics.c	1999/12/05 00:49:26	1.112
--- semantics.c	1999/12/09 09:02:21
*************** finish_switch_cond (cond, switch_stmt)
*** 592,598 ****
       tree switch_stmt;
  {
    if (building_stmt_tree ())
!     FINISH_COND (cond, switch_stmt, SWITCH_COND (switch_stmt));
    else if (cond != error_mark_node)
      {
        emit_line_note (input_filename, lineno);
--- 592,628 ----
       tree switch_stmt;
  {
    if (building_stmt_tree ())
!     {
!       if (!processing_template_decl)
! 	{
! 	  /* Convert the condition to an integer or enumeration type.  */
! 	  cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, 1);
! 	  if (cond == NULL_TREE)
! 	    {
! 	      error ("switch quantity not an integer");
! 	      cond = error_mark_node;
! 	    }
! 	  if (cond != error_mark_node)
! 	    {
! 	      tree idx;
! 	      tree type;
! 	      
! 	      cond = default_conversion (cond);
! 	      type = TREE_TYPE (cond);
! 	      idx = get_unwidened (cond, 0);
! 	      /* We can't strip a conversion from a signed type to an unsigned,
! 		 because if we did, int_fits_type_p would do the wrong thing
! 		 when checking case values for being in range,
! 		 and it's too hard to do the right thing.  */
! 	      if (TREE_UNSIGNED (TREE_TYPE (cond)) 
! 		  == TREE_UNSIGNED (TREE_TYPE (idx)))
! 		cond = idx;
! 
! 	      cond = fold (build1 (CLEANUP_POINT_EXPR, type, cond));
! 	    }
! 	}
!       FINISH_COND (cond, switch_stmt, SWITCH_COND (switch_stmt));
!     }
    else if (cond != error_mark_node)
      {
        emit_line_note (input_filename, lineno);
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.227
diff -c -p -r1.227 typeck.c
*** typeck.c	1999/12/01 18:09:09	1.227
--- typeck.c	1999/12/09 09:02:27
*************** tree
*** 6874,6903 ****
  c_expand_start_case (exp)
       tree exp;
  {
!   tree type, idx;
! 
!   exp = build_expr_type_conversion (WANT_INT | WANT_ENUM, exp, 1);
!   if (exp == NULL_TREE)
!     {
!       error ("switch quantity not an integer");
!       exp = error_mark_node;
!     }
!   if (exp == error_mark_node)
!     return error_mark_node;
! 
!   exp = default_conversion (exp);
!   type = TREE_TYPE (exp);
!   idx = get_unwidened (exp, 0);
!   /* We can't strip a conversion from a signed type to an unsigned,
!      because if we did, int_fits_type_p would do the wrong thing
!      when checking case values for being in range,
!      and it's too hard to do the right thing.  */
!   if (TREE_UNSIGNED (TREE_TYPE (exp)) == TREE_UNSIGNED (TREE_TYPE (idx)))
!     exp = idx;
! 
!   expand_start_case
!     (1, fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp)),
!      type, "switch statement");
  
    return exp;
  }
--- 6874,6880 ----
  c_expand_start_case (exp)
       tree exp;
  {
!   expand_start_case (1, exp, TREE_TYPE (exp), "switch statement");
  
    return exp;
  }


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