Skip to content

Fixes for CppParserTest#523

Merged
intjftw merged 3 commits intoEricsson:masterfrom
mcserep:cppparsertest-fixes
Apr 13, 2021
Merged

Fixes for CppParserTest#523
intjftw merged 3 commits intoEricsson:masterfrom
mcserep:cppparsertest-fixes

Conversation

@mcserep
Copy link
Collaborator

@mcserep mcserep commented Mar 10, 2021

Closes #439.

This PR fixes the strange issue that the unit tests failed when CodeCompass was compiled in Debug mode.
It turned out that these tests were really failing (for a long time actually), but when compiled Release mode, some ODB functions just fail silently and assertions are only done in Debug mode.

In most cases, the root of these issues was the query_value() function, which returns the selected record from the database as a value. The number of resulted records must be precisely one, otherwise assertion failure is done in debug mode. In release mode no error is raised at all: when multiple results are available, the first one is returned and in case of zero results, a default constructed object is returned (or even memory garbage, I haven't checked it).

As the ODB Manual states:

If the query executed using query_one() or query_value() returns more than one element, then these functions fail with an assertion. Additionally, query_value() also fails with an assertion if the query returned no elements.

These misbehaviours went unnoticed in release mode, because when multiple results were available, simply the first was returned; and when no results were available, all EQ_* assertions were inside a loop, which was executed 0 times.

In this PR I have addressed these issues and fixed them. In all cases I am confident that the unit tests were incorrect and CodeCompass worked correctly. There is only a single case where I am uncertain (related to function pointers), but I will mark that case for discussion explicitly soon.

I have also modified that the CI shall build CodeCompass in Debug mode for testing in the future, to avoid any such issue like this in the future. (Docker images and tarballs are still built in Release mode of course.)

mcserep added 2 commits March 10, 2021 19:35
… which only resulted in an assertion fail when CodeCompass was compiled in debug mode.
@mcserep mcserep requested review from bruntib and intjftw March 10, 2021 18:52
@mcserep mcserep added Kind: Bug ⚠️ Plugin: C++ Issues related to the parsing and presentation of C++ projects. Target: Test Issues related to testing of core infrastructure or any plugin (please add plugin target tag too!) labels Mar 10, 2021
@mcserep mcserep added this to the Release Flash milestone Mar 10, 2021
Comment on lines 138 to 145
model::CppFunction callee = _db->query_value<model::CppFunction>(
RCppFunction callees = _db->query<model::CppFunction>(
QCppFunction::name == "multiFunction");
EXPECT_GT(callees.size(), 0);
Copy link
Collaborator Author

@mcserep mcserep Mar 10, 2021

Choose a reason for hiding this comment

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

Here the multiFunction is declared 2 times and defined 1 time, so all together 3 records in CppFunction will be found.

Comment on lines -299 to +307
model::CppEnum integer = _db->query_value<model::CppEnum>(
QCppEnum::name == "Integer");
model::CppTypedef integer = _db->query_value<model::CppTypedef>(
QCppTypedef::name == "Integer");
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here Integer was not an enum, but a typedef in the parsed source code.

Comment on lines 452 to 464
_transaction([&, this] {
model::CppEnum enumeration = _db->query_value<model::CppEnum>(
_transaction([&, this]
{
RCppEnum enumerations = _db->query<model::CppEnum>(
QCppEnum::name == "Enumeration");
EXPECT_GT(enumerations.size(), 0);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There are multiple records for Enumeration in the CppEnum table.

Comment on lines -530 to +549
model::CppFunction fieldFunction = _db->query_value<model::CppFunction>(
TEST_F(CppParserTest, Fields)
{
_transaction([&, this] {
model::CppVariable fieldFunction = _db->query_value<model::CppVariable>(
QCppFunction::name == "fieldFunction");
astNodes = _db->query<model::CppAstNode>(
RCppAstNode astNodes = _db->query<model::CppAstNode>(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the case where I was uncertain about my fix. This fieldFunction is a defined like this:

struct Derived : public MyClass
{
  MyClass fieldVariable;
  MyClass (*fieldFunction)(const MyClass&);
  
  // etc...
};

So it is a class member field, as a function pointer. It gets parsed into the CppVariable table, not the CppFunction, but that is correct that way, right @bruntib ? It is a variable, not a function semantically.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I checked the above code, the function pointer is considered a fieldDecl.
image

@intjftw intjftw merged commit 317addc into Ericsson:master Apr 13, 2021
@mcserep mcserep deleted the cppparsertest-fixes branch April 13, 2021 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Kind: Bug ⚠️ Plugin: C++ Issues related to the parsing and presentation of C++ projects. Target: Test Issues related to testing of core infrastructure or any plugin (please add plugin target tag too!)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unit test failure in debug mode

2 participants