Main Content

Unsupported syntax used with test authoring API

Higher order calls in test or test suite configuration, and so on

Since R2023b

Description

This defect occurs when you have issues in your test or suite configuration that might affect the precision of a Polyspace® analysis. Currently, the defect checker flags calls via function pointers in your test or suite configuration.

This checker is enabled if you specify the value pstunit for the option Libraries used (-library) or find defects in a test file from the Polyspace Platform (Polyspace Test) user interface. For more information, see Check for Bugs and Run-Time Errors in C/C++ Tests and Functions Under Test (Polyspace Test).

Risk

Higher order calls reduce the precision of a Polyspace analysis. The calls might also indicate some programming error.

Fix

Refactor your code so that calls via function pointers are not needed during test or suite configuration.

Examples

expand all

In this example, the function pointer funcptr is incorrectly used to configure a suite of tests.

  • Header with type definitions (named example.h):

    #include <limits.h>
    extern unsigned gSum;
    
    typedef enum {
        NOT_SATURATED = 0,
        SATURATED = 1
    } SUM_STATUS;
    
    SUM_STATUS globalSum(unsigned x);
  • Source:

    #include "example.h"
    
    unsigned gSum;
    
    SUM_STATUS globalSum(unsigned x) {
        if (x > UINT_MAX - gSum) {
            gSum = UINT_MAX;
            return SATURATED;
        }
        gSum += x;
        return NOT_SATURATED;
    }
  • Tests:

    #include <pstunit.h>
    #include "example.h"
    
    //Test utilities
    void setgSum (void) {
        gSum = 0;
    }
    
    PST_SUITE_CONFIG(gSumTests) {
        void (*funcptr)(void) = &setgSum;
        (*funcptr)();       
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseOne){}
    PST_TEST_BODY(gSumTests, TestCaseOne) {
        unsigned test_data = UINT_MAX/2 + 1;
        unsigned expected_gSum = UINT_MAX/2 + 1;
        int  i;
        
         for(i = 1; i<= 1; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in nonsaturating sum.");
          
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseTwo){}
    PST_TEST_BODY(gSumTests, TestCaseTwo) {
        unsigned test_data = UINT_MAX/2 + 1;
        unsigned expected_gSum = UINT_MAX;
        int i;
        
        for(i = 1; i<= 2; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is just above limit.");
    
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseThree){}
    PST_TEST_BODY(gSumTests, TestCaseThree) {
        unsigned test_data = UINT_MAX/2 + 1;
        unsigned expected_gSum = UINT_MAX;
        int i;
            
        for(i = 1; i<= 3; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is well above limit.");
    }
    
    
    PST_REGFCN(myRegFcn) {
        PST_ADD_TEST(gSumTests, TestCaseOne);
        PST_ADD_TEST(gSumTests, TestCaseTwo);
        PST_ADD_TEST(gSumTests, TestCaseThree);
    }
    
    #ifndef PSTEST_BUILD
    int main(int argc, char *argv[]) {
        PST_REGFCN_CALL(myRegFcn);
        return PST_MAIN(argc, argv);
    }
    #endif
    

Correction — Avoid Calls Via Function Pointers

Refactor your code so that calls via function pointers are not needed during test or suite configuration. The corrected test file is shown below.

  • Header with type definitions (named example.h):

    #include <limits.h>
    extern unsigned gSum;
    
    typedef enum {
        NOT_SATURATED = 0,
        SATURATED = 1
    } SUM_STATUS;
    
    SUM_STATUS globalSum(unsigned x);
  • Source:

    #include "example.h"
    
    unsigned gSum;
    
    SUM_STATUS globalSum(unsigned x) {
        if (x > UINT_MAX - gSum) {
            gSum = UINT_MAX;
            return SATURATED;
        }
        gSum += x;
        return NOT_SATURATED;
    }
  • Tests:

    #include <pstunit.h>
    #include "example.h"
    
    //Test utilities
    void setgSum (void) {
        gSum = 0;
    }
    
    PST_SUITE_CONFIG(gSumTests) {
        PST_SUITE_TEST_SETUP(setgSum);
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseOne){}
    PST_TEST_BODY(gSumTests, TestCaseOne) {
        unsigned test_data = UINT_MAX/2 + 1;
        unsigned expected_gSum = UINT_MAX/2 + 1;
        int  i;
        
         for(i = 1; i<= 1; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in nonsaturating sum.");
          
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseTwo){}
    PST_TEST_BODY(gSumTests, TestCaseTwo) {
        unsigned test_data = UINT_MAX/2 + 1;
        unsigned expected_gSum = UINT_MAX;
        int i;
        
        for(i = 1; i<= 2; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is just above limit.");
    
    }
    
    PST_TEST_CONFIG(gSumTests, TestCaseThree){}
    PST_TEST_BODY(gSumTests, TestCaseThree) {
        unsigned test_data = UINT_MAX/2 + 1;
        unsigned expected_gSum = UINT_MAX;
        int i;
            
        for(i = 1; i<= 3; i++)    
                globalSum(test_data);
        
        PST_VERIFY_EQ_INT_MSG(gSum, expected_gSum, "Issue in sum that is well above limit.");
    }
    
    
    PST_REGFCN(myRegFcn) {
        PST_ADD_TEST(gSumTests, TestCaseOne);
        PST_ADD_TEST(gSumTests, TestCaseTwo);
        PST_ADD_TEST(gSumTests, TestCaseThree);
    }
    
    #ifndef PSTEST_BUILD
    int main(int argc, char *argv[]) {
        PST_REGFCN_CALL(myRegFcn);
        return PST_MAIN(argc, argv);
    }
    #endif
    

Result Information

Group: Libraries Misuse
Language: C | C++
Default: Off
Command-Line Syntax: PSTUNIT_UNSUPPORTED_SYNTAX
Impact: Medium

Version History

Introduced in R2023b