|
8 | 8 |
|
9 | 9 | #include "ansi_c_language.h"
|
10 | 10 |
|
| 11 | +#include <util/arith_tools.h> |
| 12 | +#include <util/c_types.h> |
11 | 13 | #include <util/config.h>
|
12 | 14 | #include <util/get_base_name.h>
|
| 15 | +#include <util/replace_symbol.h> |
13 | 16 | #include <util/symbol_table.h>
|
14 | 17 |
|
15 | 18 | #include <linking/linking.h>
|
@@ -124,6 +127,36 @@ bool ansi_c_languaget::typecheck(
|
124 | 127 | return true;
|
125 | 128 | }
|
126 | 129 |
|
| 130 | + unchecked_replace_symbolt array_type_updates; |
| 131 | + for(auto it = new_symbol_table.begin(); it != new_symbol_table.end(); ++it) |
| 132 | + { |
| 133 | + // C standard 6.9.2, paragraph 5 |
| 134 | + // adjust the type of an external array without size to an array of size 1 |
| 135 | + symbolt &symbol = it.get_writeable_symbol(); |
| 136 | + if( |
| 137 | + symbol.is_static_lifetime && !symbol.is_extern && !symbol.is_type && |
| 138 | + !symbol.is_macro && symbol.type.id() == ID_array && |
| 139 | + to_array_type(symbol.type).size().is_nil()) |
| 140 | + { |
| 141 | + symbol_exprt previous_expr = symbol.symbol_expr(); |
| 142 | + to_array_type(symbol.type).size() = from_integer(1, size_type()); |
| 143 | + array_type_updates.insert(previous_expr, symbol.symbol_expr()); |
| 144 | + } |
| 145 | + } |
| 146 | + if(!array_type_updates.empty()) |
| 147 | + { |
| 148 | + // Apply type updates to initializers |
| 149 | + for(auto it = new_symbol_table.begin(); it != new_symbol_table.end(); ++it) |
| 150 | + { |
| 151 | + if( |
| 152 | + !it->second.is_type && !it->second.is_macro && |
| 153 | + it->second.value.is_not_nil()) |
| 154 | + { |
| 155 | + array_type_updates(it.get_writeable_symbol().value); |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + |
127 | 160 | remove_internal_symbols(
|
128 | 161 | new_symbol_table, message_handler, keep_file_local, keep);
|
129 | 162 |
|
|
0 commit comments