@@ -156,9 +156,44 @@ void c_typecheck_baset::typecheck_new_symbol(symbolt &symbol)
156
156
}
157
157
else
158
158
{
159
- // we don't need the identifiers
160
- for (auto ¶meter : to_code_type (symbol.type ).parameters ())
161
- parameter.set_identifier (irep_idt ());
159
+ code_typet &code_type = to_code_type (symbol.type );
160
+
161
+ // Add the parameter declarations into the symbol table.
162
+ for (auto ¶meter : code_type.parameters ())
163
+ {
164
+ std::string symbol_name = id2string (symbol.name );
165
+
166
+ // CPROVER primitives, anonymous, builtin and atomics do not need identifiers
167
+ if (
168
+ symbol_name.find (" __atomic_" ) != std::string::npos ||
169
+ symbol_name.find (" __builtin_" ) != std::string::npos ||
170
+ symbol_name.find (" __CPROVER_" ) != std::string::npos ||
171
+ symbol_name.find (" __VERIFIER_" ) != std::string::npos ||
172
+ parameter.get_base_name ().empty ())
173
+ {
174
+ parameter.set_identifier (irep_idt ());
175
+ }
176
+ else
177
+ {
178
+ // produce identifier
179
+ irep_idt identifier =
180
+ symbol_name + " ::" + id2string (parameter.get_base_name ());
181
+ parameter.set_identifier (identifier);
182
+
183
+ parameter_symbolt parameter_symbol;
184
+ parameter_symbol.type = parameter.type ();
185
+ parameter_symbol.name = identifier;
186
+ parameter_symbol.base_name = parameter.get_base_name ();
187
+ parameter_symbol.location = parameter.source_location ();
188
+
189
+ symbolt *new_parameter_symbol;
190
+
191
+ symbol.mode = mode;
192
+ symbol.module = module;
193
+
194
+ move_symbol (parameter_symbol, new_parameter_symbol);
195
+ }
196
+ }
162
197
}
163
198
}
164
199
else if (!symbol.is_macro )
@@ -341,7 +376,6 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
341
376
}
342
377
343
378
// do body
344
-
345
379
if (new_symbol.value .is_not_nil ())
346
380
{
347
381
if (old_symbol.value .is_not_nil ())
@@ -379,6 +413,21 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
379
413
throw 0 ;
380
414
}
381
415
}
416
+ else if (old_ct.parameters ().size () > 0 ) // previous declaration
417
+ {
418
+ // remove parameter declarations to avoid conflicts
419
+ for (const auto &old_parameter : old_ct.parameters ())
420
+ {
421
+ const irep_idt &identifier = old_parameter.get_identifier ();
422
+
423
+ symbol_tablet::symbolst::const_iterator parameter_symbol_it =
424
+ symbol_table.symbols .find (identifier);
425
+ if (parameter_symbol_it != symbol_table.symbols .end ())
426
+ {
427
+ symbol_table.erase (parameter_symbol_it);
428
+ }
429
+ }
430
+ }
382
431
else if (inlined)
383
432
{
384
433
// preserve "extern inline" properties
@@ -402,6 +451,29 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
402
451
// move body
403
452
old_symbol.value .swap (new_symbol.value );
404
453
454
+ // Copy contract over, if it exists
455
+ const code_typet &old_type = to_code_type (old_symbol.type );
456
+ exprt old_assigns =
457
+ static_cast <const exprt &>(old_type.find (ID_C_spec_assigns));
458
+ exprt old_requires =
459
+ static_cast <const exprt &>(old_type.find (ID_C_spec_requires));
460
+ exprt old_ensures =
461
+ static_cast <const exprt &>(old_type.find (ID_C_spec_ensures));
462
+ if (old_assigns.is_not_nil ())
463
+ {
464
+ new_symbol.type .get_named_sub ().add (
465
+ ID_C_spec_assigns, std::move (old_assigns));
466
+ }
467
+ if (old_requires.is_not_nil ())
468
+ {
469
+ new_symbol.type .get_named_sub ().add (
470
+ ID_C_spec_requires, std::move (old_requires));
471
+ }
472
+ if (old_ensures.is_not_nil ())
473
+ {
474
+ new_symbol.type .move_to_named_sub (ID_C_spec_ensures, old_ensures);
475
+ }
476
+
405
477
// overwrite type (because of parameter names)
406
478
old_symbol.type =new_symbol.type ;
407
479
}
@@ -729,13 +801,12 @@ void c_typecheck_baset::typecheck_declaration(
729
801
declarator.set_name (identifier);
730
802
731
803
// If the declarator is for a function definition, typecheck it.
804
+ typecheck_symbol (symbol);
732
805
if (can_cast_type<code_typet>(declarator.type ()))
733
806
{
734
807
typecheck_assigns (to_code_type (declarator.type ()), contract);
735
808
}
736
809
737
- typecheck_symbol (symbol);
738
-
739
810
// add code contract (if any); we typecheck this after the
740
811
// function body done above, so as to have parameter symbols
741
812
// available
@@ -754,15 +825,15 @@ void c_typecheck_baset::typecheck_declaration(
754
825
typecheck_spec_expr (static_cast <codet &>(contract), ID_C_spec_ensures);
755
826
parameter_map.clear ();
756
827
757
- irept assigns_to_add = contract.find (ID_C_spec_assigns);
758
- if (assigns_to_add. is_not_nil ())
759
- new_symbol. type . add (ID_C_spec_assigns) = assigns_to_add ;
760
- irept requires_to_add = contract.find (ID_C_spec_requires);
761
- if (requires_to_add. is_not_nil ())
762
- new_symbol. type . add (ID_C_spec_requires) = requires_to_add ;
763
- irept ensures_to_add = contract.find (ID_C_spec_ensures);
764
- if (ensures_to_add. is_not_nil ())
765
- new_symbol. type . add (ID_C_spec_ensures) = ensures_to_add ;
828
+ if ( contract.find (ID_C_spec_assigns). is_not_nil ())
829
+ new_symbol. type . add (ID_C_spec_assigns) =
830
+ contract. find (ID_C_spec_assigns);
831
+ if ( contract.find (ID_C_spec_requires). is_not_nil ())
832
+ new_symbol. type . add (ID_C_spec_requires) =
833
+ contract. find (ID_C_spec_requires);
834
+ if ( contract.find (ID_C_spec_ensures). is_not_nil ())
835
+ new_symbol. type . add (ID_C_spec_ensures) =
836
+ contract. find (ID_C_spec_ensures);
766
837
}
767
838
}
768
839
}
0 commit comments