1 /* Verify that we handle functions with __attribute__ ((const)) correctly. */
3 #include "analyzer-decls.h"
5 extern int nonconst_fn (int);
7 extern int const_fn_0 () __attribute__ ((const));
8 extern int const_fn_1 (int) __attribute__ ((const));
9 extern int const_fn_2 (int, int) __attribute__ ((const));
10 extern int const_fn_3 (int, int, int) __attribute__ ((const));
11 extern int const_fn_variadic (int, ...) __attribute__ ((const));
13 /* Verify that functions without __attribute__ ((const)) have a different
16 void test_nonconst_fn (int x
, int y
)
18 int x_1
= nonconst_fn (x
);
19 int x_2
= nonconst_fn (x
);
20 int y_1
= nonconst_fn (y
);
21 int y_2
= nonconst_fn (y
);
22 __analyzer_eval (x_1
== x_2
); /* { dg-warning "UNKNOWN" } */
23 __analyzer_eval (y_1
== y_2
); /* { dg-warning "UNKNOWN" } */
24 __analyzer_eval (x_1
== y_1
); /* { dg-warning "UNKNOWN" } */
27 /* Verify functions with __attribute__ ((const)) have the same result
28 for the same arguments. */
32 extern int other_const_fn_0 () __attribute__ ((const));
34 void test_const_fn_0 (void)
36 int a
= const_fn_0 ();
37 int b
= const_fn_0 ();
38 int c
= other_const_fn_0 ();
39 int d
= other_const_fn_0 ();
40 __analyzer_eval (a
== b
); /* { dg-warning "TRUE" } */
41 __analyzer_eval (c
== d
); /* { dg-warning "TRUE" } */
42 __analyzer_eval (a
== c
); /* { dg-warning "UNKNOWN" } */
47 void test_const_fn_1 (int x
, int y
)
49 int x_1
= const_fn_1 (x
);
50 int x_2
= const_fn_1 (x
);
51 int y_1
= const_fn_1 (y
);
52 int y_2
= const_fn_1 (y
);
53 __analyzer_eval (x_1
== x_2
); /* { dg-warning "TRUE" } */
54 __analyzer_eval (y_1
== y_2
); /* { dg-warning "TRUE" } */
55 __analyzer_eval (x_1
== y_1
); /* { dg-warning "UNKNOWN" } */
60 void test_const_fn_2 (int x
, int y
, int p
, int q
)
62 int xy_1
= const_fn_2 (x
, y
);
63 int xy_2
= const_fn_2 (x
, y
);
64 int pq_1
= const_fn_2 (p
, q
);
65 int pq_2
= const_fn_2 (p
, q
);
66 __analyzer_eval (xy_1
== xy_2
); /* { dg-warning "TRUE" } */
67 __analyzer_eval (pq_1
== pq_2
); /* { dg-warning "TRUE" } */
68 __analyzer_eval (xy_1
== pq_1
); /* { dg-warning "UNKNOWN" } */
71 /* We don't handle above 2 args. */
73 void test_const_fn_3 (int x
, int y
, int z
, int p
, int q
, int r
)
75 int xyz_1
= const_fn_3 (x
, y
, z
);
76 int xyz_2
= const_fn_3 (x
, y
, z
);
77 int pqr_1
= const_fn_3 (p
, q
, r
);
78 int pqr_2
= const_fn_3 (p
, q
, r
);
79 __analyzer_eval (xyz_1
== xyz_2
); /* { dg-warning "UNKNOWN" } */
80 __analyzer_eval (pqr_1
== pqr_2
); /* { dg-warning "UNKNOWN" } */
81 __analyzer_eval (xyz_1
== pqr_1
); /* { dg-warning "UNKNOWN" } */
84 /* Variadic fn, with various numbers of extra args. */
86 void test_const_fn_variadic (int x
, int y
, int z
, int p
, int q
, int r
)
88 /* 0 extra args, for 1 arg in total. */
89 int x_1
= const_fn_variadic (x
);
90 int x_2
= const_fn_variadic (x
);
91 int p_1
= const_fn_variadic (p
);
92 int p_2
= const_fn_variadic (p
);
93 __analyzer_eval (x_1
== x_2
); /* { dg-warning "TRUE" } */
94 __analyzer_eval (p_1
== p_2
); /* { dg-warning "TRUE" } */
95 __analyzer_eval (x_1
== p_1
); /* { dg-warning "UNKNOWN" } */
97 /* 1 extra arg, for 2 args in total. */
98 int xy_1
= const_fn_variadic (x
, y
);
99 int xy_2
= const_fn_variadic (x
, y
);
100 int pq_1
= const_fn_variadic (p
, q
);
101 int pq_2
= const_fn_variadic (p
, q
);
102 __analyzer_eval (xy_1
== xy_2
); /* { dg-warning "TRUE" } */
103 __analyzer_eval (pq_1
== pq_2
); /* { dg-warning "TRUE" } */
104 __analyzer_eval (xy_1
== pq_1
); /* { dg-warning "UNKNOWN" } */
105 __analyzer_eval (x_1
== xy_1
); /* { dg-warning "UNKNOWN" } */
106 __analyzer_eval (p_1
== pq_1
); /* { dg-warning "UNKNOWN" } */
108 /* Above that, we don't track results. */
109 int xyz_1
= const_fn_variadic (x
, y
, z
);
110 int xyz_2
= const_fn_variadic (x
, y
, z
);
111 int pqr_1
= const_fn_variadic (p
, q
, r
);
112 int pqr_2
= const_fn_variadic (p
, q
, r
);
113 __analyzer_eval (xyz_1
== xyz_2
); /* { dg-warning "UNKNOWN" } */
114 __analyzer_eval (pqr_1
== pqr_2
); /* { dg-warning "UNKNOWN" } */
115 __analyzer_eval (xyz_1
== x_1
); /* { dg-warning "UNKNOWN" } */
116 __analyzer_eval (xyz_1
== xy_1
); /* { dg-warning "UNKNOWN" } */
117 __analyzer_eval (xyz_1
== pqr_1
); /* { dg-warning "UNKNOWN" } */
120 /* Builtins with __attribute__ ((const)). */
122 void test_builtin_isascii (int x
, int y
)
124 int x_1
= __builtin_isascii (x
);
125 int x_2
= __builtin_isascii (x
);
126 int y_1
= __builtin_isascii (y
);
127 int y_2
= __builtin_isascii (y
);
128 __analyzer_eval (x_1
== x_2
); /* { dg-warning "TRUE" } */
129 __analyzer_eval (y_1
== y_2
); /* { dg-warning "TRUE" } */
130 __analyzer_eval (x_1
== y_1
); /* { dg-warning "UNKNOWN" } */
133 void test_builtin_popcount (unsigned x
, unsigned y
)
135 unsigned x_1
= __builtin_popcount (x
);
136 unsigned x_2
= __builtin_popcount (x
);
137 unsigned y_1
= __builtin_popcount (y
);
138 unsigned y_2
= __builtin_popcount (y
);
139 __analyzer_eval (x_1
== x_2
); /* { dg-warning "TRUE" } */
140 __analyzer_eval (y_1
== y_2
); /* { dg-warning "TRUE" } */
141 __analyzer_eval (x_1
== y_1
); /* { dg-warning "UNKNOWN" } */
144 void test_loop (void)
146 for (int i
= 0; i
< 100; i
++)
148 int iter_val_a
= const_fn_1 (i
);
149 int iter_val_b
= const_fn_1 (i
);
150 __analyzer_eval (iter_val_a
== iter_val_b
); /* { dg-warning "TRUE" } */