Synopsys logo

Coverity® 2020.12 CodeXM

C/C++ Library Reference

Introduction

Specifying the Target Language

Class Definitions

‘enum’ Kinds

‘globalset’ Sets

Code Patterns

Functions

Hide/show Contents

Coverity® 2020.12 CodeXM

C/C++ Library Reference

Introduction

CodeXM is a domain-specific language that allows you to create customized code checkers for Coverity. CodeXM checkers analyze source code for specific coding patterns, and report these issues with messages that you provide. Like other Coverity checkers, the issues are displayed in Coverity Connect. They can be archived with the cov-commit-defect feature.

The CodeXM C/C++ library provides access to C and C++ coding constructs.

When you write your own patterns, you can employ library patterns to specify new conditions: either by narrowing down a general pattern to a more precise variation, or by combining simple patterns into a more complex composite.

This document provides information about the patterns and functions provided by the C/C++ library. To learn how to get started with CodeXM, please see Learning to Write CodeXM Checkers.

Typographic Conventions

Describing CodeXM is a bit different from describing other languages. Most programming books talk about one language only. To describe CodeXM, we have to talk about CodeXM code itself, and the code of the language it is inspecting—the target language.

This reference shows all code in monospace type.

CodeXM code appears in shades of green.

Target code (whatever the language) appears in shades of orange.

Reminder: By default, many browsers do not print out background colors.

Nullable Types

The type of certain pattern properties is said to be nullable. This means that the property might return a value, or it might not. If it does not, its value matches the CodeXM keyword null. In the CodeXM documents, a nullable type is indicated by the name of the type the property might return, followed by a question mark; for example, int?.

In checker code, a nullable type requires some special handling in order to avoid the error of referencing the null. The Handling Null Values section of Learning to Write CodeXM Checkers describes how to do this.

Specifying the Target Language

In your CodeXM source, begin with an include declaration that names the library target language: include `C/C++`.

Specifying the target language makes the library’s special patterns and functions available within this CodeXM file. These patterns and functions are the subject of this reference.

The language specification also causes the checkers defined in your CodeXM file to be applied only to the target source code in your code base.

The CUDA Extension

As of Coverity 2020.12, the C/C++ library provides support for that has been written for the CUDA® parallel computing platform. This support includes additional property fields for the functionSymbol, globalVariableSymbol, localVariableSymbol, and variableSymbol patterns. It also includes a new pattern, kernelCall, which matches calls to launch CUDA kernels.

To use kernelCall patterns in your CodeXM program, you need to replace the declaration that includes `C/C++` with an include of `CUDA`; for example: include `CUDA`.

If you don’t include the library named `CUDA`, your program can still use the CUDA-specific property fields, but it won’t recognize the kernelCall pattern.

Class Definitions

Class definitions match class entities in the abstract representation of the target code, and provide properties that describe the classes that the library supports.

astnode (class)

Every target-code object that Coverity inspects is a node in an abstract syntax tree. For a brief overview of how Coverity uses these syntax trees, see How Does Coverity Analysis Work? in the Syntax Reference.

Properties

Every astnode has the following properties:

Name Type Description
location sourceloc The location of this code construct in the source files
children list<astnode> A list of child nodes that are sub-parts of this code construct
parent astnode? This node’s parent node, if there is one; null if there is no parent
macrosExpandedFrom list<macroinfo> If the code is produced by macro expansion, this list contains the macros that generated that expansion. Otherwise, this list is empty.
implicit bool Indicates whether the node is the result of compiler intervention, as opposed to being explicitly stated in the source code. For example, if ( x ) in the source code is interpreted as if ( x != 0 ) by the compiler. The not-equals binary operator and the literal constant zero are implicit.

The astnode elements are further classified as statement, expression, initializer and ctorinit (constructor initializer), and declaration elements (declaration elements declare symbols). Certain kinds of elements have their own set of properties in addition to the astnode properties shown here.

classDefinition (class)

Describes a class (C++), struct, or union.

Note: If a type is never used in a project (a code base), its definition might be elided from analysis.

Properties

classDefinition produces a record that contains the following properties:

Name Type Description
declaredType classType The associated classType record for this definition
memberFunctionList list<functionSymbol> A list of member functions in this class
staticFieldList list<globalVariableSymbol> A list of fields declared as static
fieldList list<fieldSymbol> A list of fields that are not static
staticMemberFunctionList list<functionSymbol> A list of the static member functions in this class
parentList list<classParent> A list of parent classes
location sourceloc The source-code location of the class definition
byteSize int The byte size of a class instance
instantiatedFrom classType? The class from which this class is instantiated; null if the class is not an instance
specializationOf classType? The class of which this class is a specialization; null if the class is not a specialization
isFinal bool true if the class is marked as final
isPOD bool true if the class is marked as POD (Plain Old Data)
isStandardLayout bool true if the class is a standard layout
isTriviallyDefaultConstructible bool true if the class is trivially default-constructible
isTriviallyDestructible bool true if the class is trivially destructible
findBaseClass function<testType> A function that invokes a callback function, which can be used as a predicate to find a particular base class—in other words, to test whether the class is a parent of the current class. See the section, “The Base Class Properties”, below.
findMatchingBaseClass function<testType> A function that invokes a pattern, which can be used as a predicate to find a particular base class—in other words, to test whether the class is a parent of the current class. See the section “The Base Class Properties”, below.

Example

Given the following source-code snippet:

C/C++ code follows
struct T {
static char c;
int member;
};

... the pattern classDefinition matches the definition of struct T:

