Skip to content

Commit b4e2540

Browse files
committed
Fix dump-c output involving typedef names
Follow-up to 99067de, which made expr2c prefer typedef names over original type expressions.
1 parent 340a5ff commit b4e2540

File tree

6 files changed

+159
-1
lines changed

6 files changed

+159
-1
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
typedef long int off_t;
2+
typedef signed char smallint;
3+
4+
typedef struct chain_s {
5+
struct node_s *first;
6+
struct node_s *last;
7+
const char *programname;
8+
} chain;
9+
10+
typedef struct node_s {
11+
struct node_s *n;
12+
} node;
13+
14+
typedef struct dumper_t_x
15+
{
16+
node n; //chaning this line to 'struct node_s n' removes some bugs
17+
off_t dump_skip;
18+
signed int dump_length;
19+
smallint dump_vflag;
20+
} dumper_t;
21+
22+
typedef struct FS_x
23+
{
24+
struct FS *nextfs;
25+
signed int bcnt;
26+
} FS;
27+
28+
29+
dumper_t * alloc_dumper(void)
30+
{
31+
return (void*) 0;
32+
}
33+
34+
int main() {
35+
node n;
36+
chain c;
37+
dumper_t a;
38+
dumper_t b[3];
39+
alloc_dumper();
40+
return 0;
41+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
main.c
3+
--dump-c
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring

src/goto-instrument/dump_c.cpp

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@ void dump_ct::operator()(std::ostream &os)
285285
os << std::endl;
286286
}
287287

