주요 콘텐츠

Detect Functions with Return Immediately Discarded

This example shows how to use Polyspace Query Language (PQL) to check for violation of this rule: If a function takes at least one input, do not immediately discard its returned value.

This topic focuses on application of PQL. For more details about creating semantic defect checkers, see Detect Semantic Issues Using Polyspace Query Language Semantic Classes.

Analyze Rule

To implement the rule in PQL, analyze the components of the rule:

  • Immediately discarded return value — The predicate immediatelyDiscarded of CallSite detects function calls where the return value is immediately discarded.

  • Excluding operators — Operators are considered call sites. Exclude the operator based on name.

  • Number of argument — This information can be found using the numberOfArguments predicate of CallSite.

Implement Rule in PQL

The defect can be defined like this:

defect returnimmediatelydiscarded =
			when
                Cpp.CallSite.is(&cs)
		and cs.immediatelyDiscarded()
		and cs.numberOfArguments(&n)
		and n>0
		and cs.callee(&func)
		and func.name(&name)
        and not name.contains("operator")
                raise "Output of function with no input {name} is explicitly cast to void with number of arguments {n}."
			on cs

Test Defect

To test and verify the defect:

  1. Initialize a test standard in a writable location:

    polyspace-query-language init

  2. In main.pql, insert the defect in a test standard:

    package main
    
    /// Main PQL file defines the catalog of your PQL project.
    /// The catalog is a collection of sections.
    catalog PQL_ImmediatelyDiscarded = {
    #[Description("MySection")]
    	section mysection = {
    #[Description("myRule"), Id(Rule1)]
    		rule myRule = {
    			defect returnimmediatelydiscarded =
    			when
                    Cpp.CallSite.is(&cs)
    		and cs.immediatelyDiscarded()
    		and cs.numberOfArguments(&n)
    		and n>0
    		and cs.callee(&func)
    		and func.name(&name)
            and not name.contains("operator")
                    raise "Output of function with no input {name} is explicitly cast to void with number of arguments {n}."
    			on cs
    		}
    	}
    }
    
    

  3. Package the standard in a pschk file:

    polyspace-query-language package

  4. Create example.cpp in the same folder:

    
    #include <iostream>
    #include <string>
    
    int add(int a, int b) {
        return a + b; // returns a value
    }
    
    
    void log_message(const std::string& m) {
        std::cout << "[LOG] " << m << '\n'; //expect-0-Rule1
    }
    
    struct Accumulator {
        int sum = 0;
        int add(int x) { sum += x; return sum; }     //expect-0-Rule1
        void reset() { sum = 0; }                    // no return
    };
    
    int main() {
        // --- Return values that are used ---
        int s = add(2, 3);                   //expect-0-Rule1
        std::cout << "sum = " << s << '\n';
    
        // --- Calls with discarded return values ---
        add(10, 20);                         //expect-1-Rule1
        
    
        Accumulator acc;
        acc.add(5);                          //expect-1-Rule1
        acc.add(7);                          //expect-1-Rule1
    
        // --- Calls that have no return value (void) ---
        log_message("starting...");          //expect-0-Rule1
        acc.reset();                         //expect-0-Rule1
    
        // Force a temporary object and discard a returning method call
        Accumulator{}.add(42);               //expect-1-Rule1
    
        return 0;
    }
    
    This code explicitly states where a violation of the rule is expected using annotation expect-1-Rule1. Absence of the violation is also annotated using expect-0-Rule1.

  5. Run a test for the defect on the example code:

    polyspace-query-language test example.cpp
    The test verifies the expected violations as well as the expected absence of violations:
    Number of actual defects: 4
    Number of expected annotations: 9 (including 5 expected absence of defects).
    _______________________________________________
      Checking expected defects with actuals...
      -----------------------------------------
    _______________________________________________
      Looking for unexpected defects...
    -------------------------------------------
    _______________________________________________
    Tests passed

See Also

Topics