111
|
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 };
|