Skip to content

Commit d9e5523

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 7f41999 commit d9e5523

File tree

7 files changed

+64
-0
lines changed

7 files changed

+64
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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(x)
11+
{
12+
ae->b;
13+
}
14+
int main()
15+
{
16+
void v;
17+
d();
18+
}
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_compound_type.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,13 @@ void cpp_typecheckt::typecheck_compound_body(symbolt &symbol)
10121012

10131013
typet final_type=follow(declaration.type());
10141014

1015+
if(final_type.id() == ID_empty)
1016+
{
1017+
error().source_location = declaration.type().source_location();
1018+
error() << "void-typed member not permitted" << eom;
1019+
throw 0;
1020+
}
1021+
10151022
// anonymous member?
10161023
if(declaration.declarators().empty() &&
10171024
final_type.get_bool(ID_C_is_anonymous))

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)