SonarOpenCommunity / sonar-cxx

SonarQube C++ Community plugin (cxx plugin): This plugin adds C++ support to SonarQube with the focus on integration of existing C++ tools.
GNU Lesser General Public License v3.0
994 stars 364 forks source link

Clang compiler warnings support (like GCC and MSVC) #2325

Open aallrd opened 2 years ago

aallrd commented 2 years ago

Hello,

I am compiling my project with Clang and I would like to feed the compiler warnings from the build log as violations into SonarQube. It exists and works for GCC and MSVC: https://github.com/SonarOpenCommunity/sonar-cxx/wiki/Compilers I read the wiki and the opened issues but I could not find this feature/request documented anywhere for Clang.

Maybe I missed something, are you aware of a solution to feed Clang warnings into SonarQube?

guwirth commented 2 years ago

Hi @aallrd,

please have a look in our Wiki: https://github.com/SonarOpenCommunity/sonar-cxx/wiki/sonar.cxx.clangtidy.reportPaths https://github.com/SonarOpenCommunity/sonar-cxx/wiki/sonar.cxx.clangsa.reportPaths

For the compiler warnings you are right, there is no support yet.

Regards,

aallrd commented 2 years ago

Hey @guwirth,

Thank you for the quick reply. I am indeed already successfully using the clangtidy/clangsa sensors. If the compiler warnings report is not supported for Clang, do you have hints on how to add it to SonarQube? I would be interested in developing this feature since I need it.

guwirth commented 2 years ago

Hi @aallrd,

first of all there was already in the past a longer discussion if "compiler issues" makes sense in SQ. A lot of people have the opinion to fix such issues better in the IDE, "treat warnings as errors" and fail already in the CI/CD (instead of forwarding it to SQ).

In case you like to add it you could use: https://docs.sonarqube.org/latest/analysis/generic-issue/

Other possibility is to extend our built-in sensor:

Regards,

aallrd commented 2 years ago

I agree that -Werror is probably the best way to go to get the problem as close as possible to the developer in the first place.

However this is not possible if you already have thousands of warning in a huge codebase shared by hundreds of developers. From experience, the only thing you can do is publish the information in a central location (Sonar) and gradually tackle these warnings through targeted campaigns, before being able to treat them as errors and prevent regressions.

I'll first check the generic report and the sonar.cxx.other.rules to see if I can get something to work:

If I manage that, I'll see if I can contribute a real built-in sensor from that experience.

Thank you.

guwirth commented 2 years ago

Hi @aallrd,

the sensor is very simple and have to parse the report (warning log) only. It's most likely copy and past from an existing one. More interesting is how to get a list of all existing compiler warnings in clang?

For me also interesting what is there in beside the already existing ClangTidy and Diagnostic warnings?

Regards,

aallrd commented 2 years ago

I'll probably parse this list to create the XML of rules: https://clang.llvm.org/docs/DiagnosticsReference.html

guwirth commented 2 years ago

We have already scripts parsing clang rule files: https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/cxx-sensors/src/tools/generate_clangtidy_resources.cmd

Please have also a look into https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/cxx-sensors/src/main/resources/clangtidy.xml

This file contains already Diagnostic messages. What is missing?

aallrd commented 2 years ago

Indeed, it seems that the Clang warnings are already listed (at least for the ones I checked). They are referenced with a key <key>clang-diagnostic-{warning_name}</key>. So what is missing I guess it a way to parse a compilation log file of warning messages, produce the expected XML output and feed it to the Clang Tidy sensor? I cannot run Clang Tidy on all my codeline, it is just too big.

guwirth commented 2 years ago

Hi @aallrd,

can you provide a compilation LOG file (a snippet)? What is different in the format compared to ClangTidy?

https://clang.llvm.org/extra/clang-tidy/

Clang diagnostics are treated in a similar way as check diagnostics. Clang diagnostics are displayed by clang-tidy and can be filtered out using the -checks= option. However, the -checks= option does not affect compilation arguments, so it cannot turn on Clang warnings which are not already turned on in the build configuration. The -warnings-as-errors= option upgrades any warnings emitted under the -checks= flag to errors (but it does not enable any checks itself).

