Skip to content

Commit 09980ce

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 b233b7e commit 09980ce

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

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

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

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

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

0 commit comments

Comments
 (0)