Get Started with Polyspace Query Language
The Polyspace Query Language (PQL) is a lightweight declarative language that enables you to create your own coding standards and defects. This topic shows how you can create a simple coding standard that consists of existing Bug Finder checkers as well as a new user-defined defect.
Initialize New User-Defined Coding Standard
A user-defined coding standard is a collection of existing Bug Finder checkers and new
user-defined defects. The coding standard is divided into sections, each with one or more
checkers or defects. In this topic, you create a coding standard named
myStandard that contains these checkers:
First initialize the standard:
Create a folder named
myStandardwhere everything related to this coding standard is stored.In the folder, open a command-line prompt and enter:
This command creates the infrastructure necessary to create the coding standard. If the command is successful, it creates a file namedpolyspace-query-language init
main.pql. Use this file to define the coding standard in subsequent steps.
Create Sections
Sections in the coding standard organize the rules and makes reviewing results easier. In this example, put rules from different external coding standards in their own sections:
MISRA— MISRA C++:2023 rules.CERT— CERT C++ rules.DEFECT— Polyspace® Bug Finder™ defects and other user-defined defects.
For modularity and extensibility, implement each section in their own folders. Create
the folders MISRA, CERT, and DEFECT
as child folder of myStandard. For example, at the command-line
enter
mkdir MISRA CERT DEFECT
pql file that defines the sections and descriptions for each section
using this syntax:
myStandard\MISRA\MISRA.pqlpackage MISRA #[Description("MISRA Rules")] section MISRA = { //... }myStandard\CERT\CERT.pqlpackage CERT #[Description("CERT Rules")] section CERT = { //... }myStandard\DEFECT\DEFECT.pqlpackage DEFECT #[Description("Defects")] section DEFECT = { //... }
The string you specify in #[Description] is the label
displayed in the user interface when you configure the standard or review the results for
the standard.
Add Existing Checkers
After defining the sections of the coding standard, add rules by declaring
rule objects. A rule object can be mapped to
existing checkers. Add a new rule ruleA to the MISRA
section that is mapped to MISRA C++:2023 Rule
0.1.1 and include a
description.
package MISRA
#[Description("MISRA Rules")]
section MISRA = {
#[Description("A function shall not contain unreachable statements "), Id(M23_001)]
rule ruleA = { //Adding new rule ruleA
std.misra_cpp_2023.R0_1_1
}
}#[Description] adds a short
description for the rule that is displayed in the user interfaces. The value you specify in
Id is an identifier for the rule. Polyspace uses this identifier when showing the rule and its results in the user
interface. The identifier std.misra_cpp_2023.R0_1_1 is the PQL name for
the MISRA C++:2023 Rule
0.1.1. Find the PQL name of a checker in the Check
Information section of its reference page.Following this syntax, add rule objects to the other sections:
myStandard\CERT\CERT.pqlpackage CERT #[Description("CERT Rules")] section CERT = { #[Description("Detect and handle memory allocation errors"), Id(MEM52)] rule ruleB = { //Adding new rule ruleB std.cert_cpp.MEM52_CPP } }myStandard\DEFECT\DEFECT.pqlpackage DEFECT #[Description("Defects")] section DEFECT = { #[Description("Move Operation uses copy"), Id(MOVE_USES_COPY)] rule ruleC = { //Adding new rule ruleC std.defects.MOVE_OPERATION_USES_COPY } }
Add User-Defined Defect
In a user-defined coding standard, you can include defects that are not checked for by
existing Bug Finder checkers. For example, in the section Defect, add a
user-defined defect to myStandard that checks for integer variable names
that does not begin with a specific prefix:
Open the file
myStandard\DEFECT\DEFECT.pql.In the section
DEFECT, add a new rulenameNotDescriptive:package DEFECT #[Description("Defects")] section DEFECT = { #[Description("Move Operation uses copy"), Id(MOVE_USES_COPY)] rule ruleC = { //Adding new rule ruleC std.defects.MOVE_OPERATION_USES_COPY }, nameNotDescriptive }In the folder
myStandard\DEFECT\, create a new file namednameNotDescriptive.pqland add the definition of the rulenameNotDescriptive. This rule consists of the user-defined defectinappropriateIntName:package DEFECT #[Description ("Do not use single letter as a name"), Id(NameTooSimple)] rule nameNotDescriptive = { defect inappropriateIntName = when Cpp.Variable.is(&var) and var.name(&varName) and var.type(&varType) and varType.isIntegral() and getPrefix(varType, &prefix) and not varName.startsWith(prefix) raise "Expected prefix: \"{prefix}\"" on var } predicate getPrefix(Cpp.Type.Type vartype, Lang.String &prefix) { return ((vartype.isSigned() and Lang.createString("s", &str)) or (vartype.isUnsigned() and Lang.createString("u", &str))) and vartype.sizeInBits(&nBits) and Lang.toString(nBits, &sizestr) and Lang.catString(str, sizestr,&prefix) }
Package User Defined Coding Standard
To package the sections and the user-defined defects in a user-defined coding standard:
Navigate to the folder
myStandard. You package the user-defined coding standard in the folder that containsmain.pql.In the file
main.pql, include the sections you created in the coding standard:package main catalog myStandard = { MISRA.MISRA, CERT.CERT, DEFECT.DEFECT }At the command-line enter:
The filepolyspace-query-language package
myStandard.pschkis created.
Test User-Defined Coding Standard
After creating the coding standard, test the standard to verify that it reports the
violations you expect. This C++ code contains several violations for the standard
myStandard. The expected violations are indicated in the code using
//expect... comments. Copy this content in the file
src.cpp.
class largeInteger {
public:
largeInteger (int d1, int d2, int d3): //expect-3-NameTooSimple
lastFiveDigits(d1), nextFiveDigits(d2), firstFiveDigits(d3) {}
largeInteger &operator= (const largeInteger &other) {
if(&other != this) {
firstFiveDigits = other.firstFiveDigits;
nextFiveDigits = other.nextFiveDigits;
lastFiveDigits = other.lastFiveDigits;
}
return *this;
}
void printIntegerValue();
private:
int firstFiveDigits;
int nextFiveDigits;
int lastFiveDigits;
};
bool compareValues(largeInteger, largeInteger);
void func() {
largeInteger largeUnit{10000, 0, 0}; //Compliant
largeInteger smallUnit{1, 0, 0}; //Compliant
largeInteger tinyUnit{0, 1, 0}; //expect-1-M23_001
if(compareValues(largeUnit, smallUnit)) {
//Perform some action
}
}myStandard, at the
command line,
enter:polyspace-query-language test src.cpp
See Also
Topics
- General Polyspace Query Language Syntax
- Polyspace Query Language Syntax for Creating User-Defined Coding Standard
- Best Practice for Defining User-Defined Defect Checkers
- Polyspace Query Language Syntax for Creating User-Defined Coding Standard
- Polyspace Query Language Syntax for Creating User-Defined Defects