Skip to content

Commit 7748745

Browse files
committed
ansi_c_entry_point: avoid magic number
The code previously hard-coded an upper bound for argc that perhaps was suitable for 32-bit systems (albeit even questionable for that case). Replace this calculation by one that refers to configured bit widths. Fixes: #1708
1 parent f0a4e75 commit 7748745

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,18 +313,42 @@ bool generate_ansi_c_start_function(
313313
init_code.add(code_assumet(std::move(ge)));
314314
}
315315

316+
// On Windows, CreateProcess accepts no more than 32767 characters, so
317+
// make that a hard limit.
318+
if(config.ansi_c.os == configt::ansi_ct::ost::OS_WIN)
316319
{
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);
320+
exprt bound_expr = from_integer(32767, argc_symbol.type);
322321

323322
binary_relation_exprt le(
324323
argc_symbol.symbol_expr(), ID_le, std::move(bound_expr));
325324

326325
init_code.add(code_assumet(std::move(le)));
327326
}
327+
else
328+
{
329+
// For other systems assume argc is no larger than the what would make
330+
// argv consume all available memory space:
331+
// 2^pointer_width / (pointer_width / char_width)
332+
// is the maximum number of argv elements
333+
// sysconf(ARG_MAX) is likely much lower than this, but we don't know
334+
// that value for the verification target platform.
335+
const auto pointer_bits_2log =
336+
address_bits(config.ansi_c.pointer_width / config.ansi_c.char_width);
337+
if(
338+
config.ansi_c.pointer_width - pointer_bits_2log <=
339+
config.ansi_c.int_width)
340+
{
341+
mp_integer upper_bound =
342+
power(2, config.ansi_c.int_width - pointer_bits_2log);
343+
344+
exprt bound_expr = from_integer(upper_bound, argc_symbol.type);
345+
346+
binary_relation_exprt le(
347+
argc_symbol.symbol_expr(), ID_le, std::move(bound_expr));
348+
349+
init_code.add(code_assumet(std::move(le)));
350+
}
351+
}
328352

329353
// record argc as an input
330354
init_code.add(code_inputt{"argc", argc_symbol.symbol_expr()});

0 commit comments

Comments
 (0)