-
Notifications
You must be signed in to change notification settings - Fork 273
C++ front end fixes [blocks: #2554] #1260
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
Conversation
I will need to make the linter happy and figure out how to support the Visual Studio-provided syntax. |
I am currently looking at the failing checks. I fixed the linter complaints outside of regression, but there will be new ones, because assert() must be replaced by INVARIANT or one of its derivatives. |
I have a fix for the compilation errors with that happen with -DDEBUG. |
@andreast271 ( and @tautschnig and @peterschrammel ) thank you for looking at this; this is incredibly valuable work. |
src/cpp/parse.cpp
Outdated
merge_types(attr, t); | ||
break; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This creates a merged type with op0 = function_type, op1 = noreturn.
Is that intended? Typecheck code assumes that following subtypes uses the back of the list for merged types. Here this would be the noreturn node, which seems odd.
Adding the noreturn attribute in this way will currently cause an assertion failure in cpp_declaratort::merge_type for regression test cases that #include assert.h.
Even after a fix in cpp_declaratort::merge_type the type would then fail to typecheck in cpp_convert_plain_type(typet &type)
I'm happy to work on fix after getting an explanation of the intended use of merged_type in C++ frontend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe I had tried to mimic what the C front-end does. The obvious fix would be to swap the parameters here, but I'm not sure this will result in the attribute being picked up at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where should the attribute end up after type checking? At some point function_type is converted to code_type. At that stage the type qualifiers need to be put somewhere in the code_type node. I didn't see anything in the C++ front end that does that, so right now cpp_convert_plain_type fails because it cannot deal with a qualifier of a function type. I could fix it if I understood how the result of type checking the function should look like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The merge_types function in the C and C++ front end use a different convention for the order of arguments: in the C front end, it is merge_types(dest, src), while in C++ it is merge_types(src, dest). A possible fix would then be to change the merge_types function in C++ so that it adds the new type at the front of the subtypes (or rather anywhere but at the end). Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the merge_types functions seems to work. Regression passes and I also have a fix for the -DDEBUG compilation failures and some of the linter issues. What is the process for gettings these fixes into the PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you check whether you are able to push to my branch? If you aren't, you can certainly create a pull request in my fork (against that branch), and as soon as I merge it the changes will show up here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even with these changes C++ is not fully supported yet (not even C++-98). However, the known problematic areas are clearly documented in the code.
This would need rebasing... |
6458759
to
7d8b507
Compare
Rebase done. |
7d8b507
to
36246e1
Compare
The linter failures are all from cpp files in the regression. I discussed this with @thk123 a while ago. He agreed that the linter shouldn't run on regression test sources, and also clarified that linter failures do not prevent a merge. IMO the correct fix is to change the linter so that it skips the regression directory, but that should be a separate PR. |
Prefix: I have given up on supporting VS headers in cbmc. I compile cbmc on Windows with VisualStudio (not just the compiler, but the IDE), but even then I run under cygwin using There are 5 test failures in the cpp group on windows reported by the appveyor build:
@tautschnig : I can create a PR to tautschnig/c++-front-end-fixes with the suggested solutions if you agree with them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few style comments. I won't approve since I don't know nearly enough about the C++ front-end.
@@ -6,6 +6,7 @@ Author: Daniel Kroening, [email protected] | |||
|
|||
\********************************************************************/ | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Undo
|
||
// We have to prevent the same method to be added multiple times | ||
// otherwise we get duplicated symbol prefixes | ||
if(methods_seen.find(_method_symbol->name) != methods_seen.end()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use insert
and check its return value rather than find-then-insert double-lookup
src/cpp/cpp_typecheck_resolve.cpp
Outdated
it1!=identifiers.end(); | ||
for(resolve_identifierst::const_iterator | ||
it1=old_identifiers.begin(); | ||
it1!=old_identifiers.end(); | ||
it1++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well switch to pre-increment while we're changing things here
src/cpp/cpp_typecheck_resolve.cpp
Outdated
it1++) | ||
{ | ||
#if 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ifdef DEBUG?
src/cpp/parse.cpp
Outdated
// since several analysis functions traverse via the end for | ||
// merged_types | ||
typet::subtypest &sub=dest.subtypes(); | ||
sub.emplace(sub.begin(), src); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well use insert, since emplace is just calling a copy-constructor itself here plus doing some mildly-costly (in my experience) gymnastics to avoid copying the argument in the meantime
@@ -1,4 +1,4 @@ | |||
/**** ***************************************************************\ | |||
/********************************************************************\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accidental change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No: 03c9894 ("Fix broken comment frame", 2017-07-31)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got to commit: "C++ front-end: parse GCC attributes"
Since the changes come from a range of people, I have tagged the comments with who the commit was introduced by. I don't know if it is easier for you to apply them all @tautschnig or for the relevant people to apply the changes (in particular the comments).
I also should flag up I've not made an attempt to deeply understand the C++ parsing so cannot verify that the code is reasonable or that the tests are sufficient.
@@ -1,4 +1,4 @@ | |||
CORE | |||
KNOWNBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there isn't already, could you raise an issue and add it as a comment at the bottom of test.desc ( @tautschnig )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -15,3 +15,6 @@ struct __member_pointer_traits_imp<_Rp (_Class::*)() const> | |||
{ | |||
}; | |||
|
|||
int main(int argc, char* argv[]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this become main.cpp
as with the other file ( @tautschnig )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know -- there isn't really enough information in the initial commit message for that file (e155e42), so I'd suggest to leave it as is. It should not have any impact. Should.
src/cpp/cpp_constructor.cpp
Outdated
@@ -47,12 +47,16 @@ codet cpp_typecheckt::cpp_constructor( | |||
// The purpose of the tag #array_ini is to rule out ill-formed | |||
// programs. | |||
|
|||
// TODO: in a program it is not allowed, but the implementation of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this comment is very clear ( @peterschrammel )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
De/activating this code has no effect on cpp and systemc regression tests. We should remove this change from this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed the commit "Deactivate internal array initializer".
src/cpp/cpp_declarator_converter.cpp
Outdated
@@ -11,6 +11,12 @@ Author: Daniel Kroening, [email protected] | |||
|
|||
#include "cpp_declarator_converter.h" | |||
|
|||
//#define DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: don't check this line in ( @peterschrammel )
src/cpp/cpp_declarator_converter.cpp
Outdated
@@ -11,6 +11,12 @@ Author: Daniel Kroening, [email protected] | |||
|
|||
#include "cpp_declarator_converter.h" | |||
|
|||
//#define DEBUG | |||
|
|||
#ifdef DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly this is just ending up in the wrong commit - but we don't seem to use iostream
in this cpp. ( @peterschrammel )
@@ -9,19 +9,30 @@ Author: Daniel Kroening, [email protected] | |||
/// \file | |||
/// C++ Language Type Checking | |||
|
|||
//#define DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: don't check this in ( @peterschrammel )
src/cpp/cpp_typecheck_resolve.cpp
Outdated
@@ -11,6 +11,12 @@ Author: Daniel Kroening, [email protected] | |||
|
|||
#include "cpp_typecheck_resolve.h" | |||
|
|||
//#define DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: don't check in ( @peterschrammel )
src/cpp/cpp_typecheck.cpp
Outdated
{ | ||
if(expr.id()==ID_cpp_name) | ||
return true; | ||
forall_operands(it, expr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can you use a range based for loop here? Also since for loop extends over multiple lines please wrap in braces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in PR #6
src/cpp/cpp_typecheck_resolve.cpp
Outdated
@@ -11,7 +11,7 @@ Author: Daniel Kroening, [email protected] | |||
|
|||
#include "cpp_typecheck_resolve.h" | |||
|
|||
//#define DEBUG | |||
// #define DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: remove this line ( @peterschrammel )
src/cpp/cpp_typecheck_resolve.cpp
Outdated
identifiers.begin(); | ||
it2!=identifiers.end(); | ||
) // no it2++ | ||
for(resolve_identifierst::const_iterator it2=it1+1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: giving these iterators meaningful names might make this code a bit easier to follow
Did review commit by commit, so might still be worth checking the comments that are now out-dated, but they may be fixed in later commits |
32d1703
to
23a40ff
Compare
669de88
to
8524b10
Compare
@andreast271 I've addressed the remaining concerns voiced by @thk123. I believe this would not warrant a final (?) review by @peterschrammel and should then be merged. There is of course a lot of work left to be done in this front-end... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly minor suggestions (and I should stress I am not familiar with this code), but looks good. Main thing I'd like to see if the tests for the attribute support if they don't already exist.
regression/cpp/gcc_vector1/main.cpp
Outdated
|
||
#else | ||
|
||
void setzero() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come we're only testing on GNUC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea whether Visual Studio supports (the same) vector types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MSVC doesn't support the vector_size attribute. It does have 128-bit data types. However, these are defined in header files, and the cbmc C++ front end cannot parse MSVC C++ header files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the syntax to use them the same as with GCC/Clang? Would you actually be able to contribute a KNOWNBUG
regression test that uses them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing testcase uses the typedef for __m128 from the xmmintrin.h header files that ships with gcc. I can do the same for MSVC and add that to the existing test case in a separate PR (after this one is merged). There is an interesting problem, though: CBMC with PARSER.mode==configt::ansi_ct::flavourt::VISUAL_STUDIO
accepts the syntax of the test case, but the MSVC compiler does not: it complains that error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
Should cbmc in this case follow MSVC and report a parser error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be desirable if the CBMC front-end mimicked exactly what MSVC does, but that's surely not of the highest priority.
src/cpp/parse.cpp
Outdated
@@ -4401,6 +4401,16 @@ bool Parser::rClassSpec(typet &spec) | |||
{ | |||
if(!optAlignas(spec)) | |||
return false; | |||
|
|||
if(lex.LookAhead(0)==TOK_GCC_ATTRIBUTE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what this means exactly, but it would probably make sense to have some tests off GCC attributes after struct/class declarations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to dig up with those tests were: we do have them already, otherwise the change wouldn't have happened :-) - but then it might be rather implicit in that it's drawn in from system headers.
regression/cbmc/cpp1/test.desc
Outdated
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
^warning: ignoring |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Link to the issue would be great
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
regression/cbmc/cpp2/test.desc
Outdated
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
^warning: ignoring | ||
^equality without matching types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Link to the issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/cpp/cpp_convert_type.cpp
Outdated
@@ -130,6 +130,10 @@ void cpp_convert_typet::read_rec(const typet &type) | |||
constexpr_cnt++; | |||
else if(type.id()==ID_extern) | |||
extern_cnt++; | |||
else if(type.id()==ID_noreturn) | |||
{ | |||
noreturn_cnt++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: prefer prefix increment for consistency
++noreturn_cnt;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But ... that wouldn't be consistent here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR failed Diffblue compatibility checks (cbmc commit: 6447274).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/109163273
Status will be re-evaluated on next push.
Common spurious failures include: the cbmc commit has disappeared in the mean time (e.g. in a force-push); the author is not in the list of contributors (e.g. first-time contributors); compatibility was already broken by an earlier merge.
6447274
to
349875a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR failed Diffblue compatibility checks (cbmc commit: 349875a).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/109328420
Status will be re-evaluated on next push.
Common spurious failures include: the cbmc commit has disappeared in the mean time (e.g. in a force-push); the author is not in the list of contributors (e.g. first-time contributors); compatibility was already broken by an earlier merge.
349875a
to
9b416ca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR failed Diffblue compatibility checks (cbmc commit: 9b416ca).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/109357730
Status will be re-evaluated on next push.
Common spurious failures include: the cbmc commit has disappeared in the mean time (e.g. in a force-push); the author is not in the list of contributors (e.g. first-time contributors); compatibility was already broken by an earlier merge.
9b416ca
to
ddef9eb
Compare
@kroening This is finally ready for review - it used to be a monster, but is now down to 2 commits with just +90/−26 modified lines. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: ddef9eb).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/111944054
ddef9eb
to
1690609
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 1690609).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/112249534
1690609
to
5a735d6
Compare
This mirrors what the C front-end already does, but requires changes to constant propagation in the C++ front-end: we previously used macros, which serve a very different purpose otherwise. Fixes: diffblue#1490
5a735d6
to
a1c7330
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: a1c7330).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/112357550
feb3c1d
to
196ef9a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR failed Diffblue compatibility checks (cbmc commit: feb3c1d).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/112359540
Status will be re-evaluated on next push.
Common spurious failures include: the cbmc commit has disappeared in the mean time (e.g. in a force-push); the author is not in the list of contributors (e.g. first-time contributors); compatibility was already broken by an earlier merge.
We should perform as much sanity checking in regression tests as possible. This required cleaning up unused parameter identifiers and disabling sanity checking of names as is already done for Java, because we similarly have name mangling in C++.
While we already configured this in goto-cc, running CBMC with --winx64 or --win32 previously failed to set this.
196ef9a
to
86d4c0d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 86d4c0d).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/112363584
This is a series of fixes mainly compiled by @peterschrammel plus some additional work of mine.
This includes the following commits to be reviewed:
e92421d Do not use assert without prior declarationbe13461 Fix syntax errors in C++ regression testsc9094dd Fix broken comment frame12a71d1 Do not check friend declarations in wrong scope (moved to C++ function disambiguation and template scope cleanup [blocks: #1260] #2318)6ffc37c Do not add method body on declaration (will be handled on use)4576f14 Line break6dc9b9b Fix delayed method body conversion for templates1db4a04 Initial set of mini-system-c testsc9f3334 Clean up unused template instantiation symbolsdc7b8c8 Fix disambiguationba0df47 C++ front-end: store typedef names (moved to C++ front-end: store typedef names #4551)43c0aa6 C++ front-end: parse GCC attributescafaac5 Permit asm post-declarator mixed in any order with other qualifiers6c6618b Permit GCC attributes after struct/class in class declarationda7822b Mark already-typechecked types as suchf9e723e Typecheck initializer listsd1bf14a C++ front-end: Use C factory for compiler builtins5c14d09 Do not lose method qualifiersa67c62b Whitespace cleanup, comment type fixedf165ca9 Fix operator parsingd351125 Failing regression test from C++ Support For Operator Overloading #661d3c2f9d Failing regression test from Unwarranted "equality without matching types" error #9339fdefe8 Enable compilation with DEBUG defined. Some of the code inside #ifdef DEBUG ... #ENDIF had become stale (moved to C++ front-end: Enable compilation with DEBUG defined [blocks: #1260] #4475)edc0cd8 Swap order of subtypes in construction of merged_type nodes, so that the main type is at the end. Handle and record GCC function attribute noreturn.f89a086 Style improvements (moved to C++ front-end: Enable compilation with DEBUG defined [blocks: #1260] #4475)7cac0ce Prevent regression failures of cpp tests on windows.81a5569 Do not lint .h files in regression/a6e83f6 Don't abbreviate variable names (moved to Cleanup cpp_convert_typet: no abbreviations, pre-increment, size_t #4552)44cb7c9 decltype(bit field type) is the underlying subtypec0a4278 Move is_template_scope to parent as it holds the id_class memberab0812c Factor out set-up of sub_scope for template instantiation87fddb8 Properly set up scope prefix instead of hacking it away0c686a8 Remove duplicate save_scopeb3329e8 Remove redundant invariants