Skip to content

Commit f27a803

Browse files
committed
_Static_assert failures should be reported in the front-end
We left it to a failing invariant in goto-program conversion to detect a failing (local) _Static_assert. Global _Static_assert statements were not verified at all.
1 parent 4eb4edd commit f27a803

File tree

8 files changed

+65
-5
lines changed

8 files changed

+65
-5
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
_Static_assert(1 == 0, "must fail");
2+
3+
int main()
4+
{
5+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE gcc-only
2+
global.c
3+
4+
static assertion failed: must fail
5+
^CONVERSION ERROR$
6+
^EXIT=(1|64)$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
Invariant check failed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
int main()
2+
{
3+
_Static_assert(1 == 0, "must fail");
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE gcc-only
2+
local.c
3+
4+
static assertion failed: must fail
5+
^CONVERSION ERROR$
6+
^EXIT=(1|64)$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
Invariant check failed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
int main()
2+
{
3+
int x;
4+
_Static_assert(x, "must fail");
5+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE gcc-only
2+
not_constant.c
3+
4+
expected constant expression
5+
^CONVERSION ERROR$
6+
^EXIT=(1|64)$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
Invariant check failed

src/ansi-c/c_typecheck_base.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,10 @@ void c_typecheck_baset::typecheck_declaration(
627627
{
628628
if(declaration.get_is_static_assert())
629629
{
630-
auto &static_assert_expr = to_binary_expr(declaration);
631-
typecheck_expr(static_assert_expr.op0());
632-
typecheck_expr(static_assert_expr.op1());
630+
codet code(ID_static_assert);
631+
code.add_source_location() = declaration.source_location();
632+
code.operands().swap(declaration.operands());
633+
typecheck_code(code);
633634
}
634635
else
635636
{

src/ansi-c/c_typecheck_code.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
#include <util/config.h>
1616
#include <util/expr_initializer.h>
1717
#include <util/range.h>
18+
#include <util/string_constant.h>
1819

1920
#include "ansi_c_declaration.h"
2021

@@ -102,9 +103,24 @@ void c_typecheck_baset::typecheck_code(codet &code)
102103
}
103104
else if(statement==ID_static_assert)
104105
{
105-
assert(code.operands().size()==2);
106+
PRECONDITION(code.operands().size() == 2);
107+
106108
typecheck_expr(code.op0());
107109
typecheck_expr(code.op1());
110+
111+
code.op0() = typecast_exprt::conditional_cast(code.op0(), bool_typet{});
112+
make_constant(code.op0());
113+
114+
if(code.op0().is_false())
115+
{
116+
// failed
117+
error().source_location = code.find_source_location();
118+
error() << "static assertion failed";
119+
if(code.op1().id() == ID_string_constant)
120+
error() << ": " << to_string_constant(code.op1()).get_value();
121+
error() << eom;
122+
throw 0;
123+
}
108124
}
109125
else if(statement==ID_CPROVER_try_catch ||
110126
statement==ID_CPROVER_try_finally)
@@ -247,7 +263,6 @@ void c_typecheck_baset::typecheck_decl(codet &code)
247263

248264
if(declaration.get_is_static_assert())
249265
{
250-
assert(declaration.operands().size()==2);
251266
codet new_code(ID_static_assert);
252267
new_code.add_source_location()=code.source_location();
253268
new_code.operands().swap(declaration.operands());

0 commit comments

Comments
 (0)