Skip to content

Commit 9018306

Browse files
committed
C/C++ front-end: do not accept void-typed objects or members
We silently accepted these, as many cases would work fine in goto programs. The included regression test, however, demonstrates where this would fail an invariant during Boolean flattening (if run with --pointer-check). GCC refuses void typed variables, and so should we. Test originates from an SV-COMP task, reduced to this minimal example using C-Reduce.
1 parent 4c2b413 commit 9018306

9 files changed

+83
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
struct a
2+
{
3+
#ifdef void_member
4+
void b;
5+
#else
6+
int b;
7+
#endif
8+
};
9+
struct a *ae;
10+
void d()
11+
{
12+
ae->b;
13+
}
14+
#ifdef void_global
15+
void x;
16+
#endif
17+
int main()
18+
{
19+
void v;
20+
d();
21+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE test-c++-front-end
2+
main.c
3+
-Dvoid_global
4+
^EXIT=(64|1)$
5+
^SIGNAL=0$
6+
void-typed symbol not permitted
7+
^CONVERSION ERROR$
8+
--
9+
Invariant check failed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE test-c++-front-end
2+
main.c
3+
4+
^EXIT=(64|1)$
5+
^SIGNAL=0$
6+
void-typed symbol not permitted
7+
^CONVERSION ERROR$
8+
--
9+
Invariant check failed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE test-c++-front-end
2+
main.c
3+
-Dvoid_member
4+
^EXIT=(64|1)$
5+
^SIGNAL=0$
6+
void-typed member not permitted
7+
^CONVERSION ERROR$
8+
--
9+
Invariant check failed

src/ansi-c/c_typecheck_base.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
103103
symbol.pretty_name=new_name;
104104
}
105105

106+
if(!symbol.is_type && symbol.type.id() == ID_empty)
107+
{
108+
error().source_location = symbol.location;
109+
error() << "void-typed symbol not permitted" << eom;
110+
throw 0;
111+
}
112+
106113
// see if we have it already
107114
symbol_tablet::symbolst::const_iterator old_it=
108115
symbol_table.symbols.find(symbol.name);

src/ansi-c/c_typecheck_type.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,13 @@ void c_typecheck_baset::typecheck_compound_body(
934934
throw 0;
935935
}
936936

937+
if(new_component.type().id() == ID_empty)
938+
{
939+
error().source_location = source_location;
940+
error() << "void-typed member not permitted" << eom;
941+
throw 0;
942+
}
943+
937944
components.push_back(new_component);
938945
}
939946
}

src/cpp/cpp_typecheck_code.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,13 @@ void cpp_typecheckt::typecheck_decl(codet &code)
448448
if(is_typedef)
449449
continue;
450450

451+
if(!symbol.is_type && symbol.type.id() == ID_empty)
452+
{
453+
error().source_location = symbol.location;
454+
error() << "void-typed symbol not permitted" << eom;
455+
throw 0;
456+
}
457+
451458
code_declt decl_statement(cpp_symbol_expr(symbol));
452459
decl_statement.add_source_location()=symbol.location;
453460

src/cpp/cpp_typecheck_compound_type.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,13 @@ void cpp_typecheckt::typecheck_compound_declarator(
317317

318318
typecheck_type(final_type);
319319

320+
if(final_type.id() == ID_empty)
321+
{
322+
error().source_location = declaration.type().source_location();
323+
error() << "void-typed member not permitted" << eom;
324+
throw 0;
325+
}
326+
320327
cpp_namet cpp_name;
321328
cpp_name.swap(declarator.name());
322329

src/cpp/cpp_typecheck_declaration.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ void cpp_typecheckt::convert_non_template_declaration(
148148
declaration_type, declaration.storage_spec(),
149149
declaration.member_spec(), declarator);
150150

151+
if(!symbol.is_type && symbol.type.id() == ID_empty)
152+
{
153+
error().source_location = symbol.location;
154+
error() << "void-typed symbol not permitted" << eom;
155+
throw 0;
156+
}
157+
151158
// any template instance to remember?
152159
if(declaration.find(ID_C_template).is_not_nil())
153160
{

0 commit comments

Comments
 (0)