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 1 commit
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
4 changes: 4 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,10 @@ typet ansi_c_declarationt::full_type(

*p=type();

// retain typedef for dump-c
if(get_is_typedef())
result.set(ID_typedef,declarator.get_name());

return result;
}

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
32 changes: 28 additions & 4 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 @@ -542,6 +558,8 @@ std::string expr2ct::convert_rec(

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);
Expand All @@ -550,6 +568,8 @@ std::string expr2ct::convert_rec(
}
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);
Expand All @@ -561,6 +581,8 @@ std::string expr2ct::convert_rec(
}
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 +595,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