288+
// global typedefs
289+
for(const auto &td : typedef_map)
290+
if(!td.second.empty())
291+
os << td.second << std::endl;
292+
if(!typedef_map.empty())
293+
os << std::endl;
294+
288295
if(!func_decl_stream.str().empty())
289296
os << func_decl_stream.str() << std::endl;
290297
if(!compound_body_stream.str().empty())
@@ -338,6 +345,8 @@ void dump_ct::convert_compound(
338345
bool recursive,
339346
std::ostream &os)
340347
{
348+
collect_typedefs(type);
349+
341350
if(type.id()==ID_symbol)
342351
{
343352
const symbolt &symbol=
@@ -468,6 +477,8 @@ void dump_ct::convert_compound(
468477

469478
if(recursive && non_array_type->id()!=ID_pointer)
470479
convert_compound(comp.type(), comp.type(), recursive, os);
480+
else
481+
collect_typedefs(comp.type());
471482

472483
irep_idt comp_name=comp.get_name();
473484

@@ -521,7 +532,16 @@ void dump_ct::convert_compound(
521532
struct_body << ";" << std::endl;
522533
}
523534

524-
os << type_to_string(unresolved);
535+
typet unresolved_clean=unresolved;
536+
const irep_idt &typedef_str=unresolved.get(ID_C_typedef);
537+
if(!typedef_str.empty())
538+
{
539+
unresolved_clean.remove(ID_C_typedef);
540+
typedef_map[typedef_str]="";
541+
os << "typedef ";
542+
}
543+
544+
os << type_to_string(unresolved_clean);
525545
if(!base_decls.str().empty())
526546
{
527547
assert(language->id()=="cpp");
@@ -548,6 +568,8 @@ void dump_ct::convert_compound(
548568
os << " __attribute__ ((__transparent_union__))";
549569
if(type.get_bool(ID_C_packed))
550570
os << " __attribute__ ((__packed__))";
571+
if(!typedef_str.empty())
572+
os << " " << typedef_str;
551573
os << ";";
552574
os << std::endl;
553575
os << std::endl;
@@ -898,6 +920,10 @@ void dump_ct::cleanup_decl(
898920

899921
tmp.add_instruction(END_FUNCTION);
900922

923+
std::unordered_set<irep_idt, irep_id_hash> typedef_names;
924+
for(const auto &td : typedef_map)
925+
typedef_names.insert(td.first);
926+
901927
code_blockt b;
902928
goto_program2codet p2s(
903929
irep_idt(),
@@ -906,6 +932,7 @@ void dump_ct::cleanup_decl(
906932
b,
907933
local_static,
908934
local_type_decls,
935+
typedef_names,
909936
system_headers);
910937
p2s();
911938

@@ -915,6 +942,66 @@ void dump_ct::cleanup_decl(
915942

916943
/*******************************************************************\
917944
945+
Function: dump_ct::collect_typedefs
946+
947+
Inputs:
948+
949+
Outputs:
950+
951+
Purpose:
952+
953+
\*******************************************************************/
954+
955+
void dump_ct::collect_typedefs(const typet &type)
956+
{
957+
if(type.id()==ID_code)
958+
{
959+
const code_typet &code_type=to_code_type(type);
960+
961+
collect_typedefs(code_type.return_type());
962+
for(const auto &param : code_type.parameters())
963+
collect_typedefs(param.type());
964+
}
965+
else if(type.id()==ID_pointer || type.id()==ID_array)
966+
{
967+
collect_typedefs(type.subtype());
968+
}
969+
else if(type.id()==ID_symbol)
970+
{
971+
const symbolt &symbol=
972+
ns.lookup(to_symbol_type(type).get_identifier());
973+
collect_typedefs(symbol.type);
974+
}
975+
976+
const irep_idt &typedef_str=type.get(ID_C_typedef);
977+
978+
if(!typedef_str.empty())
979+
{
980+
std::pair<typedef_mapt::iterator, bool> entry=
981+
typedef_map.insert({typedef_str, ""});
982+
983+
if(entry.second &&
984+
(typedef_str=="__gnuc_va_list" ||
985+
typedef_str == "va_list"))
986+
{
987+
system_headers.insert("stdarg.h");
988+
}
989+
else if(entry.second)
990+
{
991+
typet t=type;
992+
t.remove(ID_C_typedef);
993+
994+
std::ostringstream oss;
995+
oss << "typedef " << type_to_string(t) << " "
996+
<< typedef_str << ';';
997+
998+
entry.first->second=oss.str();
999+
}
1000+
}
1001+
}
1002+
1003+
/*******************************************************************\
1004+
9181005
Function: dump_ct::convert_global_variables
9191006
9201007
Inputs:
@@ -935,6 +1022,9 @@ void dump_ct::convert_global_variable(
9351022
!converted_global.insert(symbol.name).second)
9361023
return;
9371024

1025+
if(func.empty() || symbol.is_extern)
1026+
collect_typedefs(symbol.type);
1027+
9381028
code_declt d(symbol.symbol_expr());
9391029

9401030
find_symbols_sett syms;
@@ -1021,13 +1111,18 @@ void dump_ct::convert_function_declaration(
10211111
code_blockt b;
10221112
std::list<irep_idt> type_decls, local_static;
10231113

1114+
std::unordered_set<irep_idt, irep_id_hash> typedef_names;
1115+
for(const auto &td : typedef_map)
1116+
typedef_names.insert(td.first);
1117+
10241118
goto_program2codet p2s(
10251119
symbol.name,
10261120
func_entry->second.body,
10271121
copied_symbol_table,
10281122
b,
10291123
local_static,
10301124
type_decls,
1125+
typedef_names,
10311126
system_headers);
10321127
p2s();
10331128

@@ -1062,6 +1157,8 @@ void dump_ct::convert_function_declaration(
10621157
if(symbol.name!=goto_functionst::entry_point() &&
10631158
symbol.name!=ID_main)
10641159
{
1160+
collect_typedefs(symbol.type);
1161+
10651162
os_decl << "// " << symbol.name << std::endl;
10661163
os_decl << "// " << symbol.location << std::endl;
10671164
os_decl << make_decl(symbol.name, symbol.type) << ";" << std::endl;

src/goto-instrument/dump_c_class.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class dump_ct
5959
declared_enum_constants_mapt;
6060
declared_enum_constants_mapt declared_enum_constants;
6161

62+
typedef std::map<irep_idt, std::string> typedef_mapt;
63+
typedef_mapt typedef_map;
64+
6265
void init_system_library_map();
6366

6467
std::string type_to_string(const typet &type);
@@ -85,6 +88,8 @@ class dump_ct
8588
return d_str.substr(0, d_str.size()-1);
8689
}
8790

91+
void collect_typedefs(const typet &type);
92+
8893
void convert_compound_declaration(
8994
const symbolt &symbol,
9095
std::ostream &os_body);

src/goto-instrument/goto_program2code.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,11 @@ void goto_program2codet::cleanup_code(
18181818

18191819
add_local_types(code.op0().type());
18201820

1821+
const irep_idt &typedef_str=code.op0().type().get(ID_C_typedef);
1822+
if(!typedef_str.empty() &&
1823+
typedef_names.find(typedef_str)==typedef_names.end())
1824+
code.op0().type().remove(ID_C_typedef);
1825+
18211826
return;
18221827
}
18231828
else if(code.get_statement()==ID_function_call)

src/goto-instrument/goto_program2code.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class goto_program2codet
4949
code_blockt &_dest,
5050
id_listt &_local_static,
5151
id_listt &_type_names,
52+
const id_sett &_typedef_names,
5253
std::set<std::string> &_system_headers):
5354
func_name(identifier),
5455
goto_program(_goto_program),
@@ -57,6 +58,7 @@ class goto_program2codet
5758
toplevel_block(_dest),
5859
local_static(_local_static),
5960
type_names(_type_names),
61+
typedef_names(_typedef_names),
6062
system_headers(_system_headers)
6163
{
6264
assert(local_static.empty());
@@ -78,6 +80,7 @@ class goto_program2codet
7880
code_blockt &toplevel_block;
7981
id_listt &local_static;
8082
id_listt &type_names;
83+
const id_sett &typedef_names;
8184
std::set<std::string> &system_headers;
8285
std::unordered_set<exprt, irep_hash> va_list_expr;
8386

0 commit comments

Comments
 (0)