Skip to content

Commit fd53863

Browse files
authored
Merge pull request #6007 from tautschnig/entry-point-magic
ansi_c_entry_point: avoid magic number
2 parents da342c5 + 658de79 commit fd53863

File tree

6 files changed

+46
-6
lines changed

6 files changed

+46
-6
lines changed

regression/cbmc/argv2/main.i

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int main(int argc, char *argv[])
2+
{
3+
__CPROVER_assert(
4+
sizeof(char *) > sizeof(int) || argc < 0x7FFFFFFF,
5+
"argc cannot reach INT_MAX on 32-bit systems");
6+
}

regression/cbmc/argv2/test.desc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.i
3+
--32
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

regression/cbmc/multiple-goto-traces/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ activate-multi-line-match
55
^EXIT=10$
66
^SIGNAL=0$
77
VERIFICATION FAILED
8-
Trace for main\.assertion\.1:(\n.*){22} assertion 4 \!= argc(\n.*){5}Trace for main\.assertion\.3:(\n.*){36} assertion argc != 4(\n.*){5}Trace for main\.assertion\.4:(\n.*){50} assertion argc \+ 1 != 5
8+
Trace for main\.assertion\.1:((\n.*){19}|(\n.*){22}) assertion 4 \!= argc(\n.*){5}Trace for main\.assertion\.3:((\n.*){33}|(\n.*){36}) assertion argc != 4(\n.*){5}Trace for main\.assertion\.4:((\n.*){47}|(\n.*){50}) assertion argc \+ 1 != 5
99
\*\* 3 of 4 failed
1010
--
1111
^warning: ignoring

src/ansi-c/ansi_c_entry_point.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,10 @@ bool generate_ansi_c_start_function(
313313
init_code.add(code_assumet(std::move(ge)));
314314
}
315315

316+
if(config.ansi_c.max_argc.has_value())
316317
{
317-
// assume argc is at most MAX/8-1
318-
mp_integer upper_bound=
319-
power(2, config.ansi_c.int_width-4);
320-
321-
exprt bound_expr=from_integer(upper_bound, argc_symbol.type);
318+
exprt bound_expr =
319+
from_integer(*config.ansi_c.max_argc, argc_symbol.type);
322320

323321
binary_relation_exprt le(
324322
argc_symbol.symbol_expr(), ID_le, std::move(bound_expr));

src/util/config.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,29 @@ bool configt::set(const cmdlinet &cmdline)
11461146
if(cmdline.isset("cpp11"))
11471147
cpp.set_cpp11();
11481148

1149+
// set the upper bound for argc
1150+
if(os == "windows")
1151+
{
1152+
// On Windows, CreateProcess accepts no more than 32767 characters, so make
1153+
// that a hard limit.
1154+
ansi_c.max_argc = mp_integer{32767};
1155+
}
1156+
else
1157+
{
1158+
// For other systems assume argc is no larger than the what would make argv
1159+
// consume all available memory space:
1160+
// 2^pointer_width / (pointer_width / char_width) is the maximum number of
1161+
// argv elements sysconf(ARG_MAX) is likely much lower than this, but we
1162+
// don't know that value for the verification target platform.
1163+
const auto pointer_bits_2log =
1164+
address_bits(ansi_c.pointer_width / ansi_c.char_width);
1165+
if(ansi_c.pointer_width - pointer_bits_2log <= ansi_c.int_width)
1166+
{
1167+
ansi_c.max_argc = power(2, config.ansi_c.int_width - pointer_bits_2log);
1168+
}
1169+
// otherwise we leave argc unconstrained
1170+
}
1171+
11491172
return false;
11501173
}
11511174

src/util/config.h

+5
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ class configt
258258
malloc_failure_modet malloc_failure_mode = malloc_failure_mode_none;
259259

260260
static const std::size_t default_object_bits = 8;
261+
262+
/// Maximum value of argc, which is operating-systems dependent: Windows
263+
/// limits the number of characters accepte by CreateProcess, and Unix
264+
/// systems have sysconf(ARG_MAX).
265+
optionalt<mp_integer> max_argc;
261266
} ansi_c;
262267

263268
struct cppt

0 commit comments

Comments
 (0)