clang-tools 20.0.0git
|
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 . | |
Provides information about the evaluation order of (sub-)expressions within a CFGBlock
.
While a CFGBlock
does contain individual CFGElement
s for some sub-expressions, the order in which those CFGElement
s 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
SequenceChecker
out into a header file (i.e. making it part of the API),SequenceChecker
on Sema
, andSequenceChecker
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.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.
Stmt
s are known to be sequenced before or after their siblings. For example, the Stmt
s that make up a CompoundStmt
are all sequenced relative to each other. The function getSequenceSuccessor()
implements these sequencing rules. Definition at line 66 of file ExprSequence.h.
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.
bool clang::tidy::utils::ExprSequence::inSequence | ( | const Stmt * | Before, |
const Stmt * | After | ||
) | const |
Returns whether Before
is sequenced before After
.
Definition at line 92 of file ExprSequence.cpp.
References clang::tidy::utils::getParentStmts(), inSequence(), and Parent.
Referenced by inSequence(), and 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 164 of file ExprSequence.cpp.
References inSequence().