Skip to content

Commit

Permalink
[clang-tidy] Sequence statements with multiple parents correctly (PR3…
Browse files Browse the repository at this point in the history
…9149)

Summary:
Before this fix, the bugprone-use-after-move check could incorrectly
conclude that a use and move in a function template were not sequenced.
For details, see

https://bugs.llvm.org/show_bug.cgi?id=39149

Reviewers: alexfh, hokein, aaron.ballman, JonasToth

Reviewed By: aaron.ballman

Subscribers: xazax.hun, cfe-commits

Tags: #clang-tools-extra

Differential Revision: https://reviews.llvm.org/D52782

llvm-svn: 343768
  • Loading branch information
martinboehme committed Oct 4, 2018
1 parent e94c869 commit 764ad2f
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
5 changes: 3 additions & 2 deletions clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
Expand Up @@ -102,8 +102,9 @@ bool UseAfterMoveFinder::find(Stmt *FunctionBody, const Expr *MovingCall,
if (!TheCFG)
return false;

Sequence.reset(new ExprSequence(TheCFG.get(), Context));
BlockMap.reset(new StmtToBlockMap(TheCFG.get(), Context));
Sequence =
llvm::make_unique<ExprSequence>(TheCFG.get(), FunctionBody, Context);
BlockMap = llvm::make_unique<StmtToBlockMap>(TheCFG.get(), Context);
Visited.clear();

const CFGBlock *Block = BlockMap->blockContainingStmt(MovingCall);
Expand Down
10 changes: 8 additions & 2 deletions clang-tools-extra/clang-tidy/utils/ExprSequence.cpp
Expand Up @@ -63,8 +63,9 @@ bool isDescendantOrEqual(const Stmt *Descendant, const Stmt *Ancestor,
}
}

ExprSequence::ExprSequence(const CFG *TheCFG, ASTContext *TheContext)
: Context(TheContext) {
ExprSequence::ExprSequence(const CFG *TheCFG, const Stmt *Root,
ASTContext *TheContext)
: Context(TheContext), Root(Root) {
for (const auto &SyntheticStmt : TheCFG->synthetic_stmts()) {
SyntheticStmtSourceMap[SyntheticStmt.first] = SyntheticStmt.second;
}
Expand Down Expand Up @@ -99,6 +100,11 @@ bool ExprSequence::potentiallyAfter(const Stmt *After,

const Stmt *ExprSequence::getSequenceSuccessor(const Stmt *S) const {
for (const Stmt *Parent : getParentStmts(S, Context)) {
// If a statement has multiple parents, make sure we're using the parent
// that lies within the sub-tree under Root.
if (!isDescendantOrEqual(Parent, Root, Context))
continue;

if (const auto *BO = dyn_cast<BinaryOperator>(Parent)) {
// Comma operator: Right-hand side is sequenced after the left-hand side.
if (BO->getLHS() == S && BO->getOpcode() == BO_Comma)
Expand Down
5 changes: 3 additions & 2 deletions clang-tools-extra/clang-tidy/utils/ExprSequence.h
Expand Up @@ -69,8 +69,8 @@ namespace utils {
class ExprSequence {
public:
/// Initializes this `ExprSequence` with sequence information for the given
/// `CFG`.
ExprSequence(const CFG *TheCFG, ASTContext *TheContext);
/// `CFG`. `Root` is the root statement the CFG was built from.
ExprSequence(const CFG *TheCFG, const Stmt *Root, ASTContext *TheContext);

/// Returns whether \p Before is sequenced before \p After.
bool inSequence(const Stmt *Before, const Stmt *After) const;
Expand All @@ -94,6 +94,7 @@ class ExprSequence {
const Stmt *resolveSyntheticStmt(const Stmt *S) const;

ASTContext *Context;
const Stmt *Root;

llvm::DenseMap<const Stmt *, const Stmt *> SyntheticStmtSourceMap;
};
Expand Down
12 changes: 12 additions & 0 deletions clang-tools-extra/test/clang-tidy/bugprone-use-after-move.cpp
Expand Up @@ -1195,6 +1195,18 @@ void ifWhileAndSwitchSequenceInitDeclAndCondition() {
}
}

// Some statements in templates (e.g. null, break and continue statements) may
// be shared between the uninstantiated and instantiated versions of the
// template and therefore have multiple parents. Make sure the sequencing code
// handles this correctly.
template <class> void nullStatementSequencesInTemplate() {
int c = 0;
(void)c;
;
std::move(c);
}
template void nullStatementSequencesInTemplate<int>();

namespace PR33020 {
class D {
~D();
Expand Down

0 comments on commit 764ad2f

Please sign in to comment.