Skip to content

Commit cdcb3cf

Browse files
authored
Merge pull request #82 from sipma/conversions
REGR: add regression test for Issue #75
2 parents d0b52cf + ae92b46 commit cdcb3cf

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Small reproducer for the CodeHawk-C my_regexec failure seen in SPEC
3+
* CPU2017 perlbench.
4+
*
5+
* The important shape is:
6+
*
7+
* unsigned_len_arg(..., end - begin)
8+
*
9+
* where begin and end are both char pointers. In C, end - begin is pointer
10+
* subtraction with signed ptrdiff_t result. Passing it to an unsigned length
11+
* parameter creates the same kind of signed-to-unsigned-cast proof obligation
12+
* as perlbench's:
13+
*
14+
* MgBYTEPOS(mg, sv, strbeg, strend - strbeg)
15+
*
16+
* CH-C generated a valid obligation for that cast, but then crashed while
17+
* reconstructing an API expression for the upper-bound invariant because it
18+
* treated the pointer difference as ordinary arithmetic XMinus and attempted
19+
* integer promotion on (char *) and (char *).
20+
*
21+
* Ref: https://github.com/static-analysis-engineering/CodeHawk-C/issues/75
22+
*/
23+
24+
#include <stddef.h>
25+
26+
typedef unsigned long STRLEN;
27+
28+
static STRLEN consume_len(const char *base, STRLEN len) {
29+
return base[len] == '\0' ? len : len + 1;
30+
}
31+
32+
STRLEN my_regexec_repro(const char *strbeg, const char *strend) {
33+
return consume_len(strbeg, strend - strbeg);
34+
}
35+
36+
STRLEN my_regexec_repro_with_guard(const char *strbeg, const char *strend) {
37+
if (strend < strbeg) {
38+
return 0;
39+
}
40+
41+
return consume_len(strbeg, strend - strbeg);
42+
}
43+
44+
STRLEN my_regexec_source_workaround(const char *strbeg, const char *strend) {
45+
if (strend < strbeg) {
46+
return 0;
47+
}
48+
49+
{
50+
STRLEN len = (STRLEN)(strend - strbeg);
51+
return consume_len(strbeg, len);
52+
}
53+
}

tests/regression/tests.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
"safe": 37
2020
}
2121
},
22+
{
23+
"filename": "my_regexec_pointer_diff_cast.c",
24+
"expected": {
25+
"safe": 106,
26+
"open": 9
27+
},
28+
"goal": "improve"
29+
},
2230
{
2331
"filename": "test_POCheckInitialized.c",
2432
"expected": {

0 commit comments

Comments
 (0)