Clang diagnostics have check names starting with clang-diagnostic-. Diagnostics which have a corresponding warning option, are named clang-diagnostic-, e.g. Clang warning controlled by -Wliteral-conversion will be reported with check name clang-diagnostic-literal-conversion.

Regards,

aallrd commented 2 years ago

Compilation with Clang of module X:

/project/source.cpp:783:16: warning: function 'testFunction' is not needed and will not be emitted [-Wunneeded-internal-declaration]
static int testFunction(int pTree, int pItm, int * pq, int fNext)
             ^
1 warning generated.

Clang Tidy run on module X:

/project/source.cpp:783:16: warning: function 'testFunction' is not needed and will not be emitted [clang-diagnostic-unneeded-internal-declaration]
static int testFunction(int pTree, int pItm, int * pq, int fNext)
               ^

I can get the build compilation log for the whole codeline with Clang (and all the compilation warnings), but I cannot get a Clang Tidy run on all my codeline (too expensive).

guwirth commented 2 years ago

@aallrd thx for the samples. Have to say that I'm not familiar with clang tools...

Some general remarks: Writing a sensor to parse the LOG files is simple but to maintain the rules with every update of LLVM a bigger effort. We also like to avoid to maintain same rules at several places.

In your sample above the only difference is:

See several possibilities to solve this:

  1. Duplicate the rules and write an own clang compiler sensor (like to avoid this: blows up plugin size and maintenance effort).
  2. Write an own clang compiler sensor and reuse the clang-tidy rules. Clang compiler issues would be visualized in the SQ UI as clang-tidy issues.
  3. Extend the existing clang-tidy sensor to also understand clang compiler issues ([-W...]) in the LOG files and map them to clang-tidy rules ([clang-diagnostic-...]). Clang compiler issues would be visualized in the SQ UI as clang-tidy issues.
  4. Split the rulesets (clang-tidy and diagnostics) and have two sensors reading the LOG files (clang compiler/clang-tidy). Would mean that LOG files has to be parsed twice, but unique issue assignment in the SQ UI. Still open how to deal then with [clang-diagnostic-...]? Most likely Clang compiler sensor has to understand than both formats: [-W...] <=> [clang-diagnostic-...].

Any proposals?

aallrd commented 2 years ago

Option 3 is probably the best one. In order to test the current Clang Tidy sensor I simply modified my compilation log file to map the warnings to the expected Clang Tidy format: [-W...] <=> [clang-diagnostic-...]

sed -E 's/\[-W(.*)\]/\[clang-diagnostic-\1\]/g' build.log > warnings.clang-tidy.txt

It was enough to get the warnings reported in the SonarQube UI as clang-tidy issues.

guwirth commented 2 years ago

After thinking again about it, think would be best:

cmorve-te commented 2 weeks ago

Can you tell me how to recreate https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/cxx-sensors/src/main/resources/clangtidy.xml?

https://github.com/SonarOpenCommunity/sonar-cxx/blob/master/cxx-sensors/src/tools/clangtidy_createrules.py#L572 has the instructions. They seem a bit outdated, though, I guess you are supposed to "clangtidy_new.xml.comparable", then let's call it a "clangtidy_diag_new.xml.comparable", and then "utils_createrules.py mergerules" them.

The result is more or less OK. With the llvmorg-19-init tag I have 1,497 warnings, I'm guessing the missing 14 were just removed at in previous llvm versions. But the diff is still giant, with differences in the formatting of the descriptions. Maybe it's the pandoc version? I'm using pandoc 3.1.3 from Ubuntu 24.04.

guwirth commented 2 weeks ago

Hi @cmorve-te,

some generell hints: https://github.com/SonarOpenCommunity/sonar-cxx/issues/2739#issuecomment-2337394587

After extracting the rules with a script it’s still a lot of manual work…

Regards,