Skip to content

Commit 2743d87

Browse files
authored
Merge pull request #6477 from tautschnig/string-abstraction-tag-types
String abstraction: use tag types
2 parents e6b3118 + ba90cd3 commit 2743d87

File tree

1 file changed

+74
-48
lines changed

1 file changed

+74
-48
lines changed

src/goto-programs/string_abstraction.cpp

Lines changed: 74 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,17 @@ string_abstractiont::string_abstractiont(
100100
s.components()[1].set_pretty_name("length");
101101
s.components()[2].set_pretty_name("size");
102102

103-
string_struct = std::move(s);
103+
symbolt &struct_symbol = get_fresh_aux_symbol(
104+
s, "tag-", "string_struct", source_locationt{}, ID_C, ns, symbol_table);
105+
struct_symbol.is_type = true;
106+
struct_symbol.is_lvalue = false;
107+
struct_symbol.is_state_var = false;
108+
struct_symbol.is_thread_local = true;
109+
struct_symbol.is_file_local = true;
110+
struct_symbol.is_auxiliary = false;
111+
struct_symbol.is_macro = true;
112+
113+
string_struct = struct_tag_typet{struct_symbol.name};
104114
}
105115

106116
typet string_abstractiont::build_type(whatt what)
@@ -310,7 +320,7 @@ void string_abstractiont::make_decl_and_def(goto_programt &dest,
310320
if(val.is_nil())
311321
{
312322
const symbolt &orig=ns.lookup(source_sym);
313-
val=make_val_or_dummy_rec(dest, ref_instr, symbol, ns.follow(orig.type));
323+
val = make_val_or_dummy_rec(dest, ref_instr, symbol, orig.type);
314324
}
315325

316326
// may still be nil (structs, then assignments have been done already)
@@ -328,29 +338,28 @@ exprt string_abstractiont::make_val_or_dummy_rec(goto_programt &dest,
328338
goto_programt::targett ref_instr,
329339
const symbolt &symbol, const typet &source_type)
330340
{
331-
const typet &eff_type=ns.follow(symbol.type);
332-
333-
if(eff_type.id()==ID_array || eff_type.id()==ID_pointer)
341+
if(symbol.type.id() == ID_array || symbol.type.id() == ID_pointer)
334342
{
335-
const typet &source_subt=is_ptr_string_struct(eff_type)?
336-
source_type:ns.follow(source_type.subtype());
337-
symbol_exprt sym_expr=add_dummy_symbol_and_value(
338-
dest, ref_instr, symbol, irep_idt(),
339-
eff_type.subtype(), source_subt);
340-
341-
if(eff_type.id()==ID_array)
342-
return array_of_exprt(sym_expr, to_array_type(eff_type));
343+
const typet &source_subt =
344+
is_ptr_string_struct(symbol.type) ? source_type : source_type.subtype();
345+
symbol_exprt sym_expr = add_dummy_symbol_and_value(
346+
dest, ref_instr, symbol, irep_idt(), symbol.type.subtype(), source_subt);
347+
348+
if(symbol.type.id() == ID_array)
349+
return array_of_exprt(sym_expr, to_array_type(symbol.type));
343350
else
344351
return address_of_exprt(sym_expr);
345352
}
346353
else if(
347-
eff_type.id() == ID_union ||
348-
(eff_type.id() == ID_struct && eff_type != string_struct))
354+
symbol.type.id() == ID_union_tag ||
355+
(symbol.type.id() == ID_struct_tag && symbol.type != string_struct))
349356
{
350-
const struct_union_typet &su_source=to_struct_union_type(source_type);
357+
const struct_union_typet &su_source =
358+
to_struct_union_type(ns.follow(source_type));
351359
const struct_union_typet::componentst &s_components=
352360
su_source.components();
353-
const struct_union_typet &struct_union_type=to_struct_union_type(eff_type);
361+
const struct_union_typet &struct_union_type =
362+
to_struct_union_type(ns.follow(symbol.type));
354363
const struct_union_typet::componentst &components=
355364
struct_union_type.components();
356365
unsigned seen=0;
@@ -364,15 +373,12 @@ exprt string_abstractiont::make_val_or_dummy_rec(goto_programt &dest,
364373
if(it->get_name()!=it2->get_name())
365374
continue;
366375

367-
const typet &eff_sub_type=ns.follow(it2->type());
368-
if(eff_sub_type.id()==ID_pointer ||
369-
eff_sub_type.id()==ID_array ||
370-
eff_sub_type.id()==ID_struct ||
371-
eff_sub_type.id()==ID_union)
376+
if(
377+
it2->type().id() == ID_pointer || it2->type().id() == ID_array ||
378+
it2->type().id() == ID_struct_tag || it2->type().id() == ID_union_tag)
372379
{
373-
symbol_exprt sym_expr=add_dummy_symbol_and_value(
374-
dest, ref_instr, symbol, it2->get_name(),
375-
it2->type(), ns.follow(it->type()));
380+
symbol_exprt sym_expr = add_dummy_symbol_and_value(
381+
dest, ref_instr, symbol, it2->get_name(), it2->type(), it->type());
376382

377383
member_exprt member(symbol.symbol_expr(), it2->get_name(), it2->type());
378384

@@ -675,58 +681,56 @@ exprt string_abstractiont::build(
675681

676682
const typet &string_abstractiont::build_abstraction_type(const typet &type)
677683
{
678-
const typet &eff_type=ns.follow(type);
679-
abstraction_types_mapt::const_iterator map_entry=
680-
abstraction_types_map.find(eff_type);
684+
abstraction_types_mapt::const_iterator map_entry =
685+
abstraction_types_map.find(type);
681686
if(map_entry!=abstraction_types_map.end())
682687
return map_entry->second;
683688

684689
abstraction_types_mapt tmp;
685690
tmp.swap(abstraction_types_map);
686-
build_abstraction_type_rec(eff_type, tmp);
691+
build_abstraction_type_rec(type, tmp);
687692

688693
abstraction_types_map.swap(tmp);
689-
map_entry=tmp.find(eff_type);
690-
CHECK_RETURN(map_entry != tmp.end());
691-
return abstraction_types_map.insert(
692-
std::make_pair(eff_type, map_entry->second)).first->second;
694+
abstraction_types_map.insert(tmp.begin(), tmp.end());
695+
map_entry = abstraction_types_map.find(type);
696+
CHECK_RETURN(map_entry != abstraction_types_map.end());
697+
return map_entry->second;
693698
}
694699

695700
const typet &string_abstractiont::build_abstraction_type_rec(const typet &type,
696701
const abstraction_types_mapt &known)
697702
{
698-
const typet &eff_type=ns.follow(type);
699-
abstraction_types_mapt::const_iterator known_entry=known.find(eff_type);
703+
abstraction_types_mapt::const_iterator known_entry = known.find(type);
700704
if(known_entry!=known.end())
701705
return known_entry->second;
702706

703707
::std::pair<abstraction_types_mapt::iterator, bool> map_entry(
704-
abstraction_types_map.insert(::std::make_pair(eff_type, typet{ID_nil})));
708+
abstraction_types_map.insert(::std::make_pair(type, typet{ID_nil})));
705709
if(!map_entry.second)
706710
return map_entry.first->second;
707711

708-
if(eff_type.id()==ID_array || eff_type.id()==ID_pointer)
712+
if(type.id() == ID_array || type.id() == ID_pointer)
709713
{
710714
// char* or void* or char[]
711-
if(is_char_type(eff_type.subtype()) ||
712-
eff_type.subtype().id()==ID_empty)
715+
if(is_char_type(type.subtype()) || type.subtype().id() == ID_empty)
713716
map_entry.first->second=pointer_type(string_struct);
714717
else
715718
{
716-
const typet &subt=build_abstraction_type_rec(eff_type.subtype(), known);
719+
const typet &subt = build_abstraction_type_rec(type.subtype(), known);
717720
if(!subt.is_nil())
718721
{
719-
if(eff_type.id()==ID_array)
720-
map_entry.first->second=
721-
array_typet(subt, to_array_type(eff_type).size());
722+
if(type.id() == ID_array)
723+
map_entry.first->second =
724+
array_typet(subt, to_array_type(type).size());
722725
else
723726
map_entry.first->second=pointer_type(subt);
724727
}
725728
}
726729
}
727-
else if(eff_type.id()==ID_struct || eff_type.id()==ID_union)
730+
else if(type.id() == ID_struct_tag || type.id() == ID_union_tag)
728731
{
729-
const struct_union_typet &struct_union_type=to_struct_union_type(eff_type);
732+
const struct_union_typet &struct_union_type =
733+
to_struct_union_type(ns.follow(type));
730734

731735
struct_union_typet::componentst new_comp;
732736
for(const auto &comp : struct_union_type.components())
@@ -745,9 +749,31 @@ const typet &string_abstractiont::build_abstraction_type_rec(const typet &type,
745749
}
746750
if(!new_comp.empty())
747751
{
748-
struct_union_typet t(eff_type.id());
749-
t.components().swap(new_comp);
750-
map_entry.first->second=t;
752+
struct_union_typet abstracted_type = struct_union_type;
753+
abstracted_type.components().swap(new_comp);
754+
755+
const symbolt &existing_tag_symbol =
756+
ns.lookup(to_tag_type(type).get_identifier());
757+
symbolt &abstracted_type_symbol = get_fresh_aux_symbol(
758+
abstracted_type,
759+
"",
760+
id2string(existing_tag_symbol.name),
761+
existing_tag_symbol.location,
762+
existing_tag_symbol.mode,
763+
ns,
764+
symbol_table);
765+
abstracted_type_symbol.is_type = true;
766+
abstracted_type_symbol.is_lvalue = false;
767+
abstracted_type_symbol.is_state_var = false;
768+
abstracted_type_symbol.is_thread_local = true;
769+
abstracted_type_symbol.is_file_local = true;
770+
abstracted_type_symbol.is_auxiliary = false;
771+
abstracted_type_symbol.is_macro = true;
772+
773+
if(type.id() == ID_struct_tag)
774+
map_entry.first->second = struct_tag_typet{abstracted_type_symbol.name};
775+
else
776+
map_entry.first->second = union_tag_typet{abstracted_type_symbol.name};
751777
}
752778
}
753779

0 commit comments

Comments
 (0)