Skip to content

Commit 750ab58

Browse files
authored
Merge pull request #5665 from tautschnig/_fdopen
C library: define _fopen for OS X
2 parents fa89b6a + d34a00d commit 750ab58

File tree

3 files changed

+70
-14
lines changed

3 files changed

+70
-14
lines changed
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
#include <assert.h>
21
#include <stdio.h>
32

43
int main()
54
{
6-
fopen();
7-
assert(0);
5+
FILE *f = fopen("some_file", "r");
6+
if(!f)
7+
return 1;
8+
9+
// fopen returns NULL or some pointer that is safe to dereference
10+
(void)*f;
11+
812
return 0;
913
}

regression/cbmc-library/fopen-01/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--pointer-check --bounds-check
44
^EXIT=0$

src/ansi-c/library/stdio.c

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ inline int puts(const char *s)
4646
return ret;
4747
}
4848

49+
/* FUNCTION: fclose_cleanup */
50+
51+
#ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS
52+
inline void fclose_cleanup(void *stream)
53+
{
54+
__CPROVER_HIDE:;
55+
__CPROVER_assert(
56+
!__CPROVER_get_must(stream, "open") || __CPROVER_get_must(stream, "closed"),
57+
"resource leak: fopen file not closed");
58+
}
59+
#endif
60+
4961
/* FUNCTION: fopen */
5062

5163
#ifndef __CPROVER_STDIO_H_INCLUDED
@@ -58,16 +70,7 @@ inline int puts(const char *s)
5870
#define __CPROVER_STDLIB_H_INCLUDED
5971
#endif
6072

61-
#ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS
62-
inline void fclose_cleanup(void *stream)
63-
{
64-
__CPROVER_HIDE:;
65-
__CPROVER_assert(!__CPROVER_get_must(stream, "open") ||
66-
__CPROVER_get_must(stream, "closed"),
67-
"resource leak: fopen file not closed");
68-
}
69-
#endif
70-
73+
void fclose_cleanup(void *stream);
7174
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
7275

7376
inline FILE *fopen(const char *filename, const char *mode)
@@ -100,6 +103,55 @@ inline FILE *fopen(const char *filename, const char *mode)
100103
return fopen_result;
101104
}
102105

106+
/* FUNCTION: _fopen */
107+
108+
// This is for Apple; we cannot fall back to fopen as we need
109+
// header files to have a definition of FILE available; the same
110+
// header files rename fopen to _fopen and would thus yield
111+
// unbounded recursion.
112+
113+
#ifndef __CPROVER_STDIO_H_INCLUDED
114+
# include <stdio.h>
115+
# define __CPROVER_STDIO_H_INCLUDED
116+
#endif
117+
118+
#ifndef __CPROVER_STDLIB_H_INCLUDED
119+
# include <stdlib.h>
120+
# define __CPROVER_STDLIB_H_INCLUDED
121+
#endif
122+
123+
void fclose_cleanup(void *stream);
124+
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
125+
126+
#ifdef __APPLE__
127+
inline FILE *_fopen(const char *filename, const char *mode)
128+
{
129+
__CPROVER_HIDE:;
130+
(void)*filename;
131+
(void)*mode;
132+
# ifdef __CPROVER_STRING_ABSTRACTION
133+
__CPROVER_assert(
134+
__CPROVER_is_zero_string(filename),
135+
"fopen zero-termination of 1st argument");
136+
__CPROVER_assert(
137+
__CPROVER_is_zero_string(mode), "fopen zero-termination of 2nd argument");
138+
# endif
139+
140+
FILE *fopen_result;
141+
142+
__CPROVER_bool fopen_error = __VERIFIER_nondet___CPROVER_bool();
143+
144+
fopen_result = fopen_error ? NULL : malloc(sizeof(FILE));
145+
146+
# ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS
147+
__CPROVER_set_must(fopen_result, "open");
148+
__CPROVER_cleanup(fopen_result, fclose_cleanup);
149+
# endif
150+
151+
return fopen_result;
152+
}
153+
#endif
154+
103155
/* FUNCTION: freopen */
104156

105157
#ifndef __CPROVER_STDIO_H_INCLUDED

0 commit comments

Comments
 (0)