1 /* PR c/80731 - poor -Woverflow warnings, missing detail
2    { dg-do compile }
3    { dg-options "-Wconversion -Woverflow -Wno-override-init -std=c99" }
4    { dg-require-effective-target int32plus } */
5 
6 #include <limits.h>
7 
8 struct Types
9 {
10   signed char sc;
11   unsigned char uc;
12   signed short ss;
13   unsigned short us;
14   signed int si;
15   unsigned int ui;
16   signed long sl;
17   unsigned long ul;
18   signed long long sll;
19   unsigned long long ull;
20 };
21 
22 const struct Types t1 = {
23   /* According to 6.3.1.3 of C11:
24      -2-  Otherwise, if the new type is unsigned, the value is converted
25 	  by repeatedly adding or subtracting one more than the maximum
26 	  value that can be represented in the new type until the value
27 	  is in the range of the new type.
28 
29      These conversions are diagnosed by -Wsign-conversion and -Wconversion,
30      respectively, by mentioning "unsigned conversion" if the conversion
31      results in sign change, and just "conversion" otherwise, as follows:  */
32 
33   .uc = SCHAR_MIN,          /* { dg-warning "unsigned conversion from .int. to .unsigned char. changes value from .-128. to .128." } */
34   .uc = -1,                 /* { dg-warning "unsigned conversion from .int. to .unsigned char. changes value from .-1. to .255." } */
35 
36   .uc = UCHAR_MAX + 1,      /* { dg-warning "conversion from 'int' to 'unsigned char' changes value from .256. to .0." } */
37   .uc = UCHAR_MAX * 2,      /* { dg-warning "conversion from 'int' to 'unsigned char' changes value from .510. to .254." } */
38 
39   /* According to 6.3.1.3 of C11:
40      -3-  Otherwise, the new type is signed and the value cannot be
41 	  represented in it; either the result is implementation-defined
42 	  or an implementation-defined signal is raised.
43 
44      In GCC such conversions wrap and are diagnosed by mentioning "overflow"
45      if the absolute value of the operand is in excess of the maximum of
46      the destination of type, and "conversion" otherwise, as follows:  */
47 
48   .sc = SCHAR_MAX + 1,      /* { dg-warning "conversion from .int. to .signed char. changes value from .128. to .-128." } */
49   .sc = SCHAR_MAX + 2,      /* { dg-warning "conversion from .int. to .signed char. changes value from .129. to .-127." } */
50   .sc = SCHAR_MAX * 2,      /* { dg-warning "conversion from .int. to .signed char. changes value from .254. to .-2." } */
51   .sc = SCHAR_MAX * 2 + 3,  /* { dg-warning "conversion from .int. to .signed char. changes value from .257. to .1." } */
52   .sc = SCHAR_MAX * 3 + 3,  /* { dg-warning "conversion from .int. to .signed char. changes value from .384. to .-128." } */
53 
54 
55   .ss = SHRT_MAX + 1,       /* { dg-warning "conversion from 'int' to 'short int' changes value from .32768. to .-32768." } */
56   .us = USHRT_MAX + 1,      /* { dg-warning "unsigned conversion from .int. to .short unsigned int. changes value from .65536. to .0." } */
57 
58   .si = INT_MAX + 1LU,      /* { dg-warning "signed conversion from 'long unsigned int. to 'int' changes value from .2147483648. to .-2147483648." } */
59   .ui = UINT_MAX + 1L,      /* { dg-warning "signed conversion from .long int. to .unsigned int. changes value from .4294967296. to .0." "lp64" { target lp64 } } */
60   .ui = UINT_MAX + 1LU,     /* { dg-warning "conversion from .long unsigned int. to .unsigned int. changes value from .4294967296. to .0." "lp64" { target lp64 } } */
61 
62   .sl = LONG_MAX + 1LU,     /* { dg-warning "signed conversion from .long unsigned int. to .long int. changes value from .9223372036854775808. to .-9223372036854775808." "lp64" { target lp64 } } */
63   /* { dg-warning "signed conversion from .long unsigned int. to .long int. changes value from .2147483648. to .-2147483648." "ilp32" { target ilp32 } .-1 } */
64   .ul = ULONG_MAX + 1LU     /* there should be some warning here */
65 };
66