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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
|
/* { dg-options "-fcondition-coverage -ftest-coverage -O2 -c" } */
#include <stdint.h>
#include <limits.h>
#include <setjmp.h>
jmp_buf buf;
int id (int);
int idp (int *);
int err;
char c;
/* This becomes problematic only under optimization for the case when the
compiler cannot inline the function but have to generate a call. It is not
really interesting to run, only build. Notably, both the function calls and
the return values are important to construct a problematic graph.
This test is also a good example of where optimization makes condition
coverage unpredictable, but not unusable. If this is built without
optimization the conditions work as you would expect from reading the
source. */
/* Adapted from cpio-2.14 gnu/utmens.c lutimens (). */
int
mcdc001 (int *v)
{
int adjusted;
int adjustment_needed = 0;
int *ts = v ? &adjusted : 0; /* conditions(0/4) true(0 1) false(0 1) */
/* conditions(end) */
if (ts)
adjustment_needed = idp (ts);
if (adjustment_needed < 0)
return -1;
if (adjustment_needed) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
{
if (adjustment_needed != 3) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
return -1;
if (ts) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
return 0;
}
if (adjustment_needed && idp (&adjusted)) /* conditions(0/4) true(0 1) false(0 1) */
/* conditions(end) */
return -1;
if (adjusted) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
return idp (ts);
return -1;
}
/* This failed when the candidate set internal/contracted-past nodes were not
properly marked as reachable in the candidate reduction phase. */
/* Adapted from cpio-2.14 gnu/mktime.c mktime_internal (). */
int
mcdc002 ()
{
int a;
if (idp (&a)) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
{
if (id (a)) /* conditions(0/2) true(0/2) true(0) false(0) */
/* conditions(end) */
goto exit;
if (err) /* conditions(0/2) true(0/2) true(0) false(0) */
/* conditions(end) */
return -1;
}
exit:
return a;
}
/* Adapted from icu4c-73.1 common/ucase.cpp ucase_getCaseLocale (). */
int
mcdc003 (const char *locale)
{
/* extern, so its effect won't be optimized out. */
c = *locale++;
if (c == 'z') /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
{
return 1;
}
else if (c >= 'a') /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
{
if (id (c)) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
c = *locale++;
}
else
{
if (c == 'T')
{
if (id (c)) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
c = *locale++;
if (id (c)) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
c = *locale++;
}
/* This may or may not become a jump table. */
else if (c == 'L') /* conditions(suppress) */
/* conditions(end) */
c = *locale++;
else if (c == 'E') /* conditions(suppress) */
/* conditions(end) */
c = *locale++;
else if (c == 'N') /* conditions(suppress) */
/* conditions(end) */
c = *locale++;
else if (c == 'H') /* conditions(suppress) */
/* conditions(end) */
{
c = *locale++;
if (id (c)) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
c = *locale++;
}
}
return 1;
}
/* The || will be changed to |, so it is impractical to predict the number of
conditions. If the walk is not properly implemented this will not finish
compiling, so the actual coverage is not interesting. */
/* Adapted from icu4c-73.1 common/uresdata.cpp res_findResource (). */
int
mcdc004 (int r, char* path, char* key)
{
char *idcc (char *, char);
#define is_kind1(type) ((type) == 23 || (type) == 14 || (type == 115))
#define is_kind2(type) ((type) == 16 || (type) == 77 || (type == 118))
#define is_kind12(type) (is_kind1 ((type)) || is_kind2 ((type)))
char *nextSepP = path;
int t1 = r;
int type = id (t1);
if (!is_kind12 (type)) /* conditions(suppress) */
/* conditions(end) */
return -1;
while (*path && t1 != -1 && is_kind12 (type)) /* conditions(suppress) */
/* conditions(end) */
{
nextSepP = idcc(path, '/');
if(nextSepP == path) /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
return -1;
if (*nextSepP == 'a') /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
*key = *path;
else if (*nextSepP == 'b') /* conditions(0/2) true(0) false(0) */
/* conditions(end) */
*key = 0;
type = t1;
}
return t1;
}
/* Adapted from jxl 0.8.2 lib/extras/dec/apng.cc processing_start ().
This created a graph where depth-first traversal of the CFG would not
process nodes in the wrong order (the extra control inserted from setjmp
created a path of complexes from root to !b without going through !a).
This only happened under optimization. */
int
mcdc005 (int a, int b)
{
a = id (a);
b = id (b);
/* The a || b gets transformed to a | b, then fused with setjmp because
they both have the same return value. */
if (a || b) /* conditions(0/4) true(0 1) false(0 1) */
/* conditions(end) */
return 1;
else
a += 1;
if (setjmp (buf))
return 1;
return a;
}
/* Adapted from cpio-2.14 gnu/quotearg.c quotearg_buffer_restyled. The ifs in
the cases (with fallthrough) re-use the same value which under optimization
causes path reuse which must be sorted out. */
int
mcdc006 (int quoting_style, int elide, int *buffer)
{
int backslash = 0;
switch (quoting_style)
{
case 1:
if (!elide)
backslash = 1;
case 2:
if (!elide)
if (buffer)
*buffer = '"';
}
if (quoting_style == 2 && backslash)
quoting_style = 1;
return 1;
}
/* Adapted from pcre2-10.42 pcre2_compile.c pcre2_compile. If SSA nodes are
created at the wrong place in the block it will fail flow analysis (because
the label is in the middle of block), caused by the final break in this
case. */
void
mcdc007 (int options, int *pso, int len)
{
if (options == 5)
return;
while (options--)
{
int i;
for (i = 0; i < len; i++)
{
int *p = pso + i;
int skipatstart = *p + 2;
if (skipatstart) {
switch(*p)
{
case 1:
*p |= *p + 1;
break;
case 2:
skipatstart += *p - skipatstart;
break;
}
break;
}
}
if (i >= len) break;
}
}
/* Adapted from alsa-lib 1.2.8 pcm/pcm.c snd_pcm_chmap_print. */
int
mcdc008 (int *map, unsigned maxlen, int *buf)
{
unsigned int len = 0;
for (unsigned i = 0; i < *map; i++) {
unsigned int p = map[i] & 0xF;
if (i > 0) {
if (len >= maxlen)
return -1;
}
if (map[i] & 0xFF)
len += idp (buf + len);
else {
len += idp (buf);
}
if (map[i] & 0xFF00) {
len += idp (buf + len);
if (len >= maxlen)
return -1;
}
}
return len;
}
/* Adapted from cpio-2.14 gnu/mktime.c mktime_internal (). The combination of
goto, automatic variables, and the ternary causes the post dominator of the
highest topological ordered node not to be the common post dominator of the
expression as a whole. */
int
mcdc009 (int *tp, int t, int isdst)
{
int t0 = tp[0];
int t1 = tp[1];
int t2 = tp[2];
if (t0 < 0 || (isdst < 0 ? t1 : (isdst != 0)))
goto offset_found;
if (t == 0)
return -1;
t1 = t2;
offset_found:
return t;
}
/* Adapted from Berkeley db 4.8.30 rep/rep_elect.c __rep_cmp_vote. This
particular combination of fallthrough and folding creates a path into the
the inner if () that does not go through the first basic condition. */
void
mcdc010 (int cmp, int *rep, int sites, int priority, int flags)
{
if (sites > 1 && (priority != 0 || (flags & 0xFF)))
{
if ( (priority != 0 && *rep == 0)
|| (((priority == 0 && *rep == 0)
|| (priority != 0 && *rep != 0)) && cmp > 0))
{
*rep = cmp;
}
}
}
/* For not sufficiently protected back edges this would create an infinite
loop. */
void
mcdc011 (int a, int b)
{
if (a && id (b))
for (;;) {}
id (a+1);
}
/* Adapted from alsa-1.2.8 tlv.c get_tlv_info (). Under optimization, the
conditions may be replaced with min (). */
int
mcdc012 (int x, int y)
{
int err;
err = id (x);
if (err < 0)
return err;
err = id (y);
if (err < 0)
return err;
return 0;
}
/* Adapted from alsa-1.2.8 control.c snd_ctl_elem_id_compare_numid (). This
test is probably not so accurate on targets where int == int64. Under
optimization, the conditions may be replaced with min/max. */
int
mcdc013 (const int64_t *id1, const int64_t *id2)
{
int64_t d;
d = *id1 - *id2;
if (d & 0xFF)
{
if (d > INT_MAX)
d = INT_MAX;
else if (d < INT_MIN)
d = INT_MIN;
}
return d;
}
|