]>
Commit | Line | Data |
---|---|---|
88fb930d JM |
1 | /* Test for diagnostics for constant overflow. Test with -pedantic-errors. */ |
2 | /* Origin: Joseph Myers <joseph@codesourcery.com> */ | |
3 | /* { dg-do compile } */ | |
4 | /* { dg-options "-std=c99 -pedantic-errors" } */ | |
5 | ||
6 | #include <limits.h> | |
7 | ||
8 | enum e { | |
9 | E0 = INT_MAX, | |
10 | /* Unsigned overflow wraps around. */ | |
11 | E1 = UINT_MAX + 1, | |
12 | /* Overflow in an unevaluated part of an expression is OK (example | |
13 | in the standard). */ | |
14 | E2 = 2 || 1 / 0, | |
ad0637fd MLI |
15 | E3 = 1 / 0, /* { dg-warning "division by zero" } */ |
16 | /* { dg-error "enumerator value for 'E3' is not an integer constant" "enum error" { target *-*-* } 15 } */ | |
88fb930d JM |
17 | /* But as in DR#031, the 1/0 in an evaluated subexpression means the |
18 | whole expression violates the constraints. */ | |
ad0637fd | 19 | E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */ |
928c19bb | 20 | /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { target *-*-* } 19 } */ |
ad0637fd MLI |
21 | E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */ |
22 | /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 21 } */ | |
88fb930d | 23 | /* Again, overflow in evaluated subexpression. */ |
ad0637fd MLI |
24 | E6 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */ |
25 | /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 24 } */ | |
88fb930d JM |
26 | /* A cast does not constitute overflow in conversion. */ |
27 | E7 = (char) INT_MAX | |
28 | }; | |
29 | ||
30 | struct s { | |
31 | int a; | |
ad0637fd | 32 | int : 0 * (1 / 0); /* { dg-warning "division by zero" } */ |
928c19bb | 33 | /* { dg-error "not an integer constant" "integer constant" { target *-*-* } 32 } */ |
ad0637fd | 34 | int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ |
928c19bb | 35 | /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 34 } */ |
88fb930d JM |
36 | }; |
37 | ||
38 | void | |
39 | f (void) | |
40 | { | |
41 | /* This expression is not required to be a constant expression, so | |
42 | it should just involve undefined behavior at runtime. */ | |
ad0637fd | 43 | int c = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */ |
b405ac80 | 44 | |
88fb930d JM |
45 | } |
46 | ||
47 | /* But this expression does need to be constant. */ | |
ad0637fd | 48 | static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */ |
928c19bb | 49 | /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 48 } */ |
88fb930d JM |
50 | |
51 | /* The first two of these involve overflow, so are not null pointer | |
52 | constants. The third has the overflow in an unevaluated | |
53 | subexpression, so is a null pointer constant. */ | |
ad0637fd | 54 | void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ |
928c19bb JM |
55 | /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 54 } */ |
56 | /* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } 54 } */ | |
ad0637fd | 57 | void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ |
4d84fe7c | 58 | /* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } 57 } */ |
928c19bb | 59 | /* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } 57 } */ |
88fb930d JM |
60 | void *r = (1 ? 0 : INT_MAX+1); |
61 | ||
62 | void | |
63 | g (int i) | |
64 | { | |
65 | switch (i) | |
66 | { | |
ad0637fd | 67 | case 0 * (1/0): /* { dg-warning "division by zero" } */ |
928c19bb | 68 | /* { dg-error "case label does not reduce to an integer constant" "constant" { target *-*-* } 67 } */ |
88fb930d | 69 | ; |
ad0637fd | 70 | case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */ |
928c19bb | 71 | /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 70 } */ |
88fb930d JM |
72 | ; |
73 | } | |
74 | } | |
75 | ||
76 | int | |
77 | h (void) | |
78 | { | |
ad0637fd | 79 | return INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */ |
88fb930d JM |
80 | } |
81 | ||
82 | int | |
83 | h1 (void) | |
84 | { | |
ad0637fd | 85 | return INT_MAX + 1 - INT_MAX; /* { dg-warning "integer overflow in expression" } */ |
88fb930d JM |
86 | } |
87 | ||
88 | void fuc (unsigned char); | |
89 | void fsc (signed char); | |
90 | ||
91 | void | |
92 | h2 (void) | |
93 | { | |
ad0637fd MLI |
94 | fsc (SCHAR_MAX + 1); /* { dg-warning "overflow in implicit constant conversion" } */ |
95 | fsc (SCHAR_MIN - 1); /* { dg-warning "overflow in implicit constant conversion" } */ | |
96 | fsc (UCHAR_MAX); /* { dg-warning "overflow in implicit constant conversion" } */ | |
97 | fsc (UCHAR_MAX + 1); /* { dg-warning "overflow in implicit constant conversion" } */ | |
88fb930d | 98 | fuc (-1); |
ad0637fd | 99 | fuc (UCHAR_MAX + 1); /* { dg-warning "large integer implicitly truncated to unsigned type" } */ |
88fb930d | 100 | fuc (SCHAR_MIN); |
ad0637fd MLI |
101 | fuc (SCHAR_MIN - 1); /* { dg-warning "large integer implicitly truncated to unsigned type" } */ |
102 | fuc (-UCHAR_MAX); /* { dg-warning "large integer implicitly truncated to unsigned type" } */ | |
88fb930d JM |
103 | } |
104 | ||
105 | void fui (unsigned int); | |
106 | void fsi (signed int); | |
107 | ||
108 | int si; | |
109 | unsigned ui; | |
110 | ||
111 | void | |
112 | h2i (int x) | |
113 | { | |
114 | /* For some reason, we only give certain warnings for implicit | |
115 | conversions among values of the same precision with -Wconversion, | |
116 | while we don't give others at all. */ | |
117 | fsi ((unsigned)INT_MAX + 1); | |
118 | si = (unsigned)INT_MAX + 1; | |
119 | si = x ? (unsigned)INT_MAX + 1 : 1; | |
120 | fsi ((unsigned)INT_MAX + 2); | |
121 | si = (unsigned)INT_MAX + 2; | |
122 | si = x ? (unsigned)INT_MAX + 2 : 1; | |
123 | fsi (UINT_MAX); | |
124 | si = UINT_MAX; | |
125 | fui (-1); | |
126 | ui = -1; | |
127 | ui = x ? -1 : 1U; | |
128 | fui (INT_MIN); | |
129 | ui = INT_MIN; | |
130 | ui = x ? INT_MIN : 1U; | |
131 | } |