clang-tools 22.0.0git
clang::tidy::utils::ExprSequence Class Reference

Provides information about the evaluation order of (sub-)expressions within a CFGBlock. More...

#include <ExprSequence.h>

Public Member Functions

 ExprSequence (const CFG *TheCFG, const Stmt *Root, ASTContext *TheContext)
 Initializes this ExprSequence with sequence information for the given CFG.
bool inSequence (const Stmt *Before, const Stmt *After) const
 Returns whether Before is sequenced before After.
bool potentiallyAfter (const Stmt *After, const Stmt *Before) const
 Returns whether After can potentially be evaluated after Before.

Detailed Description

Provides information about the evaluation order of (sub-)expressions within a CFGBlock.

While a CFGBlock does contain individual CFGElements for some sub-expressions, the order in which those CFGElements appear reflects only one possible order in which the sub-expressions may be evaluated. However, we want to warn if any of the potential evaluation orders can lead to a use-after-move, not just the one contained in the CFGBlock.

This class implements only a simplified version of the C++ sequencing rules. The main limitation is that we do not distinguish between value computation and side effect – see the "Implementation" section for more details.

Note: SequenceChecker from SemaChecking.cpp does a similar job (and much more thoroughly), but using it would require

  • Pulling SequenceChecker out into a header file (i.e. making it part of the API),
  • Removing the dependency of SequenceChecker on Sema, and
  • (Probably) modifying SequenceChecker to make it suitable to be used in this context. For the moment, it seems preferable to re-implement our own version of sequence checking that is special-cased to what we need here.

Implementation

ExprSequence uses two types of sequencing edges between nodes in the AST:

  • Every Stmt is assumed to be sequenced after its children. This is overly optimistic because the standard only states that value computations of operands are sequenced before the value computation of the operator, making no guarantees about side effects (in general).

    For our purposes, this rule is sufficient, however, because this check is interested in operations on objects, which are generally performed through function calls (whether explicit and implicit). Function calls guarantee that the value computations and side effects for all function arguments are sequenced before the execution of the function.

  • In addition, some Stmts are known to be sequenced before or after their siblings. For example, the Stmts that make up a CompoundStmtare all sequenced relative to each other. The function getSequenceSuccessor() implements these sequencing rules.

Definition at line 66 of file ExprSequence.h.

Constructor & Destructor Documentation

◆ ExprSequence()

clang::tidy::utils::ExprSequence::ExprSequence ( const CFG * TheCFG,
const Stmt * Root,
ASTContext * TheContext )

Initializes this ExprSequence with sequence information for the given CFG.

Root is the root statement the CFG was built from.

Definition at line 84 of file ExprSequence.cpp.

Member Function Documentation

◆ inSequence()

bool clang::tidy::utils::ExprSequence::inSequence ( const Stmt * Before,
const Stmt * After ) const

Returns whether Before is sequenced before After.

Definition at line 90 of file ExprSequence.cpp.

References clang::tidy::utils::getParentStmts(), and inSequence().

Referenced by clang::tidy::cppcoreguidelines::NoSuspendWithLockCheck::check(), inSequence(), and potentiallyAfter().

◆ potentiallyAfter()

bool clang::tidy::utils::ExprSequence::potentiallyAfter ( const Stmt * After,
const Stmt * Before ) const

Returns whether After can potentially be evaluated after Before.

This is exactly equivalent to !inSequence(After, Before) but makes some conditions read more naturally.

Definition at line 162 of file ExprSequence.cpp.

References inSequence().


The documentation for this class was generated from the following files: