Skip to content

Commit 544682c

Browse files
committed
Do not accept arrays of variable size with static lifetime
Neither Clang nor GCC accept these. In addition to rejecting such declarations, also fix the off-by-one error reported in #525: type declarations are type checked before their symbols are processed, thus the symbol name needs to be set up early. A lookup via the symbol table, however, is not yet possible. Thus maintain the full symbol. Fixes: #525
1 parent 40d1560 commit 544682c

File tree

5 files changed

+44
-9
lines changed

5 files changed

+44
-9
lines changed
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
typedef unsigned char u1;
2+
typedef unsigned short u2;
3+
typedef unsigned long long u4;
4+
5+
// Not resolved (as expected)
6+
u4 B[( (u1)( ( (u1)15 ) / ( ( (((sizeof(u4))/(sizeof(u1)))*((u1)15)) > ((u1)64)) ? (0) : (1) ) ) )];
7+
8+
// Correctly resolved
9+
u2 C[( (u1)( ( (u1)11 ) / ( ( (((sizeof(u2))/(sizeof(u1)))*((u1)11)) > ((u1)64)) ? (0) : (1) ) ) )];
10+
11+
int main()
12+
{
13+
// Correctly resolved
14+
u2 A[( (u1)( ( (u1)1 ) / ( ( (((sizeof(u2))/(sizeof(u1)))*((u1)1)) > ((u1)64)) ? (0) : (1) ) ) )];
15+
16+
// Correctly resolved
17+
static u4 D[( (u1)( ( (u1)4 ) / ( ( (((sizeof(u4))/(sizeof(u1)))*((u1)4)) > ((u1)64)) ? (0) : (1) ) ) )];
18+
19+
return 0;
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=(64|1)$
5+
^SIGNAL=0$
6+
^CONVERSION ERROR$
7+
array size of static symbol `B' is not constant$
8+
--
9+
^warning: ignoring

src/ansi-c/c_typecheck_base.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ void c_typecheck_baset::move_symbol(symbolt &symbol, symbolt *&new_symbol)
4545

4646
void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
4747
{
48-
current_symbol_id=symbol.name;
49-
5048
bool is_function=symbol.type.id()==ID_code;
5149

5250
const typet &final_type=follow(symbol.type);
@@ -703,6 +701,7 @@ void c_typecheck_baset::typecheck_declaration(
703701

704702
symbolt symbol;
705703
declaration.to_symbol(*d_it, symbol);
704+
current_symbol=symbol;
706705

707706
// now check other half of type
708707
typecheck_type(symbol.type);

src/ansi-c/c_typecheck_base.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class c_typecheck_baset:
6161
symbol_tablet &symbol_table;
6262
const irep_idt module;
6363
const irep_idt mode;
64-
irep_idt current_symbol_id;
64+
symbolt current_symbol;
6565

6666
typedef std::unordered_map<irep_idt, typet, irep_id_hash> id_type_mapt;
6767
id_type_mapt parameter_map;

src/ansi-c/c_typecheck_type.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515

1616
#include <util/c_types.h>
1717
#include <util/config.h>
18+
#include <util/invariant.h>
1819
#include <util/simplify_expr.h>
1920
#include <util/arith_tools.h>
2021
#include <util/std_types.h>
@@ -551,9 +552,15 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
551552
{
552553
// not a constant and not infinity
553554

554-
assert(!current_symbol_id.empty());
555+
PRECONDITION(!current_symbol.name.empty());
555556

556-
const symbolt &base_symbol=lookup(current_symbol_id);
557+
if(current_symbol.is_static_lifetime)
558+
{
559+
error().source_location=current_symbol.location;
560+
error() << "array size of static symbol `"
561+
<< current_symbol.base_name << "' is not constant" << eom;
562+
throw 0;
563+
}
557564

558565
// Need to pull out! We insert new symbol.
559566
source_locationt source_location=size.find_source_location();
@@ -564,7 +571,7 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
564571
do
565572
{
566573
suffix="$array_size"+std::to_string(count);
567-
temp_identifier=id2string(base_symbol.name)+suffix;
574+
temp_identifier=id2string(current_symbol.name)+suffix;
568575
count++;
569576
}
570577
while(symbol_table.symbols.find(temp_identifier)!=
@@ -573,13 +580,13 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
573580
// add the symbol to symbol table
574581
auxiliary_symbolt new_symbol;
575582
new_symbol.name=temp_identifier;
576-
new_symbol.pretty_name=id2string(base_symbol.pretty_name)+suffix;
577-
new_symbol.base_name=id2string(base_symbol.base_name)+suffix;
583+
new_symbol.pretty_name=id2string(current_symbol.pretty_name)+suffix;
584+
new_symbol.base_name=id2string(current_symbol.base_name)+suffix;
578585
new_symbol.type=size.type();
579586
new_symbol.type.set(ID_C_constant, true);
580587
new_symbol.is_type=false;
581588
new_symbol.is_static_lifetime=false;
582-
new_symbol.value.make_nil();
589+
new_symbol.value=size;
583590
new_symbol.location=source_location;
584591

585592
symbol_table.add(new_symbol);

0 commit comments

Comments
 (0)