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