Skip to content

Fix dump-c output involving typedef names #858

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

Merged
merged 16 commits into from
Jul 3, 2017

Conversation

tautschnig
Copy link
Collaborator

Follow-up to 99067de, which made expr2c prefer typedef names over
original type expressions.

@tautschnig tautschnig force-pushed the dump-c-typedef branch 2 times, most recently from c6584f3 to cd720f1 Compare April 26, 2017 19:16
@peterschrammel peterschrammel requested a review from thk123 April 28, 2017 18:23
Copy link
Contributor

@thk123 thk123 left a comment

Choose a reason for hiding this comment

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

Apologies if some of the questions are not meaningful - I've not looked at this code much.

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

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

Function: dump_ct::collect_typedefs

Inputs:
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing documentation for this method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment addressed.

@@ -1062,6 +1160,8 @@ void dump_ct::convert_function_declaration(
if(symbol.name!=goto_functionst::entry_point() &&
symbol.name!=ID_main)
{
collect_typedefs(symbol.type);
Copy link
Contributor

Choose a reason for hiding this comment

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

How come we don't collect typedef's for the main function?

@@ -935,6 +1025,9 @@ void dump_ct::convert_global_variable(
!converted_global.insert(symbol.name).second)
return;

if(func.empty() || symbol.is_extern)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't really understand this condition. For example, is this function supposed to just convert global symbols and therefore we must first check either the containing function func is empty OR the symbol is external. Is there a reason why this condition does not include the possibility of symbol.value.is_not_nil().

{
system_headers.insert("stdarg.h");
}
else if(entry.second)
Copy link
Contributor

@thk123 thk123 May 2, 2017

Choose a reason for hiding this comment

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

This might be more clearly expressed as:

// If not already in the map
if(entry.second)
{
  if(typedef_str=="__gnuc_va_list" || typedef_str == "va_list")
  {
    system_headers.insert("stdarg.h");
  }
  else
  {
    typet t=type;
    t.remove(ID_C_typedef);
    std::ostringstream oss;
    oss << "typedef " << type_to_string(t) << " "
        << typedef_str << ';';
    entry.first->second=oss.str();
  }
}

To make it clearer that in either case the entry must be new to the map

main.c
--dump-c
^EXIT=0$
^SIGNAL=0$
Copy link
Contributor

Choose a reason for hiding this comment

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

It isn't clear to me what this test actually checks - could you perhaps add some matching lines

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've added comments in the test to clarify!

@@ -285,6 +285,13 @@ void dump_ct::operator()(std::ostream &os)
os << std::endl;
}

// global typedefs
for(const auto &td : typedef_map)
Copy link
Contributor

Choose a reason for hiding this comment

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

This function (operator()) is already unmanageably large - could this perhaps be pulled out into a dump_typedef_map(os) const method?

@thk123
Copy link
Contributor

thk123 commented May 3, 2017

I don't really understand this condition. For example, is this function supposed to just convert global symbols and therefore we must first check either the containing function func is empty OR the symbol is external. Is there a reason why this condition does not include the possibility of symbol.value.is_not_nil().

Is this addressed by moving the code to here: https://github.com/diffblue/cbmc/pull/858/files#diff-61b958cb13458a39e3868eea217a8bfcR65?

@@ -62,6 +62,19 @@ void dump_ct::operator()(std::ostream &os)
std::stringstream func_body_stream;
local_static_declst local_static_decls;

forall_symbols(it, copied_symbol_table.symbols)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be for(const auto &symbol_entry : copied_symbol_table.symbols)?

@@ -1062,6 +1178,8 @@ void dump_ct::convert_function_declaration(
if(symbol.name!=goto_functionst::entry_point() &&
symbol.name!=ID_main)
{
collect_typedefs(symbol.type, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment still seems relevant: How come we don't collect typedef's for the main function?

@tautschnig tautschnig force-pushed the dump-c-typedef branch 2 times, most recently from e173913 to 412ea82 Compare May 3, 2017 10:44
@tautschnig
Copy link
Collaborator Author

@thk123 Thank you very much for all your comments! Several of them have indeed been addressed by more comments ;-)

@thk123
Copy link
Contributor

thk123 commented May 4, 2017

@tautschnig I think both of the last two review comments are still applicable, let me know if you disagree. 1, 2

@tautschnig
Copy link
Collaborator Author

Would you mind copy-pasting your comment "1" as that link appears to be no longer valid? Also I think "2" is addressed by an additional comment that I've inserted above that line. But I may well be wrong!

Copy link
Contributor

@thk123 thk123 left a comment

Choose a reason for hiding this comment

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

Sorry about that! I've just reapplied the comments in the correct positions


void dump_ct::gather_global_typedefs()
{
forall_symbols(it, copied_symbol_table.symbols)
Copy link
Contributor

@thk123 thk123 May 4, 2017

Choose a reason for hiding this comment

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

Can this be for(const auto &symbol_entry : copied_symbol_table.symbols)

@@ -1062,6 +1224,10 @@ void dump_ct::convert_function_declaration(
if(symbol.name!=goto_functionst::entry_point() &&
symbol.name!=ID_main)
{
// make sure typedef names are available before outputting this
// declaration
collect_typedefs(symbol.type, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

How come we don't collect typedef's for the main function?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also I think "2" is addressed by an additional comment that I've inserted above that line

Well maybe, for me I read it as a justification to call colllect_typedefs, rather than to exclude collecting typedefs when looking at main. It also seems inconsistent, if user runs with --function foo we will collect typedefs from foo but not from main.

If you think this is correct, could you add a typedef within the main function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, thank you, I'll address this!

@tautschnig
Copy link
Collaborator Author

@thk123 I think I've finally addressed your comments, which were spot on!

Copy link
Contributor

@thk123 thk123 left a comment

Choose a reason for hiding this comment

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

Thanks - glad they were useful!

@@ -857,6 +883,14 @@ bool dump_ct::ignore(const symbolt &symbol)
system_headers.insert(it->second);
return true;
}
else if(!system_library_map.empty() &&
Copy link
Member

Choose a reason for hiding this comment

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

no else after return needed

@@ -857,6 +883,14 @@ bool dump_ct::ignore(const symbolt &symbol)
system_headers.insert(it->second);
return true;
}
else if(!system_library_map.empty() &&
has_prefix(file_str, "/usr/include/") &&
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to declare a constant string, since it should be used consistently in both occurrences.

@kroening
Copy link
Member

The test needs some #ifdef to make it not fail for the Windows world.

@tautschnig
Copy link
Collaborator Author

Test amended as the __attribute__ was completely irrelevant to the purpose of the test.

@tautschnig
Copy link
Collaborator Author

This should be ready to go as it has been tested on a few thousand Debian packages.

@peterschrammel
Copy link
Member

@tautschnig, please rebase

@tautschnig
Copy link
Collaborator Author

@peterschrammel Rebase done, assert -> invariant fixes added (2f7e317).

@tautschnig tautschnig assigned kroening and unassigned tautschnig Jul 3, 2017
tautschnig and others added 15 commits July 3, 2017 14:26
remove_internal_symbols must get to see typedef names so as not to remove type
symbols that constitute typedef names.

Follow-up to 99067de
Follow-up to 99067de, which made expr2c prefer typedef names over
original type expressions.

Thanks Andreas Stahlbauer for providing the regression tests and help in
debugging.

Fixes: diffblue#882
Fixes: diffblue#964
Fixes: diffblue#972
These refer to invalid symbols.
GCC does not accept an "f" suffix on integer constants.
Cleanup of list of known functions; added several C-library internal struct
types to avoid their output when the header will be declaring them.
The user-friendly default now is to produce #include statements for C library
functions; this can be disabled using --no-system-headers.
@kroening kroening merged commit c7ce527 into diffblue:master Jul 3, 2017
@tautschnig tautschnig deleted the dump-c-typedef branch July 3, 2017 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants