False positive rule c:S995 Pointer and reference parameters should be "const" if the corresponding object is not modified

Hello,

I’m currently facing an error with this sample code named sample.c

#include <stdint.h>

typedef enum
{
    LIB_NO_ERROR = 0,
    LIB_MODULE_ID_ERROR = 1,
} LIB_ERR;

typedef enum
{
    MOD1_ID = 0x1,
    MOD2_ID = 0x2,
    MOD3_ID = 0x5,
} Lib_ModuleID;

typedef enum
{
    MOD1_IDX,
    MOD2_IDX,
    MOD3_IDX,
    LIB_NB_MODULES
} Lib_ModuleIDX_e;


LIB_ERR modIdToIdx(uint32_t moduleId, uint32_t * pModuleIdx)
{
    LIB_ERR err = LIB_NO_ERROR;

    switch (moduleId)
    {
    case MOD1_ID:
        *pModuleIdx = MOD1_IDX;
        break;
    case MOD2_ID:
        *pModuleIdx = MOD2_IDX;
        break;
    case MOD3_ID:
        *pModuleIdx = MOD3_IDX;
        break;
    default:
        err = LIB_MODULE_ID_ERROR;
    }

    return err;
}

The error returned by SonarQube is the following:
“Mark “pModuleIdx” as const at every possible pointer level.”
Which is linked to following rule:
“Pointer and reference parameters should be “const” if the corresponding object is not modified”
(c:S995)

When adding sonar.verbose=true in my sonar project properties file, here is what I get for the given sample.c file
12:15:16.918 DEBUG: [pool-5-thread-7] […path…]/sample.c:1 ‘stdint.h’ file not found

Note that I’m cross-compiling for some embbeded toolchain, and the custom stdint.h is located to some DIR location:

  • when adding DIR to sonar.c.includeDirectories, nothing changes
  • when adding DIR to sonar.sources, I get the following log message:
    12:15:13.219 WARN: File ‘DIR\stdint.h’ is ignored. It is not located in module basedir.

Is the false positive triggered by the fact that SonarQube can’t find the custom stdint.h file ? If it is the case, how can I properly tell SonarQube how to find it ? If not, how can I investigate this false positive further ?

Please note that I don’t get this error if I replace uint32_t by unsigned int (which I don’t want to do in the final code)

Thanks in advance

Hello @jandria and welcome to our community!

Is the false positive triggered by the fact that SonarQube can’t find the custom stdint.h file ?

This is most likely the reason for this false positive. And as you probably guessed, ensuring the file can be found should solve it.

Note that I’m cross-compiling for some embbeded toolchain, and the custom stdint.h is located to some DIR location:

What is your toolchain?

We support a specific set of compilers as listed here for the lasted version of SonarQube: https://docs.sonarqube.org/latest/analysis/languages/cfamily/ You may want to check the documentation specific to the version of SonarQube you are using in case it isn’t 9.3. Is your toolchain listed as supported?

when adding DIR to sonar.c.includeDirectories, nothing changes

To clarify, there is no such option in the official analyzer for C/C++/Objective-C.

when adding DIR to sonar.sources […]

This option defines the set of directories containing main source files. In other words, the source files to analyze. This doesn’t change which include search paths are used when analyzing those files.

Make sure that you are using either the SonarSource Build Wrapper or a compilation database. You’ll find the relevant information at https://docs.sonarqube.org/latest/analysis/languages/cfamily/. These tools, when properly used, will ensure the correct include search paths are used to find header files.

I hope this helps.

Hello @marco.b
Thanks for the feedback, and sorry for the late anwser.

For the problem mentioned above I was using SonarSource Build Wrapper with Xtensa xt-xcc toolchain provided by Cadence, which is fully based on GCC.

I was able to fix the first issue by switching to xt-clang, which is an equivalent cross-compiler, but clang-based.

However, I still have an error for the same rule with all the toolchains I’ve tried, including GCC 8.1.0 for Windows provided with mingw-64, with this sample code : the rule c:S995 is reported as violated for foo2 function,