CXM code follows
for d in globalset allClasses { where d matches classDefinition as c : // ... And so on };

The Base Class Properties

The function provided by the findBaseClass property has this form:

CXM code follows
function <testType> ( callback: function( base: typeof( classType ).producedType ) -> testType? );

The function provided by the findMatchingBaseClass property has this form:

CXM code follows
function <testType> ( pattern( typeof( classType ).matchedType ) -> testType ) -> testType? ;

The findBaseClass call detects whether a base class is accepted by the callback function. If the callback returns a non-null value, then findBaseClass returns that value (which matches NonNull). If the callback does not return such a non-null value on any base class, findBaseClass returns null.

The findMatchingBaseClass call uses a pattern rather than a callback function, but it returns either a matching value or null, just as findBaseClass does.

Because both these function calls accomplish the same thing, for the most part which one you choose to use is up to you. The pattern form can be easier, and less lengthy, to code (see the examples that follow); on the other hand, a callback function can encode tests that a pattern cannot.

The following “Examples” section shows checkers that use these properties.

Examples of Using Base Class Properties

This first example uses findBaseClass. If findBaseClass can locate a class whose identifier (base.identifier) is "A", it returns the object for that class. Otherwise, the return value is null.

CXM code follows
checker { name = "DERIVES_FROM_A_findBaseClass"; reports = for c in globalset allClasses where c.findBaseClass( function ( base: typeof( classType ).producedType ) -> base.identifier == "A" ? base : null ) matches NonNull as baseA : { events = [ { tag = "base"; description = baseA + " is here"; location = baseA.location; }, { tag = "child"; description = "Class " + c.declaredType + " derives from A"; location = c.location; } ]; }; };

The second example uses findMatchingBaseClass:

CXM code follows
checker { name = "DERIVES_FROM_A_findMatchingBaseClass"; reports = for c in globalset allClasses where c.findMatchingBaseClass( classType { .identifier == "A"} ) matches NonNull as baseA : { events = [ { tag = "base"; description = baseA + " is here"; location = baseA.location; }, { tag = "child"; description = "Class " + c.declaredType + " derives from A"; location = c.location; } ]; }; };

See Also

getClassDefinition

classParent (class)

Describes the parent of a given C++ class.

Properties

classParent produces a record that contains the following properties:

Name Type Description
isVirtual bool true if this is a virtual parent
parent classDefinition The definition for the parent class

Example

A class definition (that is, classDefinition) includes a list of its parent classes via the .parentList field.

enumDefinition (class)

Describes the definition of an enum.

Properties

enumDefinition produces a record that contains the following properties:

Name Type Description
declaredType enumType The type name of this enum
enumeratorList list<enumerators> A list of the literal values this type enumerates
underlyingType type The underlying type of the enumerators
hasExplicitEnumBase bool true if the underlying type is explicitly declared
isScoped bool true if the enum has a class scope
location sourceloc The source-code location of the enum definition

Example

For the following code snippet, enumDefinition matches the definition of enum E:

C/C++ code follows
enum E { A1, A2 };

‘enum’ Kinds

These are enumerations that are used by the language library, and that are available to your own CodeXM code.

assignKind (enum)

Specifies whether an assignment is simple (assignment only) or compound (incorporating an additional operation such as plus, +, or minus, -).

Details

The following values are defined:

Name Description
`simple` A simple assignment; for example, a = b
`compound` A compound assignment; for example, a += b

See Also

assignmentOperator, assignmentOperatorCompound, assignmentOperatorSimple

castKind (enum)

Represents the various kinds of casts that C and C++ support.

Details

The following values are defined:

Name Description
`explicit` An explicit cast; for example, (int) a
`implicit` An implicit cast
`static` A C++ static cast
`dynamic` A C++ dynamic cast
`reinterpret` A C++ reinterpret cast
`const` A C++ constant cast

See Also

castOperator, castOperatorExplicit, castOperatorImplicit, castOperatorStaticCast, castOperatorDynamicCast, castOperatorReinterpretCast, castOperatorConstCast

deducedTypeKind (enum)

Enumerates types that are deduced by the compiler (C++ only).

Properties

deducedTypeKind produces a record that contains the following properties:

Name Description
`auto` A type declared using the keyword auto.
`decltype` A type declared using the keyword decltype
`gnu_auto` A type declared using GNU auto.

See Also

deducedType

floatKind (enum)

Represents the kinds of floating-point types known to C and C++.

Details

The following values are defined:

Name Description
`float` A single-precision floating-point number
`double` A double-precision floating-point number
`long double` A long double-precision floating-point number

See Also

floatType

floatSuffix (enum)

Indicates the suffix used to specify the precision of a floating-point literal.

Details

The following values are defined:

`f` Indicates a suffix of f or F, which says to treat the literal value in calculations as a single-precision (float) floating-point value.
`l` Indicates a suffix of l or L, which says to treat the literal value in calculations as a long floating-point value.

The precision of single or long floating-point values depends on the target implementation.

See Also

floatLiteral

forLoopKind (enum)

Represents either simple or range for loops.

Details

A simple for loop is of the form:

C/C++ code follows
for (int i; i < 10; i++) {
// ...
}

A range for loop is of the form:

C++ code follows
foreach (int element : fibNumbers) {
// ...
};

The following values are defined:

Name Description
`range` (C++) A for loop that uses the range expression introduced in C++11
`simple` A simple C or C++ for loop

See Also

forLoop, forLoopRange, forLoopSimple

intKind (enum)

Represents the integer types known to C and C++.

Details

The following values are defined:

Name Description
`bool` A Boolean value
`char` A character
`int` A regular integer
`long` A long integer
`long long` A long long integer
`short` A short integer

Specific bit lengths for integer values depend on the target implementation.

See Also

intLiteral, intType

nullKind (enum)

Enumerates the possible values for a literal null pointer value.

Details

The following values are defined:

Name Description
`0` Zero
`NULL` The value NULL
`nullptr` The value nullptr (C++ only)

See Also

nullPointerLiteral

qualifierEnum (enum)

Specifies one of the type qualifiers available to C or C++ code.

Details

The following values are defined:

Name Description
`_Atomic` The type is qualified as _Atomic (C++ only, from C++11)
`const` The type is qualified as const (both C and C++)
`restrict` The type is qualified as restrict (C only, from C99)
`volatile` The type is qualified as volatile (both C and C++)

See Also

functionSymbol, typeQualifier

sizeofKind (enum)

Specifies whether the operand passed to sizeof() is an expression or a type.

Details

Name Description
`sizeofExpr` The operand is an expression.
`sizeofType` The operand is a type.

See Also

sizeofOperator

stringLiteralEncoding (enum)

Describes which character encoding is used by a string literal.

Details

The following values are defined:

Name Description
`char` Single-bite characters
`wchar` Wide character format
`utf16` Unicode UTF-16 format, variable length with either 2 or 4 bytes per character
`utf32` Unicode UTF-32 format, 4 bytes per character

See Also

stringLiteral

variableDeclarationKind (enum)

Describes how a variable has been declared.

Details

The following values are defined:

Name Description
`for` The variable is declared within the condition of a for loop.
`global` The variable is declared globally.
`if` The variable is declared within the condition of an if statement.
`simple` The variable is declared locally.
`switch` The variable is declared within the condition of a switch statement.
`while` The variable is declared within the condition of a while loop.

See Also

variableDeclaration

variableScopeEnum (enum)

Represents the scope of a symbol.

Details

The following values are defined:

Name Description
`global` The variable scope is global.
`local` The variable scope is local.

See Also

variableReference, variableSymbol

‘globalset’ Sets

The sets described in this section can help narrow the search of your checker. Typically they are used in for loop constructions such as the following:

CXM code follows
for code in globalset allFunctionCode where code matches // ... further criteria

allClasses (globalset)

Includes the definitions of all struct types, classes, and unions in the current code.

allEnums (globalset)

Includes the definition of all enum types in the current code.

allFunctionAndGlobalVariableCode (globalset)

Matches all the Abstract Syntax Tree (AST) nodes in all the functions and global variable initializers of the current C/C++ code.

allFunctionAndGlobalVariableDefinitions (globalset)

Matches all function definitions and global variable definitions in the current code.

allFunctionCode (globalset)

Matches all the Abstract Syntax Tree (AST) nodes in all the functions of the current C/C++ code.

allFunctionDefinitions (globalset)

Matches all function definitions in the current code.

allGlobalVariableDefinitions (globalset)

Matches all definitions of global variables in the current code.

Code Patterns

These patterns, organized by category, match the constructs that might be found in the target source code.

Statements

Patterns in this section belong to the statement class. They match executable statements in the target code.

asmStatement

Matches asm statements (C++ only) and their associated assembly source.

Properties

asmStatement produces a record that contains the following properties:

Name Type Description
sourceString expression The assembly source code contained within the asm statement
gccOperands list<record>? Additional GNU Compiler Collection operands, such as infile and outfile. If the compiler is not GCC-based, this property is null.
kind enum (see below) Specifies the development framework.

The kind property can be one of the following:

Inherits properties from:

astnode

Example

The asmStatement pattern matches an asm statement such as the following:

C++ code follows
asm (
"movl %1, %%eax;"
"movl %%eax, %0;"
:"=r"(y) // y is output operand
:"r"(x) // x is input operand
:"%eax" // %eax is clobbered register
z);

In this example, the .sourceString contains the entire assembly string "mov1 %1, %%eax; movl %%eax, %0" (which will have been string-glued by the compiler). Since this example illustrates a GCC-based asm statement, the .gccOperands list contains y and x, and .kind is set to `ADK_STANDARD`.

blockStatement (pattern)

Matches a sequence of statements enclosed by curly braces.

Details

This pattern only matches nodes of type statement.

Properties

blockStatement produces a record that contains the following properties:

Name Type Description
containedStatements list<statement> An ordered list of the statements that the block contains

Inherits properties from:

astnode

Example

For the following blockStatement, .containedStatements contains only a simpleStatement—specifically, an assignmentOperator, x = 1;:

C/C++ code follows
{
x = 1;
}

The following code shows a blockStatement whose .containedStatements contains only an empty list:

C/C++ code follows
{
}

The following CodeXM pattern matches blocks that contain only an empty statement (for example, { ; }):

CXM code follows
pattern emptyBlockStatement { blockStatement as bstmt where bstmt.containedStatements.length == 1 && bstmt.containedStatements matches emptyStatement };

breakStatement (pattern)

Matches break statements.

Properties

breakStatement produces a record that contains the following properties:

Name Type Description
controlStatement statement The flow-of-control statement within which the break statement occurs, such as for, while, or switch

Inherits properties from:

astnode

Example

Consider this bit of C or C++ code:

C/C++ code follows
while ( getMore() ) {
if ( someCondition() )
break;
};

A breakStatement pattern matches the break statement in the preceding code fragment. The pattern’s .controlStatement property references the while loop itself.

To identify break statements specifically within switch statements, use the following pattern:

CXM code follows
pattern breakInSwitch { breakStatement { .controlStatement == switchStatement } };

caseStatement (pattern)

Matches individual case statements within a switch. Does not match the statement in the default clause: See the defaultStatement pattern.

Properties

caseStatement produces a record that contains the following properties:

Name Type Description
valueExpression expression The value associated with this case

Inherits properties from:

astnode

Example

Given the same example from switchStatement:

C/C++ code follows
switch( i ) {
case 1: return "one";
case 2: return "two";
case 3: return "three";
default: return "unknown";
};

... we can use caseStatement to match the three case labels but exclude the default statement. The valueExpression is the associated value of the case label.

A custom pattern, matchCaseByValueExpression, that matches instances of case 1: looks like this:

CXM code follows
pattern matchCaseByValueExpression { caseStatement { .valueExpression == intLiteral { .valueInt == 1 } } };

continueStatement (pattern)

Matches continue statements.

Properties

continueStatement produces a record that contains the following properties:

Name Type Description
controlStatement statement The loop statement for which the continue statement occurs.

Inherits properties from:

astnode

Example

A continueStatement pattern matches the continue statement in the following example (.controlStatement is the outer for loop):

C/C++ code follows
for ( int count = 0; count < 10; count++ ) {
if ( count == 5 ) {
continue; // continueStatement matches this
}
};

To detect all continue statements, you can use the following pattern:

CXM code follows
for c in codes { where c matches continueStatement // ... };

defaultStatement (pattern)

Matches the default statement in a switch. See also caseStatement.

Properties

This pattern does not expose any new properties.

Inherits properties from:

astnode

Example

Using the same source code as the switchStatement pattern, defaultStatement would match the default case.

The following pattern identifies switch statements that do have default cases:

CXM code follows
// Switch with default statement pattern switchWithDefault { switchStatement as stms where exists stm in stms.caseList where stm matches defaultStatement };

doWhileLoop (pattern)

Matches do ... while loops.

Details

This pattern only matches nodes of type statement.

Properties

doWhileLoop produces a record that contains the following properties:

Name Type Description
conditionExpression expression The condition that causes the loop to terminate
bodyStatement statement The statement that the loop repeatedly executes. Frequently this is a blockStatement.

Inherits properties from:

astnode

Example

The following C/C++ fragment matches doWhileLoop:

C/C++ code follows
do {
DoSomethingWith( cachedResult );
} while ( cachedResult = SomeFunction() );

The doWhileLoop pattern sets the following properties:

A special case of the do ... while loop is the non-looping do ... while. This can be used for the following reasons:

The following pattern code detects a do ... while loop whose condition is always false:

CXM code follows
// Some idioms to say "false" in C and C++ pattern alwaysFalseConstant = | booleanLiteral {.isTrue == false} | intLiteral {.valueInt == 0} | binaryOperator { .lhsExpression == intLiteral{.valueInt != 0}; .operator == `==`; .rhsExpression == intLiteral{.valueInt == 0} } | binaryOperator { .lhsExpression == intLiteral{.valueInt == 0}; .operator == `==`; .rhsExpression == intLiteral.valueInt != 0} }; /* Use of the do-while(0) idiom (a non-loop) has many uses, but sometimes requires added scrutiny */ pattern doWhileNonLoop { doWhileLoop { .conditionExpression == alwaysFalseConstant } };

emptyStatement (pattern)

Matches empty statements.

An empty statement can be a line with no executable code that is terminated by a semicolon; non-executable code enclosed by curly braces; or an implied branch of an if statement.

See also blockStatement.

Properties

emptyStatement produces a record that contains the following properties:

Name Type Description
isImplicit bool Indicates whether the empty statement is implicit or not.

Inherits properties from:

astnode

Example

Within a function, a semicolon without any code preceding it parses as an emptyStatement:

C/C++ code follows
/* No code here */ ; // Matched by emptyStatement.

An emptyStatement can be inside a blockStatement, matched by blockStatement { .containedStatements == emptyStatement }:

C/C++ code follows
{
; // Matched
}

Caveat: The following code does not match emptyStatement. Instead, this is a blockStatement where the list of .containedStatements is empty:

C/C++ code follows
{
// Not matched
}

A for loop with an empty body can be matched by forLoop { .bodyStatement == emptyStatement }:

C/C++ code follows
for ( i = 0; i < max; i++ ) ; // Matched by emptyStatement

The following pattern matches any empty statement:

CXM code follows
for c in mycodes { where c matches emptyStatement };

To match an empty statement located inside a for loop, use a pattern such as the following:

CXM code follows
for c in codes { where c matches forLoop { .bodyStatement == emptyStatement } };

To match any implicit empty statement:

CXM code follows
for c in codes { where c matches emptyStatement { .isImplicit == true } };

forLoop (pattern)

Matches both kinds of for loop recognized by C++. (C recognizes only the simple variant.) To match only specific kinds of for loop, or to gain access to such a loop’s properties, see forLoopSimple and forLoopRange.

Properties

forLoop produces a record that contains the following properties:

Name Type Description
kind enum forLoopKind The kind of loop; this equals either `simple` or `range`; see forLoopKind

Inherits properties from:

astnode

Example

The following C code:

C/C++ code follows
for ( int i = 0; i < 10; i++ ) {
doSomething( i );
};

... matches the following pattern:

CXM code follows
forLoop { .kind == `simple` };

Similarly, the following C++ code:

C++ code follows
for ( int x : intArray ) {
doSomeOtherThing( x );
};

... matches the following pattern:

CXM code follows
forLoop { .kind == `range` };

Note: The more specific patterns forLoopSimple and forLoopRange are shorthand for the examples shown above. The more specific patterns have the added benefit of exposing properties specific to the kind of loop in question.

Here is another way to express the previous pattern:

CXM code follows
for c in codes { where c matches forLoop{ .kind == `simple` } };

... or its alternative:

CXM code follows
for c in codes { where c matches forLoop{ .kind == `range` } };

forLoopRange (pattern)

Matches range-based for loops. (This kind of for loop was introduced in C++11.) Does not match any C-language code.

See also forLoopSimple, which matches the classic for loop construct in either C or C++.

Properties

forLoopRange produces a record that contains the following properties:

Name Type Description
kind enum forLoopKind The kind of loop: always `range`; see forLoopKind
loopVariable variable? The name of the loop control variable, if one was specified; null otherwise
collectionExpression expression The collection of things being enumerated. This is either a variable or a literal.
bodyStatement statement The statement that the loop repeatedly executes. Frequently this is a blockStatement.

Inherits properties from:

astnode

Example

The following code:

C++ code follows
for ( int x : arrayInts ) {
doSomething(x);
};

... is matched by a forLoopRange pattern. In this example, the properties of this pattern are returned as follows:

  1. .kind is `range`.

  2. .loopVariable is the variable x.

  3. .collection is the variable arrayInts.

  4. .bodyStatement is the blockStatement that contains the function call doSomething(x).

The following pattern detects any range-based for loop:

CXM code follows
for c in codes { where c matches forLoopRange };

A common coding mistake is the “do-nothing” for loop—that is, where the developer mistakenly types a semicolon immediately after the for condition, as in this expression:

C++ code follows
for ( int x: arrayInts );

The following pattern can detect such a mistake:

CXM code follows
for c in codes { where c matches forLoopRange { .bodyStatement == emptyStatement } };

As a matter of C++ best practices, it is safe and efficient to make the loop variable of a range-based for loop a const reference, as in the following example:

C++ code follows
for ( auto const &x : vec ) {
// ...
};

This protects you against unnecessary copying and accidental modification of the member that the loop variable refers to. The following pattern detects any range-based for loop in which the loop variable has not been declared with a const reference type:

CXM code follows
pattern nonConstRefLoopVar { forLoopRange { .loopVariable.type != referenceType { .referenceOfType == constOf(anyType); } } };

forLoopSimple (pattern)

Specifically matches only simple for loops.

Properties

forLoopSimple produces a record that contains the following properties:

Name Type Description
kind enum forLoopKind The kind of loop: always `simple`; see forLoopKind
initializationStatement statement? The initialization clause of the for loop; null if there is none
conditionExpression expression The condition that causes the loop to terminate
conditionDeclaration declaration? If a variable is declared within the condition (second clause) of the for loop, this property contains its name. (This is seldom done; this property is null if no such variable is declared.)
updateStatement statement? The statement that updates the loop value; frequently something like i++. This record is null if there is no such statement
bodyStatement statement The statement that the loop repeatedly executes. Frequently this is a blockStatement.

Inherits properties from:

astnode

Example

The following code:

C/C++ code follows
for ( int i = 0; i < 42; i++ ) {
doSomething(i);
};

... is matched by forLoopSimple, which sets the following properties:

Matching a Loop Whose Condition Is Always True

The foreverLoop pattern below matches a loop with a constant true condition, such as for(;;) or while(1) or a similar construct.

CXM code follows
// Some idioms to say "true" in C and C++ pattern alwaysTrueConstant { | booleanLiteral { .isTrue == true } | intLiteral { .valueInt != 0 } | binaryOperator { .lhsExpression == intLiteral{ .valueInt != 0 }; .operator == `!=`; .rhsExpression == intLiteral{ .valueInt == 0 } } | binaryOperator { .lhsExpression == intLiteral{ .valueInt == 0 }; .operator == `!=`; .rhsExpression == intLiteral{ .valueInt != 0 } } }; // Detecting forever-while and forever-for loops pattern foreverLoop { | whileLoop { .conditionExpression == alwaysTrueConstant } | forLoopSimple { .conditionExpression == alwaysTrueConstant } };

gotoStatement (pattern)

Matches goto statements.

Properties

gotoStatement produces a record that contains the following properties:

Name Type Description
labelStatement statement The labeled statement to which the goto jumps.

Inherits properties from:

astnode

Example

The pattern gotoStatement matches goto in source code. When matched, the pattern’s .labelStatement property indicates the target label.

Consider the following target code:

C/C++ code follows
if ( i == 5 ) {
goto flag;
}
// ...
flag:
count = 2;

In this example, gotoStatement matches the goto flag; statement and the pattern’s .labelStatement is set to flag:.

ifStatement (pattern)

Matches entire if statements, including their condition expressions and their true and false branches.

In C and C++, the consequences of the condition are each a single statement, but that single statement can be a block statement (that is, any number of statements enclosed by curly braces). This is reflected in the properties of the pattern.

Properties

ifStatement produces a record that contains the following properties:

Name Type Description
conditionExpression expression The condition that determines whether the trueStatement or the falseStatement is executed
trueStatement statement The “then” statement, which is only executed if conditionExpression evaluates to true
falseStatement statement? The “else” statement, which is only executed if conditionExpression evaluates to false. If the if has no else statement, this property is null.
conditionDeclaration declaration? If a variable is declared in the conditionExpression, this property contains its name; otherwise, this property is null.

Inherits properties from:

astnode

Example

The ifStatement pattern matches an instance such as this target source:

C/C++ code follows
if ( x == 1 )
return 0;
else
CallMyFunction(x);

A match returns these values:

The following use of the ifStatement specifically finds if statements that have an else clause:

CXM code follows
for c in codes { where c matches ifStatement { .falseStatement != null } };

labelStatement (pattern)

Matches statements that have a label.

Properties

labelStatement produces a record that contains the following properties:

Name Type Description
nameString string The value of the label
targetStatement statement The statement to which this label is assigned

Inherits properties from:

astnode

Example

Using the same source code as the gotoStatement pattern, the labelStatement pattern matches the flag: target, and .targetStatement contains the statement that follows; specifically, the assignment count = 2;:

C/C++ code follows
if ( i == 5 ) {
goto flag;
}
// ...
flag:
count = 2;

returnStatement (pattern)

Matches both simple, void return statements, and return <expression> returns.

Properties

returnStatement produces a record that contains the following properties:

Name Type Description
isVoid bool Equal to true if the function is a void function that uses a simple return statement and does not return a value.
returnedExpression expression? If the type of the function is not void, this property contains the expression that the function returns; otherwise, it is null.

Inherits properties from:

astnode

Example

Consider the following source:

C/C++ code follows
int func( int i ) {
return i;
}

The returnStatement pattern matches the return statement found within that function code. In this example, the pattern’s .isVoid property is false, and the .returnedExpression is i.

The following pattern matches instances of return where the expression being returned is an integer literal that appears directly in the source code (as opposed to one that was expanded from a preprocessor macro):

CXM code follows
pattern literalIntReturn { returnStatement { .returnedExpression == intLiteral { // An integer .macrosExpandedFrom.length == 0 } // Not expanded from macro } };

In other words, this matches return 42; but it does not match return ERROR_CODE;, where ERROR_CODE is defined to be an integer.

simpleStatement (pattern)

Matches individual executable statements.

In this context, the term simple means that such statements do not affect the flow of control. Simple statements include assignments and function calls. They do not include variable declarations: See variableDeclaration.

Properties

simpleStatement produces a record that contains the following properties:

Name Type Description
expression expression The expression, such as a function call or an assignment, that makes up the statement

Inherits properties from:

astnode

Example

The target expression x = x + 5; matches the following pattern:

CXM code follows
simpleStatement { .expression == assignmentOperator };

Similarly, a statement with the callFoo(); function call matches the following pattern:

CXM code follows
simpleStatement{ .expression == functionCall };

To find all function calls in simple statements, you could use the following pattern:

CXM code follows
for c in codes { where c matches simpleStatement { .expression == functionCall } };

switchStatement (pattern)

Matches entire switch statements, including all the statements contained in their case and default clauses. See also caseStatement, defaultStatement, and breakStatement.

Properties

switchStatement produces a record that contains the following properties:

Name Type Description
conditionExpression expression The expression that determines which case is to be taken
caseList list<statement>> A list of the targets of this switch statement. A target is either a caseStatement or a defaultStatement.
bodyStatement statement The body of the switch statement. In most cases this is a blockStatement.
conditionDeclaration declaration? If a variable is declared in the conditionExpression, it is identified here. If no variable is declared, this property is null.

Inherits properties from:

astnode

Example

A switchStatement pattern matches a switch statement instance such as the following:

C/C++ code follows
switch( i ) {
case 1: return "one";
case 2: return "two";
case 3: return "three";
default: return "unknown";
};

A match to the snippet above returns these values:

The following pattern identifies switch statements that do have default cases:

CXM code follows
// Switch with default statement pattern switchWithDefault {`` switchStatement as stms where exists stm in stms.caseList where stm matches defaultStatement };

tryStatement (pattern)

Matches try statements (C++ only), including any catch blocks associated with the try.

Properties

tryStatement produces a record that contains the following properties:

Name Type Description
bodyStatement statement The statement in the body of the try statement
catchBlockList list<record> The list of catch blocks

Inherits properties from:

astnode

Example

The tryStatement pattern matches source code such as this:

C++ code follows
try {
int i = 1;
}
catch(Exception1 e1) {
}
catch(Exception2 e2) {
}
catch(Exception3 e3) {
}

... where in this example, .bodyStatement refers to int i = 1; and .catchBlockList is a list that contains Exception1, Exception2, Exception3.

whileLoop (pattern)

Matches only standard while loops (as opposed to do ... while loops or for loops). The match includes the body statement that the while loop contains.

Details

This pattern only matches nodes of type statement.

Properties

whileLoop produces a record that contains the following properties:

Name Type Description
conditionExpression expression The condition that causes the loop to terminate
conditionDeclaration declaration? If a variable is declared within the condition of the while loop, this property contains its name. (This is seldom done; this property is null if no such variable is declared.)
bodyStatement statement The statement that the loop repeatedly executes. Frequently this is a blockStatement.

Inherits properties from:

astnode

Example

The following C/C++ fragment matches a whileLoop, which sets the following properties:

C/C++ code follows
while ( int cachedResult = SomeFunction() ) {
DoSomethingWith( cachedResult );
};

See Also

Matching a Loop Whose Condition Is Always True

Declarations

Patterns in this section belong to the declaration class. They match object declarations in the target code.

localFunctionDeclaration (pattern)

Matches function declarations within a function (as opposed to outside of a function, as is frequently done in headers).

This pattern does not match actual function calls. To find function calls, see functionCall.

See also: functionType.

Properties

localFunctionDeclaration produces a record that contains the following properties:

Name Type Description
declaredFunction functionType Information for the declared function

Inherits properties from:

astnode

Example

Consider the following snippet of C code:

C/C++ code follows
int foo( int i ) {
void bar( void ); /* A declaration: there is a function
named bar(). */
bar(); // An actual call to that function
};

The functionDeclarationLocal pattern matches void bar(void); in the first line of foo(), since bar() is declared locally.

However, this pattern does not match the actual call to bar(). To match the function call itself, use the functionCall pattern.

variableDeclaration (pattern)

Matches variable declarations, regardless of their location. For example, this pattern matches both the simple declarations found at the top of function code, and the scoped declarations that are found in various flow-of-control statements.

Properties

variableDeclaration produces a record that contains the following properties:

Name Type Description
kind enum variableDeclarationKind (see below) Variables can be declared in a variety of locations. This property indicates the scope of the declaration.
variable symbol The identifier of the variable being declared
initializer initializer? The expression evaluated to determine the initial value; null if there is no such expression

These are the possible values for the kind property (see also variableDeclarationKind):

`simple`
A local variable declaration

`global`
A variable declaration with global scope

`for`
A variable declared within the conditional expression of a for

`while`
A variable declared within the conditional expression of a while

`if`
A variable declared within the conditional expression of a if

`switch`
A variable declared within the conditional expression of a switch

Inherits properties from:

astnode

Declarations in conditional expressions:

For example, a variable declared in the conditional expression of an if statement is in scope for the rest of the conditional, and also within the statement’s then and else clauses.

Example

The variableDeclaration pattern matches source code such as the following:

C/C++ code follows
int num;
int count = 1;

In the first instance, .variable refers to num, and the property .initializer is null.

In the second instance, .variable refers to count, and .initializer is set to an expressionInitializer whose value is an intLiteral equal to 1.

The following pattern matches uninitialized variable declarations:

CXM code follows
pattern variableDeclarationUninitialized { variableDeclaration { .initializer == null } };

Types

These patterns match various types of values in the target code.

arrayType (pattern)

Matches arrays.

Properties

arrayType produces a record that contains the following properties:

Name Type Description
elementType type The type of the elements in the array
elementCount int? The number of elements in the array; null if the array is uninitialized
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
sizeInBytes int The number of bytes required to store a value of this type

Example

In the following source code, the pattern arrayType matches the type of a local variable x in the assignment statement, provided that .elementType is intType and .elementCount is 10:

C/C++ code follows
int x[10];
x[0] = 1;

The following pattern detects an expression that is an array type:

CXM code follows
node matches expression { .type == arrayType };

boolType (pattern)

Matches the Boolean types, both bool and _Bool (C11 and later).

Properties

boolType produces a record that contains the following properties:

Name Type Description
kind enum One of `bool` or `_Bool`
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
sizeInBytes int The number of bytes required to store a value of this type
sizeInBits int The number of bits required to store a value of this type

Example

In the following source code, the pattern boolType matches the type of a local variable x:

C/C++ code follows
bool x = true;

The following pattern matches all expressions with a Boolean type:

CXM code follows
node matches expression { .type == boolType };

charType (pattern)

Matches character types such as char or the C++ wchar_t.

Properties

charType produces a record that contains the following properties:

Name Type Description
kind enum One of `char`, `unsigned char`, `signed char`, or `wchar_t`
isSigned bool true if the type is signed
isExplicitlySigned bool true if the sign is explicitly stated (rather than being implied)
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
sizeInBytes int The number of bytes required to store a value of this type
sizeInBits int The number of bits required to store a value of this type

Example

In the following source code, the pattern charType matches the type of a local variable x:

C/C++ code follows
char x = 'a';

The following example matches explicitly signed char types:

CXM code follows
node matches expression { .type == charType { .isExplicitlySigned == true } };

classType (pattern)

Matches class (C++), struct, and union types.

Properties

classType produces a record that contains the following properties:

Name Type Description
kind enum One of `class`, `struct`, or `union`
isAnonymous bool true if the object is anonymous
identifier string? The string used as an unqualified name for this type; null if the object is unnamed
mangledName string? The internal “mangled” name used for the class (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available
isAlignmentAssigned bool true if the class is aligned
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
isComplete bool true if the object definition is known at compile time
location sourceloc The source-code location of the type definition
scopeList list<string> The scopes within which the class is nested
sizeInBytes int The number of bytes required to store a value of this type

Example

In the following source code, the pattern classType matches the type of a local variable x:

C++ code follows
class T { /* ... */ };
T x;

The following pattern matches all expressions with an anonymous class type:

CXM code follows
node matches expression as e && e.type matches classType { .isAnonymous == true };

See Also

getClassDefinition

deducedType (pattern)

Matches compiler-deduced types specified using the auto or decltype declarators.

Be careful: This pattern only applies to C++. With this pattern, the auto keyword refers to C++ usage, not to C usage. It indicates a variable that is declared in a function’s stack frame. Because the C-language use of auto is the default, auto in C code is not recorded by analysis, per se; see localVariableSymbol.

Properties

deducedType produces a record that contains the following properties:

Name Type Description
kind enum deducedTypeKind One of `auto`, `decltype`, or `gnu_auto`; see deducedTypeKind
inferredType type The type inferred by a compiler

Example

In the following source code, the type of a local variable a is declared using auto. This can be matched by a deducedType pattern that specifies .inferredType to be intType (that is, the compiler inferred the type of integer) and .kind to be `auto`.

C/C++ code follows
auto i = 1;

The following example matches types that are inferred to be integers:

CXM code follows
node matches expression as e && e.type matches deducedType { .inferredType == intType };

enumType (pattern)

Matches enum types.

Properties

enumType produces a record that contains the following properties:

Name Type Description
identifier string The string used as an unqualified name for the enum
mangledName string? The internal “mangled” name used for the enum (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available
location sourceloc The source-code location of the enum definition
isAlignmentAssigned bool true if the enum is aligned
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
scopeList list<string> The scopes within which the enum is nested
sizeInBytes int The number of bytes required to store a value of this type

Example

In the following source, the code pattern enumType matches the type of a local variable x:

C/C++ code follows
enum FOO { bar, baz };
FOO x = bar;

The following pattern matches all expressions with type enum FOO:

CXM code follows
node matches expression as e && e.type matches enumType { .identifier == "FOO" };

See Also

getEnumDefinition

floatType (pattern)

Matches primitive floating-point types such as float, double, or long double.

Please be aware: The precision of floating-point representations depends on the target system’s implementation.

Properties

floatType produces a record that contains the following properties:

Name Type Description
kind enum floatKind One of `float`, `double`, or `long double`; see floatKind
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
sizeInBytes int The number of bytes required to store a value of this type
sizeInBits int The number of bits required to store a value of this type

Example

In the following source code, the pattern floatType matches the type of a local variable x:

C/C++ code follows
float x = 1.0;

The following example matches float types, but does not match double or long double:

CXM code follows
node matches expression { .type == floatType { .kind == `float` } };

functionType (pattern)

Matches the types of functions; for example, the type of the function being called in a function call.

Properties

functionType produces a record that contains the following properties:

Name Type Description
declaredThrownTypeList list<type>? The types of the exceptions that the function might directly or indirectly throw; null if there are none
doesNotReturn bool true if the function does not return
hasEllipsis bool true if the function’s parameter list uses ellipsis ( ... ) notation
hasNoExcept bool true if the function is declared with the keyword noexcept (since C++11)
isMemberFunction bool true if the function is a method in a class (C++ only)
isPrototyped bool true if the function has a prototype
paramTypeList list<type> The types of the function’s formal parameters
returnType type The type of the value returned by the function

Example

The following pattern matches a member function call whose return type is voidType.

CXM code follows
pattern memberFcnCallWithVoidReturn { functionCall { .calledFunction.type == functionType { .isMemberFunction == true; .returnType == voidType } } };

intType (pattern)

Matches integer types, including bool, char, short, int, long, and long long (C++).

Properties

intType produces a record that contains the following properties:

Name Type Description
kind enum intKind One of `bool`, `char`, `short`, `int`, `long` or `long long`; see intKind
isSigned bool true if the type is signed
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
sizeInBytes int The number of bytes required to store a value of this type
sizeInBits int The number of bits required to store a value of this type

Example

In the following source code, the pattern intType matches the type of a local variable x:

C/C++ code follows
int x = true;

The following pattern matches all short types:

CXM code follows
node matches expression { .type matches intType { .kind == `short` } };

memberType (pattern)

(C++) Matches members of classes.

Properties

memberType produces a record that has the following properties:

Name Type Description
classType classType The type of the class that owns the member
memberType type The type of the member itself

Example

Consider the following source code:

C++ code follows
class Bird {
public:
int mN;
};
int Bird::*pN = &Bird::mN;

The following CodeXM fragment would match both these members of Bird: the pointer pN and the pointer target &Bird::mN:

CXM code follows
pointerType { .pointerToType == memberType };

nullPointerType (pattern)

Matches null pointers, including the keyword nullptr introduced in C++11.

Properties

This pattern matches only nodes of type type. It does not expose any new properties.

Inherits properties from:

astnode

Example

In the following source code fragment, nullPointerType matches the variable nullVar:

C++ code follows
#include <cstddef>
std::nullptr_t nullVar = nullptr;

pointerType (pattern)

Matches pointer types such as int* or char*.

Properties

pointerType produces a record that contains the following properties:

Name Type Description
pointerToType type The type of the referenced value
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned
sizeInBytes int The number of bytes required to store a value of this type

Example

In the following source code, the pattern pointerType matches the type of a local variable x, provided that the .pointerToType property is intType:

C++ code follows
int *x = nullptr;

The following pattern matches all expressions that are pointers to integers:

CXM code follows
node matches expression as e && e.type matches pointerType { .pointerToType == intType };

referencedTypesType (pattern)

Matches types that instantiate a template (C++).

Details

This pattern only matches nodes of type type.

Properties

referencedTypesType produces a record that contains the following properties:

Name Type Description
referencedTypes list<type> The types that the template instance references.
targetType type The type of the template instance.

Example

Suppose you had a program with the following declarations:

C++ code follows
template< typename T1, typename T2 >
class myClass {
}
myClass< int, bool > cls;

... then referencedTypesType would match cls. Its .referencedTypes property would contain intType and boolType, and the value of .targetType would be "myClass".

sizeofOperatorType (pattern)

Matches instances of the sizeof() operator applied to types; for example, sizeof( int ).

Properties

sizeofOperatorType produces a record that contains the following properties:

Name Type Description
operandType type The type being evaluated
vlaExpressions list<expression>? The expression being evaluated to find the size of a variable-length array; null if there is no expression

Example

The sizeofOperatorType pattern matches the use of sizeof() in the following source code:

C/C++ code follows
int var = /* something */;
int size = sizeof(int[var]);

In this case, the pattern has an .operandType indicating that it is an array, and .vlaExpressions refers to var.

The following pattern matches any sizeof() operator applied to a variable-length array:

CXM code follows
pattern sizeofVLA { sizeofOperatorType { .operandType == arrayType; .vlaExpressions != null; } };

typedefType (pattern)

Matches uses of a type defined using a typedef declarator.

Properties

typedefType produces a record that contains the following properties:

Name Type Description
identifier string The string used as an unqualified name for the symbol
mangledName string The internal “mangled” name used for the symbol (the mangled name includes type and scope information, to disambiguate this instance of the identifier)
targetType type The original, underlying type
scopeList list<string> The scopes within which the typedef is nested

Example

In the following source code, the type of variable pattern typedefType matches i, provided .targetType is a typeQualifier and .targetType specifies an integer type (intType):

C/C++ code follows
typedef const int CInt;
CInt i = 1;

The following pattern matches nodes whose type is defined as Cint:

CXM code follows
node matches expression as e && e.type matches typedefType { .alias == "CInt" };

typeQualifier (pattern)

Matches C-language type qualifiers, such as const, volatile, or restrict.

Details

This pattern does not match the C++ qualifier _Atomic.

Properties

typeQualifier produces a record that contains the following properties:

Name Type Description
qualifierList list<enum qualifierEnum> The qualifiers of the type: Items in the list can be `const`, `volatile`, or `restrict`; see qualifierEnum
targetType type The type the qualifier is applied to

Example

Given the following code snippet:

C/C++ code follows
const int i = 1;

... the following pattern:

CXM code follows
node matches expression as e && e.type matches typeQualifier as ty where ty.qualifierList.contains( `const` );

... matches the variable i, because this variable’s declaration is qualified by const.

typeQualifierAtomic (pattern)

Matches types qualified by using the atomic qualifier.

Properties

typeQualifierAtomic produces a record that contains the following properties:

Name Type Description
targetType type The type the qualifier is applied to

typeQualifierConst (pattern)

Matches types qualified by using the const qualifier.

Properties

typeQualifierConst produces a record that contains the following properties:

Name Type Description
targetType type The type the qualifier is applied to

typeQualifierRestrict (pattern)

Matches types qualified by using the restrict qualifier.

Properties

typeQualifierRestrict produces a record that contains the following properties:

Name Type Description
targetType type The type the qualifier is applied to

typeQualifierVolatile (pattern)

Matches types qualified by using the volatile qualifier.

Properties

typeQualifierVolatile produces a record that contains the following properties:

Name Type Description
targetType type The type the qualifier is applied to

voidType (pattern)

Matches the void type.

Properties

This pattern does not expose any new properties.

Example

In the following code, the return type of the function test() is matched by voidType:

C/C++ code follows
void test() { /* ... */ };

Expressions

Patterns in this section belong to the expression class. They match expressions in the target code.

Many statements in C or C++ code contain expressions. The patterns in this section match specific kinds of expressions.

Please be aware: The patterns shown in the “Literals” and “Operators” sections are expressions, too.

Example: Expressions used as if-statement conditions

For example, in the following snippet of target code:

C/C++ code follows
if ( my_boolean ) {
if ( getPropertyValue(a) == v) {
// ... Do something.
}
};

... we see a pair of if statements. As described in the previous section, the ifStatement pattern detects either instance.

But each statement has a condition: namely, the part enclosed by the parentheses that follow the keyword if. Both conditions in this example are expressions. The first is simply a variable reference. The second is more complicated: It is made up of a binary operator (specifically, the equality operator) with operands (which are themselves expressions) appearing on either side. The left-hand operand is a function call, and the right-hand operand is a variable reference.

You could match the first of these conditions by using the expression pattern variableReference (which also matches the right-hand side of the second condition), and you could match the second of these conditions by using the expression pattern binaryOperator.

To inspect a complete condition expression, look at the .conditionExpression property of the ifStatement pattern.

Common Properties of Expressions

In addition to the properties specific to each pattern, and the properties inherited from astnode, all expression patterns have the following properties:

Name Type Description
type type The C/C++ type of the expression
isParenthesized bool Whether there are parenthesis around this expression

functionCall (pattern)

Matches function call sites: places in the current code where a function is invoked.

Details

This pattern only matches actual function call sites. It does not match simple references to the function’s identifier. For example, it would not match the function name’s appearance in code that assigned a function pointer to the function.

Properties

functionCall produces a record that contains the following properties:

Name Type Description
calledFunction functionSymbol? Information about the function itself; null if this is not available
argumentList list<expression> The parameters used in the call
isVirtual bool true if the function is a virtual method call (C++ only)
isNonstaticMethod bool true if the function call is into a class method that is not static (that is, it has a this pointer)
isQualified bool true if the function’s return type has a qualifier

Inherits properties from:

astnode

Example

The functionCall pattern matches source code that invokes a call to another function; for example, sum( i, j+k ) in the initialization shown by the following code:

C/C++ code follows
int m = sum( i, j+k );

In this example, the .calledFunction refers to the metadata for the function sum(). The .argumentList contains two items: The first is a variableReference to i, and the second is the binaryOperator that represents the addition of the variables j and k.

kernelCall (pattern)

Matches calls to launch a CUDA kernel.

These calls have the scheme launchNewKernel<<< Dg, Db, Ns >>>( parameters, ... ).

Reminder: To find kernelCall patterns, your program needs to include `CUDA` as the language library. See The CUDA Extension.

Properties

kernelCall produces a record that contains the following properties:

Name Type Description
associatedStream expression The associated stream to launch
blockDimension expression The dimension of each block
callExpression functionCall The call itself, excluding its configuration arguments
gridDimension expression The dimension of the grid
sharedMemoryBytes expression The number of bytes per block in shared memory that is dynamically allocated for this call

Inherits properties from:

astnode

memberReference (pattern)

Matches references to member fields of structures or classes (C++ only).

Properties

memberReference produces a record that contains the following properties:

Name Type Description
objectExpression expression The structure or class object whose member is being accessed
field type The member field

Inherits properties from:

astnode

Example

The pattern memberReference matches references to members of a struct or a class. Consider the following C++ code:

C++ code follows
typedef struct {
int i;
float f;
} ST;
ST st;

In this case, memberReference matches two instances, one on each line shown below:

C++ code follows
int my_i = st.i;
st.f = 42.0f;

On the first line, the .objectExpression is st, and the .field property refers to field i.

On the second, the pattern is almost the same, but the .field property refers to field f.

pointerDereference (pattern)

Matches pointer dereference (*p) expressions.

Properties

pointerDereference produces a record that contains the following properties:

Name Type Description
pointerExpression expression The pointer being dereferenced

Inherits properties from:

astnode

Example

The pointerDereference pattern matches the dereference in the following code:

C/C++ code follows
int n = *p_m;

The .pointerExpression property is a variableReference to p_m.

sizeofOperatorExpression (pattern)

Matches instances of the sizeof() operator applied to expression; for example, sizeof( y[0] ).

See also sizeofOperatorExpression and sizeofOperatorType.

Properties

sizeofOperatorExpression produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being evaluated for size information

Inherits properties from:

astnode

Example

The sizeofOperatorExpression pattern matches code such as the following:

C/C++ code follows
int num = 1;
int size = sizeof(num)

In this instance, .operandExpression refers to num.

The following pattern matches a sizeof() operator invoked using a variable reference expression:

CXM code follows
pattern sizeofVar { sizeofOperatorExpression { .operandExpression == variableReference; } };

subscriptReference (pattern)

Matches subscript references, such as p[i].

Caution: This pattern does not match the logical equivalent, *( p + i ), and it does not match C++ subscript operator overloads (which are method calls rather than actual operators).

See also arrayOf for a function that specifically looks for an array of the type you indicate.

Properties

subscriptReference produces a record that contains the following properties:

Name Type Description
arrayExpression expression The array being referenced
indexExpression expression The indexing expression

Inherits properties from:

astnode

Example

The subscriptReference pattern matches the two instances in the following source code:

C/C++ code follows
x = arr[3];
arr[5] = 1;

In the both cases, .arrayExpression refers to a variableReference of arr, and in both cases the .indexExpression is an integer literal: The values will be 3 and 5, respectively.

variableReference (pattern)

Matches variable references within expressions.

Properties

variableReference produces a record that contains the following properties:

Name Type Description
identifier string The name of the identifier (shorthand for .variable.identifier)
mangledName string The internal “mangled” name used for the variable (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available
variable variableType The variable being referenced
scope enum variableScopeEnum The scope of the variable: either `local` or `global`. Static variables are classified as `global`; see variableScopeEnum
isVolatile bool true if this variable is volatile
isFunctionStatic bool true if this variable was declared within a function and modified by the keyword static
isClassStatic bool true if this variable is a static member variable of a class (C++ only)

Inherits properties from:

astnode

Example

Imagine the following target code:

C/C++ code follows
int x = 123; // "x" is a global variable.
void func() {
int y;
y = x;
};l

The variableReference pattern matches x in the function func() (specifically in respect to the assignment y = x).

The following pattern detects all references of global variables within expressions:

CXM code follows
pattern globalVariableSymbolReference { variableReference { .scope == `global`; } }

Literals

These patterns match literal values in the target code.

booleanLiteral (pattern)

Matches the Boolean literals true and false.

Details

This pattern only matches nodes of type expression.

Properties

booleanLiteral produces a record that contains the following properties:

Name Type Description
isTrue bool Matches the value of the literal.

Inherits properties from:

astnode

Example

In the following C++ snippet, the pattern booleanLiteral matches false by setting the property .isTrue to false:

C++ code follows
bool flag = false;

The following pattern matches any true Boolean literal.

CXM code follows
pattern trueBoolean { booleanLiteral { .isTrue == true } };

floatLiteral (pattern)

Matches all floating-point literals, including both single and double precision (that is, the types float and double).

Details

This pattern only matches nodes of type expression.

Properties

floatLiteral produces a record that contains the following properties:

Name Type Description
valueString string The string representation of the literal
suffix enum floatSuffix? `f` or `l` if a suffix is specified in the source (see floatSuffix); null if there is no suffix.
isLowercaseSuffix bool true if the suffix is lower case in the source
isLowercaseLSuffix bool true if the suffix is a lowercase l (ell)
isHexFloat bool true if the literal is hexadecimal (preceded by 0x or 0X)

Inherits properties from:

astnode

Example

In the case of the folllowing code:

C/C++ code follows
float x = 2.5f;

... a floatLiteral matches if .valueString is set to "2.5" and .suffix is set to `f`. The property .isLowercaseSuffix will be true.

intLiteral (pattern)

Matches all integer literals, regardless of their sign or base.

Details

This pattern only matches nodes of type expression.

Properties

intLiteral produces a record that contains the following properties:

Name Type Description
value int The actual value represented by the literal
base enum `binary`, `decimal`, `octal`, or `hexadecimal`
kind enum intKind `bool`, `char`, `short`, `int`, `long`, or `long long` (C++ only); see intKind
llsuffix enum? `l` or `ll` if the literal has one of these suffixes; null otherwise
isLowercaseLSuffix bool true if the suffix is lower case
hasUSuffix bool true if the suffix is U (for unsigned)
isLowercaseSuffix bool true if all the suffixes are lower case

Inherits properties from:

astnode

Example

Consider the following literal initialization:

C/C++ code follows
long x = 8888l;

The value 8888l produces an integer literal, so an intLiteral pattern matches it. The .value property will be 8888, .kind will be `long`, .llSuffix will be `L`, and .isLowercaseLSuffix will be true.

Because the appearance of the lowercase letter L (l) is nearly indistinguishable from the digit one (1) in many typefaces and environments, many coding standards require that the suffix always be uppercase to avoid misinterpretation. The following pattern matches violations of this rule:

CXM code follows
pattern intLiteralLowercaseSuffix { intLiteral { // An integer literal .llSuffix != null; // ... that has a suffix .isLowercaseLSuffix == true; // ... that is lowercase } };

nullPointerLiteral (pattern)

Matches null pointers.

Details

The nullptr value (as opposed to NULL) was introduced in C++11.

This pattern only matches nodes of type expression.

Properties

nullPointerLiteral produces a record that contains the following properties:

Name Type Description
kind enumnullKind The kind of literal used to encode the null: `0`, `NULL`, or `nullptr`; see nullKind

Inherits properties from:

astnode

Example

The nullPointerLiteral pattern matches NULL or nullptr or 0 in source code.

For example, the pattern nullPointerLiteral matches the following snippet with .kind set to `NULL`:

C/C++ code follows
int *p_i = NULL;

The pattern nullPointerLiteral matches the next snippet by setting .kind to `0`.

C/C++ code follows
int *p_i = 0;

The following pattern matches the use of 0 as a null pointer:

CXM code follows
pattern nullPointerZero { nullPointerLiteral { .kind == `0` } };

stringLiteral (pattern)

Matches all character string literals.

Details

This pattern only matches nodes of type expression.

Properties

stringLiteral produces a record that contains the following properties:

Name Type Description
valueString string The actual string
encodingType enum stringLiteralEncoding `char`, `wchar`, `utf16`, or `utf32`; see stringLiteralEncoding

Inherits properties from:

astnode

Example

Consider the following declaration:

C/C++ code follows
char str[] = "hello";

In this case, the stringLiteral pattern matches "hello", with .valueString containing the string itself and .encodingType set to `char`.

The following pattern matches a stringLiteral whose encoding type is `char`, such as the one in the previous example:

CXM code follows
pattern stringPtn { stringLiteral { .encodingType == `char` } };

Operators

These patterns match operators in the target code.

addressOf (pattern)

Matches instances of the & (“address of”) operator.

Details

This pattern only matches nodes of type expression.

Properties

addressOf produces a record that contains the following properties:

Name Type Description
operandExpression expression The operand of the & operator (the object whose address is being retrieved)

Inherits properties from:

astnode

Example

The addressOf pattern matches the &num in the following code:

C/C++ code follows
int *p_num = &num;

The following pattern matches the addressOf of any global variable:

CXM code follows
pattern addressOfGlobal { addressOf { .operandExpression == variableReference { .scope == `global` } } };

assignmentOperator (pattern)

Matches all forms of the assignment operator in expressions, or the cases where a variable takes on a new value. This pattern does not match variable declarations, which are distinct and are matched by their own pattern, variableDeclaration.

This general pattern matches both simple assignments such as x = 10 and the compound forms such as x += 10. (The patterns assignmentOperatorSimple and assignmentOperatorCompound make the distinction by matching only one of these forms of assignment or the other.)

Details

This pattern only matches nodes of type expression.

Properties

assignmentOperator produces a record that contains the following properties:

Name Type Description
kind enum assignKind Either `simple` or `compound`, to indicate which form of assignment has matched; see assignKind
targetExpression expression The target of the assignment; typically, a variable receiving a new value, such as what C/C++ refers to as an lvalue
sourceExpression expression The expression which, when evaluated, is assigned to the target
operator enum The assignment operator, either `=` or one of the many compound forms, such as `+=` or `*=`

Inherits properties from:

astnode

Example

The assignmentOperator pattern matches source such as the assignment shown here:

C/C++ code follows
int num;
num = 1;

In this match, the .operator is described as `=` and its .kind is `simple`. Unsurprisingly, the .sourceExpression is an intLiteral; specifically, the literal 1.

What might be surprising is that there is a property named .targetExpression. You might expect this to be named “.targetVariable”, but consider that not every assignment is directly to a named variable. For example, an assignment can also be made to an address pointed to by a pointer, or to a member of an array.

In this particular example, however, .targetExpression is a variableReference, which is always the case when a variable is being assigned.

Consider the following pattern:

CXM code follows
pattern embeddedAssignment { assignmentOperator { .parent != simpleStatement } };

Statements and expressions in your code can be visualized as a tree structure. We saw this in the section named “Code Patterns”, and we draw upon that example here. Remember that the following source code:

C/C++ code follows
x = y*2 + 1;

... is expressed by the following syntax tree:

Code expressed as a tree of nodes

We see that the simpleStatement pattern matches the expression x = y*2 + 1, which is an assignment of y*2 + 1 to the variable x.

The pattern embeddedAssignment shown above matches any instance of an assignment operator that is not immediately under a simple statement. In other words, embeddedAssignment finds assignments that occur within a larger expression (because the parent would be another expression) or within an if, while, or other statement (because the parent would be another kind of statement).

Consequently, this pattern would detect the assignment of y in the following source code:

C/C++ code follows
x = 4 * (y = 42) + z;

... as well as the assignment of x in the following source:

C/C++ code follows
if (x = 42) {
// ...
};

assignmentOperatorCompound (pattern)

Matches only compound assignments such as x += y or z *= 3.14.

This pattern is shorthand for the pattern assignmentOperator { .kind == `compound` }.

Details

This pattern only matches nodes of type expression.

Properties

assignmentOperatorCompound produces a record that contains the following properties:

Name Type Description
kind enum assignKind Always `compound`; see assignKind
targetExpression expression The target of the assignment; typically, a variable receiving a new value, such as what C/C++ refers to as an lvalue
sourceExpression expression The expression which, when evaluated, is assigned to the target
operator enum The assignment operator: one of the many compound forms, such as `+=` or `*=`

Inherits properties from:

astnode

Example

The assignmentOperatorCompound pattern can match source code that uses the += operator:

C/C++ code follows
int count = 0;
count += 1;

In this match, the property .kind is `compound` and .targetExpression refers to count. The .sourceExpression refers to the intLiteral with the value of 1, and .operator is `+`.

Combining these properties, we can construct the following pattern. It detects compound addition assignments to a variable named count. Pattern decomposition defines two constraints on the assignment operator’s properties—that is, both must be true for the overall pattern to match.

CXM code follows
pattern compoundAdditionToCount { assignmentOperatorCompound { .operator == `+=`; .targetExpression == variableReference { .identifier == "count" }; } };

assignmentOperatorSimple (pattern)

Matches only simple assignments.

Be careful: Even though variable declarations look similar to assignment operators, this pattern does not match variable declarations. See the pattern variableDeclaration.

This pattern is shorthand for the pattern assignmentOperator { .kind == `simple` }.

Details

This pattern only matches nodes of type expression.

Properties

assignmentOperatorSimple produces a record that contains the following properties:

Name Type Description
kind enum assignKind Always `simple`; see assignKind
targetExpression expression The target of the assignment; typically, a variable receiving a new value, such as what C/C++ refers to as an lvalue
sourceExpression expression The expression which, when evaluated, is assigned to the target
operator enum Always `=`

Inherits properties from:

astnode

Example

The following code assigns a constant value 123 to the variable x. The pattern assignmentOperatorSimple matches this simple assignment:

C/C++ code follows
int x;
x = 123;

As mentioned previously, assignment doesn’t happen only to variables. The following pattern matches an assignment to the target of a pointer:

CXM code follows
pattern assignmentToPointer { assignmentOperatorSimple { .targetExpression == pointerDereference } };

Assuming the following definition:

C/C++ code follows
char* chptr;

... the assignmentToPointer pattern would not match the following code:

C/C++ code follows
chptr = somebuf;

... because the target expression is a variable reference (chptr itself).

The pattern would match the following source:

C/C++ code follows
*chptr = 42;

... because here the target expression dereferences chptr.

When a variable is a pointer, the array-like notation is seen as a pointer dereference as well. That is, chptr[0] is equivalent to *chptr, so assignmentToPointer matches it. This does not hold true for variables defined as arrays: for char buf[], the array reference buf[0] does not match.

binaryOperator (pattern)

Matches the many binary operators—operators that take an operand on either side, such as +, *, ==, and so on.

Details

This pattern only matches nodes of type expression.

Properties

binaryOperator produces a record that contains the following properties:

Name Type Description
operator enum Can be one of: `==`, `!=`, `<`, `>`, `<=`, `>=`, `<=>`, `*`, `/`, `%`, `+`, `-`, `<<`, `>>`, `&`, `^`, `|`, `&&`, `||`, `,`, or `=`
lhsExpression expression The operand on the left-hand side of the operator
rhsExpression expression The operand on the right-hand side of the operator
isImplicit bool true if the operator is implicit

Inherits properties from:

astnode

Nested Expressions

When pattern matching, be aware that either or both operands of a binary operator can themselves be binary operators that represent operations to be completed before the matched operation is performed.

For example, a + b * c is understood as a + (b * c) due to operator precedence. This is matched as a binary addition that has a right-hand operand of b * c. The value of the subexpression must be computed before the addition is performed.

On the other hand, (a + b) * c is matched as a binary multiplication. The left-hand operand, a + b, must be computed before it is multiplied by c.

The following illustration shows these two situations:

Parsing binary operations

In both these cases, a binaryOperator { .operand == `*` } pattern matches some part of the expression. In the left-hand case, it matches b * c. In the right-hand case, it matches the entire expression.

Example

In the following snippet, an unconstrained binaryOperator matches all binary operations, including 2*a + 3 (the addition operation, where the left-hand side is a binary operation), 2*a (multiplication), and a & c (logical AND).

C/C++ code follows
int a = 1;
int b, c, d;
b = 2*a + 3;
c = 2;
d = a & c;

You can refine the binaryOperator pattern to match only specific operations. For example, the following pattern:

CXM code follows
binaryOperator { .operator == `*` };

... matches only multiplication (the instance 2*a in the example above), and the following pattern:

CXM code follows
binaryOperator { .operator == `+` };

... matches only addition.

Patterns can be compositions of separate sub-patterns, in order to match a more complicated expression; for example, to match the addition of a product of two terms with another term, you could use a pattern such as the following:

CXM code follows
pattern multiplyThenAdd { binaryOperator { .operator == `+`; .lhsExpression == binaryOperator { .operator == `*` }; } };

The previous pattern only detects when the multiplication happens on the left-hand side of the addition: 2*a + 3 matches, but 3 + 2*a does not. To generalize the pattern so it matches either variation, use the following code:

CXM code follows
pattern multiplyThenAdd { | binaryOperator { .operator == `+`; .lhsExpression == binaryOperator { .operator == `*` }; } | binaryOperator { .operator == `+`; .rhsExpression == binaryOperator { .operator == `*` }; } };

This uses the alternative ( | ) operator to say the pattern can match either multiplication on the left-hand side or the right-hand side.

However, this new pattern matches multiplication on one side, the other, or both; for example, it would also match this code:

C/C++ code follows
2*a + 3*b

... where multiplication occurs on both sides of the addition. If you want to match multiplication on one side only, revise the pattern to impose that constraint.

castOperator (pattern)

Matches all C and C++ type casts. These includes C-style casts (explicit), implicit type conversions, and the C++ operations static_cast, dynamic_cast, reinterpret_cast, and const_cast.

Details

This pattern only matches nodes of type expression.

Properties

castOperator produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being cast
kind enum castKind `explicit`, `implicit`, `static`, `dynamic`, `reinterpret`, or `const`; see castKind

The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.

Inherits properties from:

astnode

Example

Consider the following code:

C/C++ code follows
int i = 1;
float f = i;

The castOperator pattern matches the implicit cast on the second line, where the integer i needs to be converted to floating point so it can be assigned to f. In this example, the .kind property is `implicit`.

The following pattem shows how to match any implicit cast from an integer type to a floating-point type:

CXM code follows
pattern implicitCastIntToFloat { castOperator { .kind == `implicit`; .type == floatType; // The intended type .operandExpression.type == intType; // the uncast type } };

castOperatorConstCast (pattern)

Matches only C++ constant casts (const_cast<A>( p )).

This pattern is equivalent to using castOperator with the .kind property set to `const`.

Details

This pattern only matches nodes of type expression.

Properties

castOperatorConstCast produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being cast
kind enum castKind `const`; see castKind see castKind

The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.

Inherits properties from:

astnode

Example

The castOperatorConstCast matches the following source code:

C++ code follows
char* p1 = const_cast<char*>(p);

The following pattern matches constant casts from the integer type:

CXM code follows
pattern constCastFromInt { castOperatorStatic { .operandExpression.type == intType; } };

castOperatorDynamicCast (pattern)

Matches only C++ dynamic casts (dynamic_cast<A>( p )).

This pattern is equivalent to using castOperator with the .kind property set to `dynamic`.

Details

This pattern only matches nodes of type expression.

Properties

castOperatorDynamicCast produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being cast
kind enum castKind `dynamic`; see castKind

The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.

Inherits properties from:

astnode

Example

The castOperatorDynamicCast pattern matches the cast present in following source code:

C++ code follows
T1 *p1 = dynamic_cast<T2*>(p);

The following pattern matches dynamic casts from the class named A:

CXM code follows
pattern dynamicCastFromA { castOperatorDynamicCast { .operandExpression.type == classType { .identifier == "A" } } };

castOperatorExplicit (pattern)

Matches only explicit C-style casts.

This pattern is equivalent to using castOperator with the .kind property set to `explicit`.

Details

This pattern only matches nodes of type expression.

Properties

castOperatorExplicit produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being cast
kind enum castKind `explicit`; see castKind

The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.

Inherits properties from:

astnode

Example

To match an explicit cast from the int type, you could use the following pattern:

CXM code follows
pattern explicitCastFromInt { castOperatorExplicit { .operandExpression.type == intType; } };

castOperatorImplicit (pattern)

Matches only implicit type conversions. That is, places where a type conversion occurs but is not explicitly specified in the source code.

This pattern is equivalent to using castOperator with the .kind property set to `implicit`.

Details

This pattern only matches nodes of type expression.

Properties

castOperatorImplicit produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being cast
kind enum castKind `implicit`; see castKind

The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.

Inherits properties from:

astnode

Example

To match an implicit cast from the int type, you could use the following pattern:

CXM code follows
pattern implicitCastFromInt { castOperatorImplicit { .operandExpression.type == intType; } };

castOperatorReinterpretCast (pattern)

Matches only C++ reinterpret casts (reinterpret_cast<A>( p )).

This pattern is equivalent to using castOperator with the .kind property set to `reinterpret`.

Details

This pattern only matches nodes of type expression.

Properties

castOperatorReinterpretCast produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being cast
kind enum castKind `reinterpret`; see castKind

The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.

Inherits properties from:

astnode

Example

The castOperatorReinterpretCast matches the following source code:

C++ code follows
char* p1 = reinterpret_cast<char*>(p);

The following pattern matches reinterpret casts from the class named A:

CXM code follows
pattern reinterpretCastFromA { castOperatorReinterpretCast { .operandExpression.type == classType { .identifier == "A" } } };

castOperatorStaticCast (pattern)

Matches only C++ static casts (static_cast<A>( p )).

This pattern is equivalent to using castOperator with the .kind property set to `static`.

Details

This pattern only matches nodes of type expression.

Properties

castOperatorStaticCast produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being cast
kind enum castKind `static`; see castKind

The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.

Inherits properties from:

astnode

Example

The castOperatorStaticCast matches the following source code:

C++ code follows
T1 *p1 = static_cast<T2*>(p);

To match static casts from integers, you could use the following pattern:

CXM code follows
pattern staticCastFromInt { castOperatorStatic { .operandExpression.type == intType; } };

conditionalOperator (pattern)

Matches the conditional operator (sometimes called the “ternary” operator) ?:.

Details

This pattern only matches nodes of type expression.

Properties

conditionalOperator produces a record that contains the following properties:

Name Type Description
conditionExpression expression The condition: the expression before the question mark
trueExpression expression The expression to evaluate if the condition is true: the expression between the question mark and the colon
falseExpression expression The expression to evaluate if the condition is false: the expression after the colon

Inherits properties from:

astnode

Example

The conditionalOperator matches the following source code:

C/C++ code follows
x > 0 ? x : -x;

In the preceding code, the property .conditionExpression is set to the condition x > 0. The x and -x outcomes correspond to the trueExpression and falseExpression, respectively.

The following pattern matches any operator that uses a binary operator as its condition:

CXM code follows
pattern binaryOpInCond { conditionalOperator { .conditionExpression == binaryOperator } };

decrementOperator (pattern)

Matches the decrement operators, detecting both prefix (as in --i) and postfix (i--) variants.

Details

This pattern only matches nodes of type expression.

Properties

decrementOperator produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being decremented
kind enum `prefix` or `postfix`

Inherits properties from:

astnode

Example

The decrementOperator pattern matches the instance on both lines of the following source code:

C/C++ code follows
m--;
--m;

In both instances, .operandExpression refers to the variable m. The .kind property is `postfix` in the first instance and `prefix` in the second.

The following pattern matches any postfix decrement operator:

CXM code follows
pattern postfixDecrement { decrementOperator { .kind == `postfix` } };

deleteOperator (pattern)

Matches the C++ delete operator.

Details

This pattern only matches nodes of type expression.

Properties

deleteOperator produces a record that contains the following properties:

Name Type Description
isArray bool true if this instance represents the array delete[] rather than the scalar delete operator.
operandExpression expression The expression (typically a variable) being deleted
hasGlobalScopeModifier bool true if :: precedes delete (specifying global scope)
operatorDeleteFunction functionSymbol The function operator delete

Inherits properties from:

astnode

Example

The deleteOperator matches the following source code:

C++ code follows
delete myPtr;

In this instance, .isArray is false because the scalar version of delete was used. The .operandExpression refers to myPtr.

The following pattern matches any delete operator for an integer pointer:

CXM code follows
pattern deleteIntPointer { deleteOperator { .operandExpression == variableReference { .type == pointerType { .pointerToType == intType } } } };

incrementOperator (pattern)

Matches the increment operators, detecting both prefix (as in ++i) and postfix (i++) variants.

Details

This pattern only matches nodes of type expression.

Properties

incrementOperator produces a record that contains the following properties:

Name Type Description
operandExpression expression The expression being incremented
kind enum `prefix` or `postfix`

Inherits properties from:

astnode

Example

The incrementOperator pattern matches both of the following two lines.

C/C++ code follows
m++;
++m;

In both instances, .operandExpression refers to the variable m. The .kind property is `postfix` in the first instance and `prefix` in the second.

The following custom pattern detects when post-incrementation is used in the update statement of a for loop:

CXM code follows
pattern forLoopPostIncrement { forLoopSimple { .updateStatement == NonNull } as forIncr where forIncr.updateStatement matches simpleStatement { .expression == incrementOperator { .kind == `postfix` } } };

In particular, the forLoopPostIncrement pattern matches the following code,

C/C++ code follows
for ( int i = 0; i < 99; i++ ) {
// Do something.
};

... but it does not match the comparable pre-incrementation:

C/C++ code follows
for ( int i = 0; i < 99; ++i ) {
// Do something.
};

newOperator (pattern)

Matches the C++ new operator.

Details

This pattern only matches nodes of type expression.

Properties

newOperator produces a record that contains the following properties:

Name Type Description
operandType type The type being requested
operatorDeleteFunction functionSymbol? The function operator delete (if there is a chance the constructor might throw); null if there is no such operator
operatorNewFunction functionSymbol The function operator new
placementArguments list<expression>? Argument to placement new; size is not included; null if there are no arguments
arraySizeExpression expression? For array creation, the size of the array; null if the size is not specified
hasGlobalScopeModifier bool true if :: precedes new (specifying global scope)
initializer initializer? The expression evaluated to determine the initial value; null if the array is not initialized. For an array new, repeat this argument for each element.

Inherits properties from:

astnode

Example

The newOperator matches source code such as the following:

C++ code follows
int* myPtr = ::new int();

In this case, the .operandType is an int (which can be matched by the intType pattern) and the .hasGlobalScopeModifier is true.

The following pattern matches uses of the ::new operator (that is, with the global scope modifier ::):

CXM code follows
pattern newIntPtrWithGlobalScope { newOperator { .hasGlobalScopeModifier == true; } };

sizeofOperator (pattern)

Matches instances of the sizeof() operator, regardless of whether the operand is an expression or a type.

See also sizeofOperatorExpression and sizeofOperatorType.

Details

This pattern only matches nodes of type expression.

Properties

sizeofOperator produces a record that contains the following property:

Name Type Description
kind enum sizeofKind `sizeofExpression` or `sizeofType`; see sizeofKind

Inherits properties from:

astnode

throwOperator (pattern)

Matches the C++ throw expression.

Properties

throwOperator produces a record that contains the following properties:

Name Type Description
operandexpression expression? The expression to be thrown by this operator; null if an object is not specified

Inherits properties from:

astnode

Example

The throwOperator matches both of the following lines of code:

C++ code follows
throw e;
throw;

In the former case, .operandExpression refers to e; in the latter case, .operandExpression is null.

As part of memory ownership assignment, some development environments always require pointers to be thrown, while others never do. A checker that enforces either of these conventions might use the following pattern:

CXM code follows
pattern throwNewObject { throwOperator { .operandExpression == newOperator } };

Conversely, to find instances where throw doesn’t use new, the following pattern would be useful:

CXM code follows
pattern throwNonNewObject { throwOperator { .operandExpression != newOperator } };

unaryOperator (pattern)

Matches unary operators—those operators that have only one operand.

Details

This pattern only matches nodes of type expression.

Properties

unaryOperator produces a record that contains the following properties:

Name Type Description
operator enum Can be one of: `+`, `-`, `!`, or `~`.
operandExpression expression The expression being operated on

Inherits properties from:

astnode

Example

The unaryOperator pattern matches source code such as this:

C/C++ code follows
n = -m;
isTrue = !false;

In the first instance, the .operator is `-` and in the second, the .operator is `!`.

Initializers

Patterns in this section belong to the initializer class—or the ctorinit class, in the case of the constructor initializer. They match initializers in the target code.

In many cases, an initializer can look the same as an assigment statement. However, many languages treat initialization as its own, special case. The CodeXM language libraries treat initialization in this way, as well.

aggregateInitializer (pattern)

Matches expressions used to initialize aggregate types such as structs or arrays.

Properties

aggregateInitializer produces a record that contains the following properties:

Name Type Description
hasExplicitBraces bool Whether the initializer is enclosed by braces ( {} ) in the source
semanticIinitializerList list<initializer> The list of initializers used to initialize the subobjects of the aggregate type
syntacticInitializerList list<initializer> The list of initializers used to initialize the subobjects of the aggregate type (at the syntactic level of a source program)
tailInitializer initializer? A tail initializer used to initialize the remaining objects of an aggregate, if one exists; null if there is no tail initializer

Inherits properties from:

astnode

Example

The following code matches aggregateInitializer:

C/C++ code follows
int x[3] = {1, 2};

Both .semanticIinitializerList and .syntacticIinitializerList contain two elements, which are expressionInitializer { .expression == intLiteral }. (In most cases no semantic and syntactic initializers are similar.) The .tailInitializer is a zero initializer, indicating the initializer that the compiler provides to fill out the initialization.

A similar aggregate initializer of a struct:

C/C++ code follows
struct T {
int x;
int y;
}
T t { 2, 1, 3};

This following pattern matches an aggregate initializer with exactly three elements:

CXM code follows
pattern has3Initializers { aggregateInitializer as i where i.syntacticInitializerList.length == 3 };

constructorInitializer (pattern)

Matches cases where a class constructor (C++ only) is used to initialize an object

Properties

constructorInitializer produces a record that contains the following properties:

Name Type Description
constructorFunction functionType The constructor function called to initialize the object
arguments list<initializer> A list of the arguments passed to the constructor

Inherits properties from:

astnode

Example

The constructorInitializer pattern matches the following code:

C/C++ code follows
T t(0);
T t();

... such that the .arguments list holds a single argument (for example, 0) for the first instance and an empty list for the second.

Here is a pattern that matches a constructor that has no arguments:

CXM code follows
pattern defaultConstructor { constructorInitializer as i where i.arguments.length == 3 };

expressionInitializer (pattern)

Matches simple expressions used to initialize scalar objects.

Properties

expressionInitializer produces a record that contains the following properties:

Name Type Description
expression expression The expression that evaluates to a value used to initialize the object

Inherits properties from:

astnode

Example

In the following code:

C/C++ code follows
int x = y + z;

... expressionInitializer matches the right-hand-side of the initialization and captures it via the property .expression.

The unqualified pattern matches any initializer. To match a specific type of initializer—for example, the type of initializer represented by the binary operator (as in the example above)—you could use the following pattern:

CXM code follows
node matches expressionInitializer { .expression == binaryOperator };

unionFieldInitializer (pattern)

Matches union field initializers.

Properties

unionFieldInitializer produces a record that contains the following properties:

Name Type Description
field fieldSymbol The field in the union being initialized
initializer initializer The initializer for this field

Inherits properties from:

astnode

Example

Given the following declaration:

C/C++ code follows
union U {
int i;
float f;
};

... the unionFieldInitializer pattern matches the following code, such that the .field property refers to i, whereas the .initializer property is expressionInitializer:

C/C++ code follows
union U val = { i : 0 };

The following pattern matches a union initialized using int only; that is, it matches the initializer { i: 0 } but does not match { f: 0.0 }:

CXM code follows
pattern UnionIntInitializer { unionFieldInitializer { .initializer == expressionInitializer { .expression == intLiteral } } };

zeroInitializer (pattern)

Matches setting the initial value of an object to zero in the following cases:

  1. A named variable with static or thread-local storage duration that is not subject to constant initialization (since C++14), before any other initialization.

  2. As part of a value-initialization sequence for non-class types, and for members of value-initialized class types that have no constructors, including value initialization of elements of aggregates for which no initializers are provided.

  3. When a character array is initialized with a string literal that is too short, and the remainder of the array is zero-initialized.

Properties

This pattern does not expose any new properties.

Inherits properties from:

astnode

Example

The following pattern:

CXM code follows
node matches zeroInitializer;

... matches the right-hand-sides of the declarations shown in the following source code:

C/C++ code follows
static int x;
// assuming struct T { int x; }
T t = {};
char c[10] = {};

Symbols

These patterns match symbols in the target code.

A symbol is an entity that can have an identifier; for example, a symbol might be a variable, a function, or a field in a record.

In Coverity Analysis, each symbol in a program is its own node in the abstract syntax tree, and is distinct from the identifier that represents it in the source.

Common Properties of Symbols

In addition to the properties that are specific to each pattern, all symbol patterns have the following properties in common:

Name Type Description
identifier string? The string used as an unqualified name for the symbol; null if there is none
mangledName string? The internal “mangled” name used for the symbol (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available
location sourceloc The location where this symbol was declared
type type The C/C++ type declared for this symbol
access enum AccessKeyword The scoping keywords associated with the symbol, such as `public` or `private`
is_file_or_readonly bool true if the symbol has a final specifier (applies only to C++ source)
scopeList list<string> A list of the class names and namespaces that enclose the symbol

enumeratorSymbol (pattern)

Matches enumeration (enum) values.

Details

This pattern only matches nodes of type symbol.

Properties

The .ownerEnumType property lists all possible values of the enumeration.

enumeratorSymbol produces a record that contains the following properties:

Name Type Description
isExplicit bool true if the enumeration value is declared explicitly.
ownerEnumType record[type] Enumerates the identifiers declared in the enum base type
value int The value of this particular instance of a member of the enum

Inherits properties from:

symbol

Example

Given the following sample of source code:

C/C++ code follows
enum myEnum {
enm1 = 1;
enm2 = 3;
specMem
};

... the following CodeXM fragment would match the non-explicit value represented by specMem:

CXM code follows
enumeratorSymbol { .identifier == "specMem" }

fieldSymbol (pattern)

Matches fields of a class (C++ only), struct, or union.

Properties

fieldSymbol produces a record that contains the following properties:

Name Type Description
access enum The access kind of the field; can be `AK_NONE`, `fileprivate`, `internal`, `open`, `private`, `protected`, `protected internal`, `protected private`, or `public`
isBitField bool true if the field is declared as a bit-field
isSignedBitField bool true if the field is declared as a signed bit-field
hasInitializer bool true if the field has an initializer in its declaration
isAnonymous bool true if the bit-field was declared without a name
bitWidth int The bit-width of the field
offset int The offset from the start of the struct
bitOffset int The bit-offset from the start of the struct
isClassStatic bool true if the field is within a static class member
isExplicitLambdaCapture bool true if the field is an explicit capture in a lambda expression
isVolatile bool true if the field is within an object declared with the volatile specifier
isAlignmentAssigned bool true if the variable is aligned
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned

Inherits properties from:

symbol

Example

Given the following source-code declaration:

C/C++ code follows
struct T {
int m;
};

... the fieldSymbol pattern matches field m of the struct t in the following code snippet:

C/C++ code follows
void test( struct T t ) {
t.m++;
};

The following example shows one way to express the pattern:

CXM code follows
node matches variableReference { .variable matches fieldSymbol };

functionSymbol (pattern)

Matches functions.

Details

A function definition and a call to that function each have their own functionSymbol node. The node contains essential information about the function.

This pattern only matches nodes of type symbol.

Properties

functionSymbol produces a record that contains the following properties:

Name Type Description
explicitParameterCount int The number of parameters explicitly declared for this function
functionType record[type] The type of the function; see functionType
hasThis bool (C++) true if the function is a class member method and it is a non-static and unfriended one
isCUDAGlobal bool true if the function is declared as a CUDA __global__ function
isCompilerGenerated bool true if the function is generated by the compiler
isConstMethod bool (C++) true if the function is a const class member method that has been qualified with a const keyword at its end
isConstexpr bool (C++ since C++11) true if the variable was declared as a constexpr
isConstructor bool (C++) true if this function is a constructor of a class
isDefaulted bool (C++) true if this is a special member function that is explicitly or implicitly defaulted
isDeleted bool (C++) true if this is a special member function that is explicitly or implicitly deleted
isDestructor bool (C++) true if this function is a destructor of a class
isExplicitConstructor bool (C++) true if this function is a constructor declared with the keyword explicit
isExplicitlyDefaulted bool (C++) true if this is a special member function that is explicitly defaulted using = default
isExplicitlyDeleted bool (C++) true if this is a special member function that is explicitly deleted using = delete
isInline bool true if this function is inline
isNonstaticMethod bool (C++) true if this function is a non-static class member method
isOverride bool true if this function overrides another function
isPureVirtual bool true if this function is a pure virtual function
isStaticMethod bool (C++) true if this function is a static class member method
isStaticScope bool true if this function is a static function that is not a member
isTemplate bool (C++) true if this function is a template function
isTemplateOrInTemplateClass bool (C++) true if this function is a template function or it is a member method of a template class
isTrailingReturnType bool (C++) true if this function uses a trailing return specifier
isVirtual bool (C++) true if the function is virtual
methodQualifierList enum qualifierEnum Enumerates the qualifiers with which this function was declared; can include `_Atomic`, `const`, `restrict`, and `volatile`; see qualifierEnum
specialMethodKind enum (C++) Specifies the special member kind of this function; can be `None`, `DefaultConstructor`, `CopyConstructor`, `MoveConstructor`, `Constructor`, `CopyAssignment`, `MoveAssignment`, or `Destructor`

Inherits properties from:

symbol

Example

Given the following source-code snippet:

C/C++ code follows
void foo( void );
void test( void ) {
foo();
};

... the following pattern would match the call to foo():

CXM code follows
pattern funCallOfFoo { functionCall { .calledFunction == functionSymbol { .identifier == "foo" } } };

globalVariableSymbol (pattern)

Matches uses of global variables.

Properties

globalVariableSymbol produces a record that contains the following properties:

Name Type Description
hasImplicitSize bool true if the variable is an array with an implicit size; for example, int a[] = {1, 2, 3}
isFunctionStatic bool true if the variable is a static variable in a function
isVolatile bool true if the variable was declared with the volatile specifier
isClassStatic bool true if the variable is a static class member
isConstexpr bool (C++) true if the variable was declared as a constexpr
isCUDAConstant bool true if the variable is declared as a CUDA __constant__
isCUDAManaged bool true if the variable is declared as a CUDA __managed__ variable
isCUDAShared bool true if the variable is declared as a CUDA __shared__ variable
isAlignmentAssigned bool true if the variable is aligned
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned

Inherits properties from:

symbol

Example

The globalVariableSymbol pattern matches variable a in the following code snippet, provided the property .identifier specifies "a":

C/C++ code follows
int a;
void test() {
a++;
};

The following expression matches a in the preceding source code:

CXM code follows
node matches variableReference as v && v.variable matches globalVariableSymbol;

The following code, relying on pattern decomposition, accomplishes the same thing:

CXM code follows
node matches variableReference { .variable matches globalVariableSymbol };

localVariableSymbol (pattern)

Matches uses of local variables.

Properties

localVariableSymbol produces a record that contains the following properties:

Name Type Description
hasImplicitSize bool true if the variable is an array with an implicit size; for example, int a[] = {1, 2, 3}
isVolatile bool true if the variable was declared with the volatile specifier
isRegister bool true if the variable was declared with the register specifier
isCUDAConstant bool true if the variable is declared as a CUDA __constant__
isCUDAManaged bool true if the variable is declared as a CUDA __managed__ variable
isCUDAShared bool true if the variable is declared as a CUDA __shared__ variable
isAlignmentAssigned bool true if the variable is aligned
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned

Inherits properties from:

symbol

Example

The localVariableSymbol pattern matches variable a in the following code snippet, provided the property .identifier specifies "a":

C/C++ code follows
void test() {
int a = 1;
a++;
};

The following pattern limits the more general variableReference to match only local variables:

CXM code follows
pattern variableReferenceLocal { variableReference { .variable == localVariableSymbol } };

parameterSymbol (pattern)

Matches uses of named parameters in function definitions.

Properties

parameterSymbol produces a record that contains the following properties:

Name Type Description
position int The position in the parameter list
isThis bool true if the symbol is the this pointer (applies only to C++ source)
isArray bool true if this parameter was declared as an array with brackets and a minimum size
arrayType arrayType? If the parameter was declared as an array, this property names the associated array type; null if the parameter is not an array
isStaticSizeArray bool true if the keyword static was used when specifying the array size (does not apply if the parameter is not an array)
declaredType type The parameter type as it appears in the function declaration, before dereferencing. In particular, this property can include array types.

Inherits properties from:

symbol

Example

The parameterSymbol pattern matches variable a in the following snippet, provided the .identifier property specifies "a":

C/C++ code follows
void test( int a, int b[100] ) {
a++;
};

The following pattern limits the more general variableReference to match only parameters:

CXM code follows
pattern variableReferenceParameter { variableReference { .variable == parameterSymbol } };

variableSymbol (pattern)

Matches uses of variables, including both global and local variables.

Details

This pattern only matches nodes of type symbol.

Properties

variableSymbol produces a record that contains the following properties:

Name Type Description
scope enum variableScopeEnum The scope of the variable: either `local` or `global`; see variableScopeEnum
hasImplicitSize bool true if the variable is an array with an implicit size; for example, int a[] = {1, 2, 3}
isFunctionStatic bool true if the variable is a static variable in a function
isVolatile bool true if the variable was declared with the volatile specifier
isClassStatic bool true if the variable is a static class member
isConstexpr bool (C++ since C++11) true if the variable was declared as a constexpr
isCUDAConstant bool true if the variable is declared as a CUDA __constant__
isCUDAManaged bool true if the variable is declared as a CUDA __managed__ variable
isCUDAShared bool true if the variable is declared as a CUDA __shared__ variable
isAlignmentAssigned bool true if the variable is aligned
alignmentInBytes int? The alignment of the type, in bytes; null if the type is not aligned

Inherits properties from:

symbol

See Also

globalVariableSymbol, lovalVariableSymbol

Functions

The C/C++ library provides a number of functions to help you handle, and analyze, the target source code.

See the Common Library Reference for descriptions of some general-purpose functions that are available to all language libraries.

Definition Functions

Definition functions retrieve class and enum definitions.

getClassDefinition( classTypeResult )

Gets a classDefinition from the specified classType.

Parameters and Return Value

Name Type Description
classTypeResult classType The classType of a specific class
return value classDefinition? The loaded definition of the specified class type; null if none exists

getEnumDefinition( enumTypeResult )

Gets an enumDefinition from the specified enumType.

Parameters and Return Value

Name Type Description
enumTypeResult enumType The enumType of a specific enum
return value enumDefinition? The loaded definition of the specified enum type; null if none exists

Pattern Functions

Pattern functions return patterns that you can use in your CodeXM searches, just as you use patterns provided by the language library.

aliasTypeOf( typePattern )

Returns a pattern that matches the type specified by typePattern. The pattern will also match declarations that eventually resolve to typePattern.

Parameters and Return Value

Name Type Description
typePattern pattern The type to match
return value pattern Pattern to match type and its aliases

Example

Given the following code snippet:

C/C++ code follows
typedef int foo;
typedef foo bar;
bar x = 10;

... the pattern returned by aliasTypeOf(intType) will match x, because the type bar is an alias for int.

Here is a sample pattern to perform this match:

CXM code follows
node matches expression as e && e.type matches aliasTypeOf(intType);

anyQualifiedTypeOf( typePattern )

Returns a pattern that matches a type (specified by typePattern) provided the type is qualified by const, restrict (C++), or volatile. The pattern will also match qualified declarations that eventually resolve to typePattern.

Parameters and Return Value

Name Type Description
typePattern pattern The type to match
return value pattern Pattern to match type when it is qualified

Example

Given the following code:

C/C++ code follows
const int a = 5; // (1)
const int *b = NULL; // (2)

... the pattern that anyQualifiedTypeOf(intType) returns will match line (1), because this line declares an integer qualified by const. The pattern will not match line (2), because this line declares a pointer, not an integer.

Here is a sample pattern to perform this match:

CXM code follows
node matches expression as e && e.type matches anyQualifiedTypeOf(intType);

arrayOf( typePattern )

Returns a pattern that matches an array of the type specified by typePattern. The pattern will also match arrays of types that eventually resolve to typePattern.

Parameters and Return Value

Name Type Description
typePattern pattern The type to match
return value pattern Pattern to match an array of type

Example

Given the following code snippet:

C/C++ code follows
typedef int foo;
foo x[10];
x[0] = 1;

... the pattern returned by arrayOf(intType) will match x, because x is an array of elements of type foo, and foo is in turn an alias for int.

Here is a sample pattern to perform this match:

CXM code follows
node matches expression as e && e.type matches arrayOf(intType);

constOf( typePattern )

Returns a pattern that matches a type (specified by typePattern), provided the type is declared to be const. The pattern will also match declarations that eventually resolve to typePattern.

Parameters and Return Value

Name Type Description
typePattern pattern The type to match
return value pattern Pattern to match constants of type

Example

Given the following code snippet:

C/C++ code follows
typedef const int foo;
foo x = 10;

... the pattern returned by constOf(intType) will match x, because x is of type foo, and foo is an alias for const int.

Here is a sample pattern to perform this match:

CXM code follows
node matches expression as e && e.type matches constOf( intType );

pointerTo( typePattern )

Returns a pattern that matches a pointer to the type specified by typePattern. The pattern will also match pointers to types that eventually resolve to typePattern.

Parameters and Return Value

Name Type Description
typePattern pattern The type to match when it is pointed to
return value pattern Pattern to match a pointer to type

Example

Given the following code snippet:

C++ code follows
typedef int foo;
foo *x = nullptr;

... the pattern returned by pointerTo(intType) will match x, because x points to the type foo, and foo is an alias for int.

Here is a sample pattern to perform this match:

CXM code follows
node matches expression as e && e.type matches pointerTo(intType);

volatileOf( typePattern )

Returns a pattern that matches a type (specified by typePattern), provided the type is declared to be volatile. The pattern will also match declarations that eventually resolve to typePattern.

Parameters and Return Value

Name Type Description
typePattern pattern The type to match
return value pattern Pattern to match volatile instances of type

Example

Given the following code snippet

C/C++ code follows
typedef volatile int foo;
foo x = 10;

... the pattern returned by volatileOf(intType) will match x, because x is of type foo, and foo is an alias for volatile int.

Here is a sample pattern to perform this match:

CXM code follows
node matches expression as e && e.type matches volatileOf( intType );

Type Functions

Type functions handle elaborated types.

hasBaseType( typeName )

For pointerType, arrayType, typeQualifier, typedefType, or deducedType, returns the base type of these types; that is, the type a pointer points to, the type contained in an array, and so on.

This function is applied recursively, so that like the pattern functions, it can resolve declarations that resolve to typeName.

Parameters and Return Value

Name Type Description
typeName type The type to match
return value type The base type without pointers, arrays, or qualifiers

Example

The following code defines the integer type sideLength, and then declares a pointer to the new type:

C/C++ code follows
typedef int sideLength;
Length *sideLength;

The following pattern uses hasBaseType() to check whether the type passed in (ty) resolves to an integer. It would match the sample above.

CXM code follows
pattern isInteger { type as ty where ( hasBaseType( ty ) matches intType ) };

The hasBaseType() function can also check whether two types are the same, as in the following function declaration shows:

CXM code follows
function typeIsTheSame( type1, type2 ) : bool -> hasBaseType( type1 ) == hasBaseType( type2 );

Decomposing Functions

Decomposing functions deal explicitly with managing casts and qualifiers.

getQualifiers( typeName )

Returns a set that contains the qualifiers on a type.

Parameters and Return Value

Name Type Description
typeName type The type to match
return value set<qualifiers> A set whose members represent the qualifiers applied to the type

Example

Given the following code snippet:

C/C++ code follows
volatile int a;
const char *b;

The following pattern would detect the volatile qualifier:

CXM code follows
pattern useVolatileVariable { pattern { | variableReference as vr -> vr.type | pointerDereference as pd -> pd.type | memberReference as mr -> mr.field.type | subscriptReference as sr -> sr.type } as t where getQualifiers( t ).contains( `volatile` ) };

qualifiersOf( typeName )

Returns a list of the qualifiers on a type.

Parameters and Return Value

The return type is list<qualifierEnum>.

Example

This source code sample has declarations that are qualified:

C/C++ code follows
volatile int a;
const char *b;

You could use the following pattern to detect the `volatile` qualifier:

CXM code follows
pattern useVolatileVariable { pattern { | variableReference as vr -> vr.type | pointerDereference as pd -> pd.type | memberReference as mr -> mr.field.type | subscriptReference as sr -> sr.type } as t where getQualifiersOf(t).contains(`volatile`) };

stripCasts( expressionString )

Strips an outermost cast, if present, to return the underlying expression.

If the expression consists of subexpressions that themselves are being cast, those casts are also stripped.

Parameters and Return Value

Name Type Description
expressionString expression The expression to strip casts from
return value expression The expression without casts

Example

Given the following source code:

C/C++ code follows
int *ptr;
void *a = (void *) ptr;

... the following pattern uses stripCasts() to match *a:

CXM code follows
pattern intPointerReference { stripCasts( expr ) matches variableReference { .type == pointerType { .pointerToType == intType; } } };

stripQualifiers( typeName )

Returns the base type that is wrapped by typeQualifier, typedefType, or deducedType.

This is different from hasBaseType(), as it does not strip pointerType or arrayType.

Parameters and Return Value

Name Type Description
typeName type The type to match
return value type The base type without qualifiers

Example

To strip qualifiers on a specific type, to any depth, you might define a pattern such as the following:

CXM code follows
pattern nonCharPointer { pointerType as pt where ! ( stripQualifiers( pt.pointerToType ) ) matches charType };