Welcome to the new Parasoft forums! We hope you will enjoy the site and try out some of the new features, like sharing an idea you may have for one of our products or following a category.

How to create a rule using RuleWizard to identify a comparison operator?

jgl_22
jgl_22 Posts: 6

I am creating a Parasoft rule for C/C++test using RuleWizard that flags whenever a type std::string is used as an argument within certain function calls.

For example, this line should be a violation since it uses the variable 'mytestString' without a call to .c_str()
LOG_TRACE(7, "ParasoftTestProj::main() Some TRACE Message Data: %s", mytestString);

For the specific case when the argument is a ternary operator that uses a std::string as the condition, I want it to be ignored since it actually returns back a different value.
For example, the following line should be OK:
LOG_TRACE(7, "ParasoftTestProj::main() Some TRACE Message Data: %d", mytestString == "test" ? 1 : 0);

The rule that I have so far finds violations for both examples, and I need it to only flag the first example and ignore the second. A copy of my rule is attached.

Under my Declarations branch, the first two branches from that successfully find the violation in the first example but also finds a violation in the second example (which I want it to ignore). I tried to resolve this by adding the third branch below (Context a==b) to identify that if a std::string type is found to be used as a comparison it should be disregarded. However, this branch doesn't seem to be working as I intend it to. Is there a way to modify this branch to get my rule working? Or is there any other workaround that might solve this use case?

Best Answer

  • mstaron
    mstaron Posts: 35
    Answer ✓

    I think the best way to detect such cases is to create a rule that checks the type of the argument and reports when that type is std :: string. Try to use such a rule

Answers

  • jgl_22
    jgl_22 Posts: 6

    This worked, thank you!

  • jgl_22
    jgl_22 Posts: 6

    I had a follow up that I wanted to see if you had any ideas about.

    I wanted the rule to be able to identify a Macros also. In our instance the Macros is defined as
    [pound sign]define LOG_TRACE Log::Trace //where Trace is a function of class Log

    When I use the above Macros, the rule does not work in finding violations in functions named LOG_TRACE. If I change it to use the constexpr specifier as in the following, it does work:
    constexpr auto LOG_TRACE = Log::Trace;

    However, the performance time showed the Macros to be much faster so I need the rule to be able to identify the Macros rather than the specifier. Is there any way that we can edit the rule so that way it is able to treat the Macros as a function to flag violations?

  • mstaron
    mstaron Posts: 35

    Rule Wizard C/C++ rules work on the preprocessed code, so it is not possible to detect use of the macro, but if after macro expansion the function call is in preprocessed code, then it should be detected.
    However, if a macro is a function-like macro and is defined in a file that is not in the testing scope, then violations in lines containing calls of this macro are suppressed by default (violations are not visible). The same seems to be the case when a macro expands to a function name.

    If you have code like this:
    // test.h
    #define LOG_TRACE Log::Trace
    // test.cpp
    #include
    #include "test.h"

    class Log
    {
    public:
    static void Trace(std::string s);
    };

    void use(std::string sp)
    {
    Log::Trace(sp); // reported
    LOG_TRACE(sp); // reported if test.h is in testing scope.
    }
    and test.h is not in the testing scope then violation on LOG_TRACE is not reported.

    If you want to see such violations, then both files should be in testing scope.

  • jgl_22
    jgl_22 Posts: 6

    I see. Is there any way to run the static analysis so that way the header files are within testing scope then? Since I wouldn't be able to integrate the class within the source file.

    If not, might there be a way to get the rule working using C++Text Dictionary Node Properties rather than the C/C++ Dictionary Node Properties? For example using the Preprocessor Directives or IsMacro Textnode Properties that are a part of the C++Text Dictionary?

  • mstaron
    mstaron Posts: 35

    You can try to use a cross rule. It allows to check calls in the C/C++ rule and report on macro identifiers in the C++Text rule.

  • jgl_22
    jgl_22 Posts: 6

    That looks like a viable solution.

    To backtrack to the previous rule though, is there a way to configure my testing scope so that way my header file is also analyzed with the source file?

    From Visual Studio I clicked on the Parasoft tab on top of screen and went to Test Configurations > User-defined > Static Analysis > Example Configuration > Static > Flow Analysis Advanced Settings > Extended Scope of Analysis. Under here there is an option to List additional header files to analyze, and I included the path to the header file I want included. By itself, this did not work, but I am wondering if there is something in addition to this that I can do to broaden the test scope.

    Also, I am using Windows for this.

  • mstaron
    mstaron Posts: 35

    This is not a flow rule, so the flow analysis settings are irrelevant. If you are running test configuration in the GUI, then you need select all files that should be in testing scope. C++test checks by default all code in the resource selected when the Test Configuration is run.

  • jgl_22
    jgl_22 Posts: 6

    Do you know if there would be any issues arising with uploading the cross rule to the DTP? Would I have to upload both rules - the C++Text rule and the main C/C++ rule. Or is uploading just the one rule enough to work?