typedef struct S1
{
    int val1;
} S1_t;

typedef struct S2
{
    S1_t *pS1;
    int tab[3];
} S2_t;

void foo1(S1_t *pS1)
{
    pS1->val1 = 8;
    return;
}

void foo2(S2_t *pS2)
{
    foo1(pS2->pS1);
    pS2->tab[2] = 42;
    return;
}

The object pointed by pS2 is modified by foo2, and I can’t compile if I declare void foo2(const S2_t *pS2)

Thanks for your help,
Jérémy

Thank you for your message, Jérémy. I’m glad you were able to fix the initial issue.

To better diagnose and address this second issue (which looks like a bug indeed), I would need a reproducer file from your configuration.

To generate the reproducer file:

  • Search in the analysis log for the full path of the source file for which you want to create a reproducer (for instance, here, the file that generates this issue). You will have to use exactly this name (same case, / or \…)
  • Add the reproducer option to the scanner configuration:
    sonar.cfamily.reproducer= "Full path to the source file"
  • Re-run the scanner to generate a file named sonar-cfamily.reproducer in the project folder.
  • Please share this file. If you think this file contains private information, let us know, we’ll send you a private message that will allow you to send it privately.

Thank you

Hello @marco.b , I ran the scan with the reproducer option, and got this error:

14:48:11.144 ERROR: 
14:48:11.192 ERROR: Please contact SonarSource Support and provide file D:\DSP\DspRefCode\sonar-cfamily.reproducer
14:48:11.261 ERROR: 
14:48:11.284 INFO: [pool-5-thread-1] D:/DSP/DspRefCode/src/audio/modules/DummyModule/DummyModule.c
14:48:11.748 INFO: ------------------------------------------------------------------------
14:48:11.748 INFO: EXECUTION FAILURE
14:48:11.749 INFO: ------------------------------------------------------------------------
14:48:11.750 INFO: Total time: 17.346s
14:48:11.838 INFO: Final Memory: 19M/129M
14:48:11.840 INFO: ------------------------------------------------------------------------
14:48:11.842 ERROR: Error during SonarScanner execution
java.lang.IllegalStateException: sonar.cfamily.reproducer
        at com.sonar.cpp.plugin.CFamilySensor.execute(CFamilySensor.java:211)
        at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:45)
        at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:88)
        at org.sonar.scanner.phases.SensorsExecutor.lambda$execute$1(SensorsExecutor.java:65)
        at org.sonar.scanner.phases.SensorsExecutor.withGlobalStrategy(SensorsExecutor.java:80)
        at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:65)
        at org.sonar.scanner.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:74)
        at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:166)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:300)
        at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:295)
        at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:269)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.scanner.task.ScanTask.execute(ScanTask.java:48)
        at org.sonar.scanner.task.TaskContainer.doAfterStart(TaskContainer.java:82)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.scanner.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:131)
        at org.sonar.batch.bootstrapper.Batch.doExecuteTask(Batch.java:116)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:71)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at com.sun.proxy.$Proxy0.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
        at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
        at org.sonarsource.scanner.cli.Main.main(Main.java:61)

For info when running the scan without reproducer I got this line:

14:33:21.480 INFO: [pool-5-thread-1] D:/DSP/DspRefCode/src/audio/modules/DummyModule/DummyModule.c

and I set this option in my sonar-project.properties:

sonar.cfamily.reproducer=D:/DSP/DspRefCode/src/audio/modules/DummyModule/DummyModule.c

However a sonar-cfamily.reproducer file was generated and I can send it to you privately

Thank you,
Jérémy

Hello @jandria,

Thank you for taking the time to report this issue and share the reproducer.

I had a look at the reproducer you sent privately. The good news is that we have already fixed the false positive you reported. So I would suggest you try a newer version of SonarQube. You could use the latest released version, 9.3, or the latest LTS version, 8.9.7 LTS. Both address this issue.

I hope this helps

Hi, thanks for the feedback. We will consider an SonarQube update whenever possible.

Jérémy

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.