Skip to content

Commit 1a86739

Browse files
committed
Static-lifetime symbols require compile-time constant initialisers
We previously silently accepted initialisers that weren't compile-time constants, resulting in surprising behaviour: the assertion in the enclosed regression test would fail, because x ended up being initialised before y.
1 parent bf439bd commit 1a86739

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

regression/ansi-c/static4/main.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
int main()
2+
{
3+
int y = 42;
4+
static int x = y;
5+
6+
__CPROVER_assert(x == 42, "local static");
7+
}

regression/ansi-c/static4/test.desc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
4+
expected constant expression
5+
^CONVERSION ERROR$
6+
^EXIT=(1|64)$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring

src/ansi-c/c_typecheck_code.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,19 @@ void c_typecheck_baset::typecheck_decl(codet &code)
308308
// see if it's a typedef
309309
// or a function
310310
// or static
311-
if(symbol.is_type ||
312-
symbol.type.id()==ID_code ||
313-
symbol.is_static_lifetime)
311+
if(symbol.is_type || symbol.type.id() == ID_code)
314312
{
315313
// we ignore
316314
}
315+
else if(symbol.is_static_lifetime)
316+
{
317+
// make sure the initialization value is a compile-time constant
318+
if(symbol.value.is_not_nil())
319+
{
320+
exprt init_value = symbol.value;
321+
make_constant(init_value);
322+
}
323+
}
317324
else
318325
{
319326
code_frontend_declt decl(symbol.symbol_expr());

0 commit comments

Comments
 (0)