diff --git a/regression/ansi-c/Array_Declarator8/main.c b/regression/ansi-c/Array_Declarator8/main.c new file mode 100644 index 00000000000..4320252ca8d --- /dev/null +++ b/regression/ansi-c/Array_Declarator8/main.c @@ -0,0 +1,20 @@ +typedef unsigned char u1; +typedef unsigned short u2; +typedef unsigned long long u4; + +// Not resolved (as expected) +u4 B[( (u1)( ( (u1)15 ) / ( ( (((sizeof(u4))/(sizeof(u1)))*((u1)15)) > ((u1)64)) ? (0) : (1) ) ) )]; + +// Correctly resolved +u2 C[( (u1)( ( (u1)11 ) / ( ( (((sizeof(u2))/(sizeof(u1)))*((u1)11)) > ((u1)64)) ? (0) : (1) ) ) )]; + +int main() +{ + // Correctly resolved + u2 A[( (u1)( ( (u1)1 ) / ( ( (((sizeof(u2))/(sizeof(u1)))*((u1)1)) > ((u1)64)) ? (0) : (1) ) ) )]; + + // Correctly resolved + static u4 D[( (u1)( ( (u1)4 ) / ( ( (((sizeof(u4))/(sizeof(u1)))*((u1)4)) > ((u1)64)) ? (0) : (1) ) ) )]; + + return 0; +} diff --git a/regression/ansi-c/Array_Declarator8/test.desc b/regression/ansi-c/Array_Declarator8/test.desc new file mode 100644 index 00000000000..d42f8db33a9 --- /dev/null +++ b/regression/ansi-c/Array_Declarator8/test.desc @@ -0,0 +1,9 @@ +CORE +main.c + +^EXIT=(64|1)$ +^SIGNAL=0$ +^CONVERSION ERROR$ +array size of static symbol `B' is not constant$ +-- +^warning: ignoring diff --git a/src/ansi-c/ansi_c_declaration.cpp b/src/ansi-c/ansi_c_declaration.cpp index a764ab1a639..00beb3a92cf 100644 --- a/src/ansi-c/ansi_c_declaration.cpp +++ b/src/ansi-c/ansi_c_declaration.cpp @@ -128,6 +128,7 @@ void ansi_c_declarationt::to_symbol( symbol.value=declarator.value(); symbol.type=full_type(declarator); symbol.name=declarator.get_name(); + symbol.pretty_name=symbol.name; symbol.base_name=declarator.get_base_name(); symbol.is_type=get_is_typedef(); symbol.location=declarator.source_location(); diff --git a/src/ansi-c/c_typecheck_base.cpp b/src/ansi-c/c_typecheck_base.cpp index 391039691c4..0d18016602d 100644 --- a/src/ansi-c/c_typecheck_base.cpp +++ b/src/ansi-c/c_typecheck_base.cpp @@ -45,8 +45,6 @@ void c_typecheck_baset::move_symbol(symbolt &symbol, symbolt *&new_symbol) void c_typecheck_baset::typecheck_symbol(symbolt &symbol) { - current_symbol_id=symbol.name; - bool is_function=symbol.type.id()==ID_code; const typet &final_type=follow(symbol.type); @@ -703,6 +701,7 @@ void c_typecheck_baset::typecheck_declaration( symbolt symbol; declaration.to_symbol(*d_it, symbol); + current_symbol=symbol; // now check other half of type typecheck_type(symbol.type); diff --git a/src/ansi-c/c_typecheck_base.h b/src/ansi-c/c_typecheck_base.h index 684b0b64edc..521ae29aa4a 100644 --- a/src/ansi-c/c_typecheck_base.h +++ b/src/ansi-c/c_typecheck_base.h @@ -61,7 +61,7 @@ class c_typecheck_baset: symbol_tablet &symbol_table; const irep_idt module; const irep_idt mode; - irep_idt current_symbol_id; + symbolt current_symbol; typedef std::unordered_map id_type_mapt; id_type_mapt parameter_map; diff --git a/src/ansi-c/c_typecheck_type.cpp b/src/ansi-c/c_typecheck_type.cpp index 6abcf8f81a2..62e651f9135 100644 --- a/src/ansi-c/c_typecheck_type.cpp +++ b/src/ansi-c/c_typecheck_type.cpp @@ -15,6 +15,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include #include #include @@ -551,9 +552,15 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type) { // not a constant and not infinity - assert(!current_symbol_id.empty()); + PRECONDITION(!current_symbol.name.empty()); - const symbolt &base_symbol=lookup(current_symbol_id); + if(current_symbol.is_static_lifetime) + { + error().source_location=current_symbol.location; + error() << "array size of static symbol `" + << current_symbol.base_name << "' is not constant" << eom; + throw 0; + } // Need to pull out! We insert new symbol. source_locationt source_location=size.find_source_location(); @@ -564,7 +571,7 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type) do { suffix="$array_size"+std::to_string(count); - temp_identifier=id2string(base_symbol.name)+suffix; + temp_identifier=id2string(current_symbol.name)+suffix; count++; } while(symbol_table.symbols.find(temp_identifier)!= @@ -573,13 +580,13 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type) // add the symbol to symbol table auxiliary_symbolt new_symbol; new_symbol.name=temp_identifier; - new_symbol.pretty_name=id2string(base_symbol.pretty_name)+suffix; - new_symbol.base_name=id2string(base_symbol.base_name)+suffix; + new_symbol.pretty_name=id2string(current_symbol.pretty_name)+suffix; + new_symbol.base_name=id2string(current_symbol.base_name)+suffix; new_symbol.type=size.type(); new_symbol.type.set(ID_C_constant, true); new_symbol.is_type=false; new_symbol.is_static_lifetime=false; - new_symbol.value.make_nil(); + new_symbol.value=size; new_symbol.location=source_location; symbol_table.add(new_symbol);