Skip to content

Store the typedef identifier in the symbol_type #345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/ansi-c/ansi_c_convert_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ Function: ansi_c_convert_typet::write

void ansi_c_convert_typet::write(typet &type)
{
irep_idt _typedef = type.get(ID_typedef);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems weird and not required.

type.clear();
type.set(ID_typedef,_typedef);

// first, do "other"

Expand Down
11 changes: 11 additions & 0 deletions src/ansi-c/ansi_c_declaration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ typet ansi_c_declarationt::full_type(

*p=type();

// retain typedef for dump-c
if(get_is_typedef())
result.set(ID_typedef,declarator.get_name());
// If this declaration was declared with a typedef'd type, we record it in the
// type of the expression.
irep_idt typedef_type=declarator.get(ID_typedef);
if(typedef_type!="")
{
result.set(ID_typedef, typedef_type);
}

return result;
}

Expand Down
15 changes: 15 additions & 0 deletions src/ansi-c/ansi_c_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ void ansi_c_parsert::add_declarator(
irept &declarator)
{
assert(declarator.is_not_nil());

irep_idt typedefd_name="";
if(declarator.id()==ID_symbol)
{
if(declaration.type().id()==ID_symbol)
{
typedefd_name=declaration.type().get(ID_identifier);
}
}

ansi_c_declarationt &ansi_c_declaration=
to_ansi_c_declaration(declaration);

Expand Down Expand Up @@ -197,6 +207,11 @@ void ansi_c_parsert::add_declarator(
identifier.prefixed_name=prefixed_name;
}

if(typedefd_name!="")
{
new_declarator.set(ID_typedef, typedefd_name);
}

ansi_c_declaration.declarators().push_back(new_declarator);
}

Expand Down
20 changes: 18 additions & 2 deletions src/ansi-c/c_typecheck_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Author: Daniel Kroening, [email protected]
#include "type2name.h"
#include "c_storage_spec.h"

#include <iostream>

/*******************************************************************\

Function: c_typecheck_baset::to_string
Expand Down Expand Up @@ -96,6 +98,9 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
bool is_function=symbol.type.id()==ID_code;

const typet &final_type=follow(symbol.type);
// std::cout << "BASENAME: " << symbol.base_name << std::endl;
// std::cout << "TYPE: " << symbol.type.pretty() << std::endl;
// std::cout << "FINAL: " << final_type.pretty() << std::endl;

// set a few flags
symbol.is_lvalue=!symbol.is_type && !symbol.is_macro;
Expand Down Expand Up @@ -127,13 +132,23 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
(final_type.id()==ID_struct ||
final_type.id()==ID_incomplete_struct))
{
symbol.pretty_name="struct "+id2string(symbol.base_name);
if(symbol.type.find(ID_typedef).is_not_nil())
symbol.pretty_name=symbol.type.get(ID_typedef);
else
symbol.pretty_name="struct "+id2string(symbol.base_name);
}
else if(symbol.is_type &&
(final_type.id()==ID_union ||
final_type.id()==ID_incomplete_union))
{
symbol.pretty_name="union "+id2string(symbol.base_name);
if(symbol.type.find(ID_typedef).is_not_nil())
{
symbol.pretty_name=symbol.type.get(ID_typedef);
symbol_table.symbols.find(symbol.type.get(ID_identifier))->second.pretty_name=symbol.type.get(ID_typedef);
symbol_table.symbols.find(symbol.type.get(ID_identifier))->second.type.set(ID_typedef,symbol.pretty_name);
}
else
symbol.pretty_name="union "+id2string(symbol.base_name);
}
else if(symbol.is_type &&
(final_type.id()==ID_c_enum ||
Expand All @@ -149,6 +164,7 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
// see if we have it already
symbol_tablet::symbolst::iterator old_it=symbol_table.symbols.find(symbol.name);


if(old_it==symbol_table.symbols.end())
{
// just put into symbol_table
Expand Down
11 changes: 11 additions & 0 deletions src/ansi-c/c_typecheck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Author: Daniel Kroening, [email protected]
#include "type2name.h"
#include "ansi_c_convert_type.h"

#include <iostream>

/*******************************************************************\

Function: c_typecheck_baset::typecheck_type
Expand Down Expand Up @@ -52,12 +54,14 @@ void c_typecheck_baset::typecheck_type(typet &type)
c_qualifiers+=c_qualifierst(type.subtype());
bool packed=type.get_bool(ID_C_packed);
exprt alignment=static_cast<const exprt &>(type.find(ID_C_alignment));
irept _typedef=type.find(ID_typedef);

type.swap(type.subtype());

c_qualifiers.write(type);
if(packed) type.set(ID_C_packed, true);
if(alignment.is_not_nil()) type.add(ID_C_alignment, alignment);
if(_typedef.is_not_nil()) type.add(ID_typedef, _typedef);

return; // done
}
Expand Down Expand Up @@ -726,11 +730,15 @@ void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type)
// Anonymous? Must come with body.
assert(have_body);

// std::cout << "__TYPE: " << type.pretty() << std::endl;

// produce symbol
symbolt compound_symbol;
compound_symbol.is_type=true;
compound_symbol.type=type;
compound_symbol.location=type.source_location();
if(compound_symbol.type.find(ID_typedef).is_not_nil())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be required, but I don't really understand the "already_typechecked" thing so don't know what can cause that to fail.

compound_symbol.pretty_name=compound_symbol.type.get(ID_typedef);

typecheck_compound_body(to_struct_union_type(compound_symbol.type));

Expand All @@ -739,6 +747,9 @@ void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type)
compound_symbol.name="tag-#anon#"+typestr;
identifier=compound_symbol.name;

// std::cout << "TYPEDEF: " << compound_symbol.type.get_string(ID_typedef) << std::endl;
// std::cout << "BASENAME: " << id2string(compound_symbol.base_name) << std::endl;

// We might already have the same anonymous union/struct,
// and this is simply ok. Note that the C standard treats
// these as different types.
Expand Down
74 changes: 55 additions & 19 deletions src/ansi-c/expr2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,12 @@ std::string expr2ct::convert_rec(
{
const struct_typet &struct_type=to_struct_type(src);

std::string dest=q+"struct";
std::string dest=q;

if(src.find(ID_typedef).is_not_nil())
dest+="typedef struct";
else
dest+="struct";

const irep_idt &tag=struct_type.get_tag();
if(tag!="") dest+=" "+id2string(tag);
Expand All @@ -378,7 +383,10 @@ std::string expr2ct::convert_rec(

dest+=" }";

dest+=d;
if(src.find(ID_typedef).is_not_nil())
dest+=src.get_string(ID_typedef);
else
dest+=d;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peterschrammel How come we only add on the d (declarator) string if not a typedef. Not really clear on exactly what could be in d at this point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does appear to be a bug, for the following code:

typedef struct tag_struct_name
{
	int x;
	float y;
} MYSTRUCT;

void fun()
{
	   const struct tag_struct_name tag_struct_var = {.x = 1, .y = 3.14f};
	   const MYSTRUCT mystruct_var = {.x = 3, .y = 2.1f};
}

I get the following symbols:

Symbol......: fun::1::mystruct_var
Pretty name.: fun::1::mystruct_var
Module......: main
Base name...: mystruct_var
Mode........: C
Type........: const MYSTRUCT
Value.......: { .x=3, .y=2.100000e+0f }
Flags.......: lvalue thread_local file_local
Location....: file main.c line 11 function fun

Symbol......: fun::1::tag_struct_var
Pretty name.: fun::1::tag_struct_var
Module......: main
Base name...: tag_struct_var
Mode........: C
Type........: struct tag_struct_name
Value.......: { .x=1, .y=3.140000e+0f }
Flags.......: lvalue thread_local file_local
Location....: file main.c line 10 function fun

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this seems unrelated as I get this problem on the main branch, I have created an issue #355 and a PR that includes a regression test checking for it: #356


return dest;
}
Expand All @@ -396,7 +404,12 @@ std::string expr2ct::convert_rec(
{
const union_typet &union_type=to_union_type(src);

std::string dest=q+"union";
std::string dest=q;

if(src.find(ID_typedef).is_not_nil())
dest+="typedef union";
else
dest+="union";

const irep_idt &tag=union_type.get_tag();
if(tag!="") dest+=" "+id2string(tag);
Expand All @@ -414,7 +427,10 @@ std::string expr2ct::convert_rec(

dest+=" }";

dest+=d;
if(src.find(ID_typedef).is_not_nil())
dest+=src.get_string(ID_typedef);
else
dest+=d;

return dest;
}
Expand Down Expand Up @@ -538,29 +554,47 @@ std::string expr2ct::convert_rec(
}
else if(src.id()==ID_symbol)
{
const typet &followed=ns.follow(src);
symbol_typet symbolic_type=to_symbol_type(src);
const irep_idt &typedef_identifer=symbolic_type.get(ID_typedef);

if(followed.id()==ID_struct)
// Providing we have a valid identifer, we can just use that rather than
// trying to find the concrete type
if(typedef_identifer!="")
{
std::string dest=q+"struct";
const irep_idt &tag=to_struct_type(followed).get_tag();
if(tag!="") dest+=" "+id2string(tag);
dest+=d;
return dest;
return q+id2string(typedef_identifer)+d;
}
else if(followed.id()==ID_union)
else
{
std::string dest=q+"union";
const irep_idt &tag=to_union_type(followed).get_tag();
if(tag!="") dest+=" "+id2string(tag);
dest+=d;
return dest;
const typet &followed=ns.follow(src);

if(followed.id()==ID_struct)
{
if(followed.find(ID_typedef).is_not_nil())
return followed.get_string(ID_typedef)+d;
std::string dest=q+"struct";
const irep_idt &tag=to_struct_type(followed).get_tag();
if(tag!="") dest+=" "+id2string(tag);
dest+=d;
return dest;
}
else if(followed.id()==ID_union)
{
if(followed.find(ID_typedef).is_not_nil())
return followed.get_string(ID_typedef)+d;
std::string dest=q+"union";
const irep_idt &tag=to_union_type(followed).get_tag();
if(tag!="") dest+=" "+id2string(tag);
dest+=d;
return dest;
}
else
return convert_rec(followed, new_qualifiers, declarator);
}
else
return convert_rec(followed, new_qualifiers, declarator);
}
else if(src.id()==ID_struct_tag)
{
if(src.find(ID_typedef).is_not_nil())
return src.get_string(ID_typedef)+d;
const struct_tag_typet &struct_tag_type=
to_struct_tag_type(src);

Expand All @@ -573,6 +607,8 @@ std::string expr2ct::convert_rec(
}
else if(src.id()==ID_union_tag)
{
if(src.find(ID_typedef).is_not_nil())
return src.get_string(ID_typedef)+d;
const union_tag_typet &union_tag_type=
to_union_tag_type(src);

Expand Down
Loading