Skip to content

Commit ec44b95

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 1ab5de1 commit ec44b95

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
@@ -312,18 +312,42 @@ bool generate_ansi_c_start_function(
312312
init_code.add(code_assumet(std::move(ge)));
313313
}
314314

315+
// On Windows, CreateProcess accepts no more than 32767 characters, so
316+
// make that a hard limit.
317+
if(config.ansi_c.os == configt::ansi_ct::ost::OS_WIN)
315318
{
316-
// assume argc is at most MAX/8-1
317-
mp_integer upper_bound=
318-
power(2, config.ansi_c.int_width-4);
319-
320-
exprt bound_expr=from_integer(upper_bound, argc_symbol.type);
319+
exprt bound_expr = from_integer(32767, argc_symbol.type);
321320

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

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

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

0 commit comments

Comments
 (0)