Bug 40335 - The implement of Switch statment is against with C++ standard
Summary: The implement of Switch statment is against with C++ standard
Status: RESOLVED DUPLICATE of bug 39371
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.0
: P3 critical
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, wrong-code
Depends on:
Blocks:
 
Reported: 2009-06-04 08:13 UTC by ShenRuifen
Modified: 2019-09-18 23:08 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 2.95.4
Known to fail: 3.3.6 4.3.3
Last reconfirmed: 2009-06-04 10:05:43


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ShenRuifen 2009-06-04 08:13:40 UTC
Source code: 1.cpp
#include <stdio.h>
static int i;

int
main (void)
{
  i = -1; 
  switch ((signed char) i) {
  case 255:
    printf("255\n");
    break;
  default:
    printf("default\n");
    break;
  }
}

Compiling command  : g++ 1.cpp && ./a.out
result             : 255
The expected result: default  

According to C++ standard, an integral promotion of expression "(signed char) i" should be performed firstly, the result of control expression should be 0xffff; then the label of case statment will be converted to int-type. So the expected result should be default in my opinion. 

Thanks very much.

C++ standard:
The condition shall be of integral type, enumeration type, or of a class type for which a single conversion function to integral or enumeration type exists (12.3). If the condition is of class type, the condition is converted by calling that conversion function, and the result of the conversion is used in place of the original condition for the remainder of this section. 
Integral promotions are performed.
Any statement within the switch statement can be labeled with one or more case labels as follows:
case constant-expression :
where the constant-expression shall be an integral constant-expression. The integral constant-expression (5.19) is implicitly converted to the promoted type of the switch condition.
Comment 1 Richard Biener 2009-06-04 09:04:11 UTC
Integral promotion is performed on the switch argument, thus signed char -1
is sign-extended to int -1.  You probably want (unsigned char) i instead.
Comment 2 ShenRuifen 2009-06-04 09:09:04 UTC
The expected result should be -1, not 255.
But the result is 255 when I use g++ to compiling this code.
Comment 3 ShenRuifen 2009-06-04 09:47:43 UTC
I have debug the C++ front-end of gcc3.3.5.
In function finish_switch_cond:
	
      if (cond != error_mark_node)
	{
	  cond = default_conversion (cond);
	  cond = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (cond), cond));
	}

SRF: the type of cond is "int"

      if (cond != error_mark_node)
	{
	  index = get_unwidened (cond, 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 (cond))
	      == TREE_UNSIGNED (TREE_TYPE (index)))
	    cond = index;
	}

SRF: bug the type of cond is back to "signed char" here.....
     Maybe there is something error in function "get_unwidened" 
Comment 4 Richard Biener 2009-06-04 10:05:42 UTC
GCC 3.3 is very old and no longer maintained.

> g++-4.4 -o t t.C
t.C: In function ‘int main()’:
t.C:9: warning: case label value exceeds maximum value for type

which seems indeed bogus (but hints at what happens).

The C frontend correctly dispatches to the default case but still warns:

> gcc-4.4 -o t t.c -Wall
t.c: In function ‘main’:
t.c:9: warning: case label value exceeds maximum value for type
t.c:16: warning: control reaches end of non-void function
Comment 5 ShenRuifen 2009-06-04 10:24:02 UTC
Thanks very much.
Waiting for your patch. the patch of gcc3.3.5 is also expected if you have enough time to do it. it should be similar with gcc4.**
Thanks agian. 
Comment 6 Paolo Carlini 2009-06-04 10:45:47 UTC
Note that 3_4-branch, 4_0-branch, 4_1-branch, 4_2-branch are all closed.
Comment 7 Richard Biener 2009-06-04 11:16:33 UTC
Oh, 4.4 and 4.5 already work.

*** This bug has been marked as a duplicate of 39371 ***