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]

Re: c/2454


On 6 Jun 2001, Neil Booth wrote:

>  jsm28@gcc.gnu.org wrote:-
>  
>  >      Confirmed as a bug, and a regression from 2.95.  A small
>  >      testcase is
>  >      
>  >      static int i;
>  >      
>  >      int
>  >      main (void)
>  >      {
>  >        i = -1;
>  >        switch((signed char) i) {
>  >        case 255:
>  >          abort ();
>  >        default:
>  >          exit (0);
>  >        }
>  >      }
>  
>  Ugh.  These signedness-of-less-than-int issues seem to be endless.

This bug is more complicated than I'd hoped.  I think the patch below 
addresses a C front end bug that is part of the problem - we shouldn't 
strip type conversions from the switch case expression.  (2.95 did strip 
them, but then gave a warning that the case value was out of range.  3.0 
converts the case value, as required by the C standard - but the 
conversion should be to the promoted type, int, not signed char.)  
However, after this patch the testcase still fails with -O2, -Os, -O3.  
Could someone familiar with the optimizers take a look at this?  This is a 
regression, but not currently marked as "high".

2001-06-06  Joseph S. Myers  <jsm28@cam.ac.uk>

	* c-typeck.c (c_start_case): Don't strip conversions from the
	controlling expression.  Partially fixes PR c/2454.

2001-06-06  Joseph S. Myers  <jsm28@cam.ac.uk>

	* gcc.c-torture/execute/20010606-1.c: New test.

--- c-typeck.c.orig	Tue Jun  5 07:05:47 2001
+++ c-typeck.c	Wed Jun  6 16:54:11 2001
@@ -7044,7 +7044,6 @@
 	}
       else
 	{
-	  tree index;
 	  type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
 
 	  if (warn_traditional && !in_system_header
@@ -7054,14 +7053,6 @@
 
 	  exp = default_conversion (exp);
 	  type = TREE_TYPE (exp);
-	  index = get_unwidened (exp, NULL_TREE);
-	  /* 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 (index)))
-	    exp = index;
 	}
     }
 
--- testsuite/gcc.c-torture/execute/20010606-1.c	Mon Mar 26 23:57:02 2001
+++ testsuite/gcc.c-torture/execute/20010606-1.c	Wed Jun  6 16:53:01 2001
@@ -0,0 +1,22 @@
+/* Origin: Joseph Myers <jsm28@cam.ac.uk>.  */
+/* Case labels in a switch statement are converted to the promoted
+   type of the controlling expression, not an unpromoted version.
+   Reported as PR c/2454 by
+   Andreas Krakowczyk <Andreas.Krakowczyk@fujitsu-siemens.com>.  */
+
+extern void exit (int);
+extern void abort (void);
+
+static int i;
+
+int
+main (void)
+{
+  i = -1;
+  switch((signed char) i) {
+  case 255:
+    abort ();
+  default:
+    exit (0);
+  }
+}

-- 
Joseph S. Myers
jsm28@cam.ac.uk


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