Skip to content
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

sonar cxx plugin takes around 20 minutes to analyze the code that has templates and boost::optional #1539

Closed
roopshree opened this issue Aug 9, 2018 · 4 comments

Comments

@roopshree
Copy link

We have a code file which the sonar.cxx plugin takes around 20 minutes to analyze.
I have reduced the code to bare minimum to reproduce this issue:

#include <boost/optional.hpp>
#include <cstdint>
#include <iostream>
#include <tuple>

template <typename ParameterType>
struct FOOPARAM {
  const std::string paramName;

  FOOPARAM(std::string &&name) : paramName(std::move(name)) {}
};

template <typename T, typename... Parameters> class FOO final {
public:
  std::string my_command;
  std::tuple<Parameters...> my_parameters;

  FOO(std::string &&commandName, std::tuple<Parameters...> const & parameters)
      : my_command(std::move(commandName)),
        my_parameters(parameters) {}

  ~FOO() = default;
};

template <typename T, typename... TupleArgs>
FOO<T, TupleArgs...> makeObject(std::string &&commandName,
                                TupleArgs const &... tupleArgs) {
  return FOO<T, TupleArgs...>(
      std::move(commandName),
      std::make_tuple(tupleArgs...));
}

struct BAR final {
  boost::optional<uint32_t> optional1Uint32;
  boost::optional<uint32_t> optional2Uint32;
  boost::optional<bool> optionalBool;
  boost::optional<std::string> optional1String;
  boost::optional<std::string> optional2String;
  std::string stringVal1;
  std::string stringVal2;
  uint32_t uint32Val;

  BAR(boost::optional<uint32_t> var1, boost::optional<uint32_t> var2,
      boost::optional<bool> var3, boost::optional<std::string> var4,
      boost::optional<std::string> var5, std::string val6, uint32_t val7,
      std::string val8)
      : optional1Uint32(std::move(var1)), optional2Uint32(std::move(var2)),
        optionalBool(std::move(var3)), optional1String(std::move(var4)),
        optional2String(std::move(var5)), stringVal1(val6), stringVal2(val8),
        uint32Val(val7) {
    //
  }
};

int main() {
  auto obj(makeObject<BAR>("Test", FOOPARAM<boost::optional<uint32_t>>("Key1"),
                           FOOPARAM<boost::optional<uint32_t>>("Key2"),
                           FOOPARAM<boost::optional<bool>>("Key3"),
                           FOOPARAM<boost::optional<std::string>>("Key4"),
                           FOOPARAM<boost::optional<std::string>>("Key5"),
                           FOOPARAM<std::string>("Key6"),
                           FOOPARAM<uint32_t>("Key7"),
                           FOOPARAM<std::string>("Key8")));
  std::cout << "Done";

  return 0;
}

If I reduce the number of boost::optional in the code above or remove the additional indirection in FOOPARAM, then the analysis speeds up. Unfortunately, I cannot do either in the actual code.

sonar-project.properties used:

sonar.projectKey=SAMPLE_TEST
sonar.projectVersion=1.0
sonar.projectName=sample-test

sonar.sources=./scratch_1.cpp
sonar.cxx.coverage.forceZeroCoverage=true
sonar.cxx.coverage.reportPath=./coverage.xml
sonar.cxx.compiler.reportPath=./compiler.out
sonar.cxx.compiler.parser=GCC
sonar.log.level=TRACE
sonar.showProfiling=true

sonar debug logs

@guwirth
Copy link
Collaborator

guwirth commented Aug 9, 2018

Hi @roopshree,

is this with or without sonar.cxx.includeDirectories settings? You can download and play around with
https://github.com/SonarOpenCommunity/sonar-cxx/releases/download/cxx-1.1.0/sslr-cxx-toolkit-1.1.0.jar which parts of your code are slowing down the analysis.

Includes could be a root cause or an enabled cxx check?

Regards

@roopshree
Copy link
Author

roopshree commented Aug 9, 2018

The actual sonar properties that is used with the production code has the includedirectories. I did not bother adding the includedirectories because I was working with a cpp file. Do I still need to include the path to standard header files?

Also, is there a documentation on how to use the toolkit link that you provided?

@guwirth
Copy link
Collaborator

guwirth commented Aug 10, 2018

@roopshree

includedirectories: parsing the files is a two step process. Reading the cpp file, running the preprocessor and than creating an AST with the C++ grammar. Typically such problems comes from adding the boost header files to includedirectories. In this case the parser has to handle thousands of includes.

is there a documentation on how to use the toolkit link that you provided?

Tool is straight forward. Start the tool on your local PC. Copy the sample code into it and press Parse Source Code. On the right side you will get the AST or an error message.

I tried it out. Your are right. Parsing the code is indeed horrible slow (without setting includedirectories).

@guwirth guwirth added bug and removed question labels Aug 10, 2018
@guwirth guwirth added this to the 1.2.1 milestone Nov 14, 2018
@guwirth guwirth modified the milestones: 1.2.1, 1.2.2 Dec 23, 2018
@ivangalkin ivangalkin mentioned this issue Jan 3, 2019
@guwirth guwirth removed this from the 1.2.2 milestone Feb 9, 2019
@guwirth
Copy link
Collaborator

guwirth commented Feb 9, 2019

see #1685

@guwirth guwirth closed this as completed Feb 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants