Skip to content

Commit 9aff8ad

Browse files
committed
Fix use-after-poison in UsefulAnalyzer's reverse CFG walk.
UsefulAnalyzer::AnalyzeCFGBlock walks a block's CFGElements in reverse, but started the iterator at block.end() and dereferenced it, using block.begin() - 1 as the loop sentinel. Both are invalid iterators: end() is one past the last element and begin() - 1 is out of bounds. Reading a CFGElement's PointerIntPair through them is undefined; under -fsanitize=address the container annotations on the element storage turn it into a use-after-poison (e.g. Analyses/UsefulForward.cpp). Use rbegin()/rend() instead: a plain forward walk over reverse iterators visits the same elements in the same order without ever dereferencing end() or forming the out-of-bounds sentinel.
1 parent aa9a866 commit 9aff8ad

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

lib/Differentiator/UsefulAnalyzer.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "UsefulAnalyzer.h"
22

3+
#include "clang/AST/Stmt.h"
4+
35
using namespace clang;
46

57
namespace clad {
@@ -46,12 +48,11 @@ static void mergeVarsData(std::set<const clang::VarDecl*>* targetData,
4648
}
4749

4850
void UsefulAnalyzer::AnalyzeCFGBlock(const CFGBlock& block) {
49-
for (auto ib = block.end(); ib != block.begin() - 1; ib--) {
50-
if (ib->getKind() == clang::CFGElement::Statement) {
51-
52-
const clang::Stmt* S = ib->castAs<clang::CFGStmt>().getStmt();
51+
for (const auto* it = block.rbegin(); it != block.rend(); ++it) {
52+
if (it->getKind() == clang::CFGElement::Statement) {
53+
const clang::Stmt* S = it->castAs<clang::CFGStmt>().getStmt();
5354
// The const_cast is inevitable, since there is no
54-
// ConstRecusiveASTVisitor.
55+
// ConstRecursiveASTVisitor.
5556
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
5657
TraverseStmt(const_cast<clang::Stmt*>(S));
5758
}

0 commit comments

Comments
 (0)