This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: c/2454
- To: Neil Booth <neil at daikokuya dot demon dot co dot uk>
- Subject: Re: c/2454
- From: "Joseph S. Myers" <jsm28 at cam dot ac dot uk>
- Date: Wed, 6 Jun 2001 21:32:12 +0100 (BST)
- cc: <gcc-gnats at gcc dot gnu dot org>, <gcc-patches at gcc dot gnu dot org>
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