[PATCH] D52782: [clang-tidy] Sequence statements with multiple parents correctly (PR39149)

Martin Böhme via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 2 07:39:53 PDT 2018


mboehme created this revision.
Herald added subscribers: cfe-commits, xazax.hun.

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


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D52782

Files:
  clang-tidy/bugprone/UseAfterMoveCheck.cpp
  clang-tidy/utils/ExprSequence.cpp
  clang-tidy/utils/ExprSequence.h
  test/clang-tidy/bugprone-use-after-move.cpp


Index: test/clang-tidy/bugprone-use-after-move.cpp
===================================================================
--- test/clang-tidy/bugprone-use-after-move.cpp
+++ test/clang-tidy/bugprone-use-after-move.cpp
@@ -1195,6 +1195,18 @@
   }
 }
 
+// Null statements (and some other statements) in templates 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();
Index: clang-tidy/utils/ExprSequence.h
===================================================================
--- clang-tidy/utils/ExprSequence.h
+++ clang-tidy/utils/ExprSequence.h
@@ -69,8 +69,8 @@
 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;
@@ -94,6 +94,7 @@
   const Stmt *resolveSyntheticStmt(const Stmt *S) const;
 
   ASTContext *Context;
+  const Stmt *Root;
 
   llvm::DenseMap<const Stmt *, const Stmt *> SyntheticStmtSourceMap;
 };
Index: clang-tidy/utils/ExprSequence.cpp
===================================================================
--- clang-tidy/utils/ExprSequence.cpp
+++ clang-tidy/utils/ExprSequence.cpp
@@ -63,8 +63,9 @@
 }
 }
 
-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;
   }
@@ -99,6 +100,11 @@
 
 const Stmt *ExprSequence::getSequenceSuccessor(const Stmt *S) const {
   for (const Stmt *Parent : getParentStmts(S, Context)) {
+    // For statements that have 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)
Index: clang-tidy/bugprone/UseAfterMoveCheck.cpp
===================================================================
--- clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -102,8 +102,9 @@
   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);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52782.167946.patch
Type: text/x-patch
Size: 3378 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181002/95955eee/attachment.bin>


More information about the cfe-commits mailing list