Skip to content

Commit 2b9abf0

Browse files
committed
Revert "[analyzer] Handle [[assume(cond)]] as __builtin_assume(cond) (#116462)"
This reverts commit 89da344. Reason: buildbot breakages e.g., https://lab.llvm.org/buildbot/#/builders/55/builds/4556 (for which the reverted patch is the only code change)
1 parent 527595f commit 2b9abf0

File tree

8 files changed

+25
-218
lines changed

8 files changed

+25
-218
lines changed

clang/include/clang/AST/AttrIterator.h

-12
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "clang/Basic/LLVM.h"
1717
#include "llvm/ADT/ADL.h"
1818
#include "llvm/ADT/SmallVector.h"
19-
#include "llvm/ADT/iterator_range.h"
2019
#include "llvm/Support/Casting.h"
2120
#include <cassert>
2221
#include <cstddef>
@@ -125,17 +124,6 @@ inline auto *getSpecificAttr(const Container &container) {
125124
return It != specific_attr_end<IterTy>(container) ? *It : nullptr;
126125
}
127126

128-
template <typename SpecificAttr, typename Container>
129-
inline auto getSpecificAttrs(const Container &container) {
130-
using ValueTy = llvm::detail::ValueOfRange<Container>;
131-
using ValuePointeeTy = std::remove_pointer_t<ValueTy>;
132-
using IterTy = std::conditional_t<std::is_const_v<ValuePointeeTy>,
133-
const SpecificAttr, SpecificAttr>;
134-
auto Begin = specific_attr_begin<IterTy>(container);
135-
auto End = specific_attr_end<IterTy>(container);
136-
return llvm::make_range(Begin, End);
137-
}
138-
139127
} // namespace clang
140128

141129
#endif // LLVM_CLANG_AST_ATTRITERATOR_H

clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h

-4
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,6 @@ class ExprEngine {
498498
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
499499
ExplodedNodeSet &Dst);
500500

501-
/// VisitAttributedStmt - Transfer function logic for AttributedStmt
502-
void VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred,
503-
ExplodedNodeSet &Dst);
504-
505501
/// VisitLogicalExpr - Transfer function logic for '&&', '||'
506502
void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
507503
ExplodedNodeSet &Dst);

clang/lib/Analysis/CFG.cpp

+20-52
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ class reverse_children {
433433
ArrayRef<Stmt *> children;
434434

435435
public:
436-
reverse_children(Stmt *S, ASTContext &Ctx);
436+
reverse_children(Stmt *S);
437437

438438
using iterator = ArrayRef<Stmt *>::reverse_iterator;
439439

@@ -443,47 +443,28 @@ class reverse_children {
443443

444444
} // namespace
445445

446-
reverse_children::reverse_children(Stmt *S, ASTContext &Ctx) {
447-
switch (S->getStmtClass()) {
448-
case Stmt::CallExprClass: {
449-
children = cast<CallExpr>(S)->getRawSubExprs();
446+
reverse_children::reverse_children(Stmt *S) {
447+
if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
448+
children = CE->getRawSubExprs();
450449
return;
451450
}
452-
453-
// Note: Fill in this switch with more cases we want to optimize.
454-
case Stmt::InitListExprClass: {
455-
InitListExpr *IE = cast<InitListExpr>(S);
456-
children = llvm::ArrayRef(reinterpret_cast<Stmt **>(IE->getInits()),
457-
IE->getNumInits());
458-
return;
451+
switch (S->getStmtClass()) {
452+
// Note: Fill in this switch with more cases we want to optimize.
453+
case Stmt::InitListExprClass: {
454+
InitListExpr *IE = cast<InitListExpr>(S);
455+
children = llvm::ArrayRef(reinterpret_cast<Stmt **>(IE->getInits()),
456+
IE->getNumInits());
457+
return;
458+
}
459+
default:
460+
break;
459461
}
460-
case Stmt::AttributedStmtClass: {
461-
auto *AS = cast<AttributedStmt>(S);
462462

463-
// for an attributed stmt, the "children()" returns only the NullStmt
464-
// (;) but semantically the "children" are supposed to be the
465-
// expressions _within_ i.e. the two square brackets i.e. [[ HERE ]]
466-
// so we add the subexpressions first, _then_ add the "children"
463+
// Default case for all other statements.
464+
llvm::append_range(childrenBuf, S->children());
467465

468-
for (const auto *Attr : AS->getAttrs()) {
469-
if (const auto *AssumeAttr = dyn_cast<CXXAssumeAttr>(Attr)) {
470-
Expr *AssumeExpr = AssumeAttr->getAssumption();
471-
if (!AssumeExpr->HasSideEffects(Ctx)) {
472-
childrenBuf.push_back(AssumeExpr);
473-
}
474-
}
475-
// Visit the actual children AST nodes.
476-
// For CXXAssumeAttrs, this is always a NullStmt.
477-
llvm::append_range(childrenBuf, AS->children());
478-
children = childrenBuf;
479-
}
480-
return;
481-
}
482-
default:
483-
// Default case for all other statements.
484-
llvm::append_range(childrenBuf, S->children());
485-
children = childrenBuf;
486-
}
466+
// This needs to be done *after* childrenBuf has been populated.
467+
children = childrenBuf;
487468
}
488469

489470
namespace {
@@ -2450,7 +2431,7 @@ CFGBlock *CFGBuilder::VisitChildren(Stmt *S) {
24502431

24512432
// Visit the children in their reverse order so that they appear in
24522433
// left-to-right (natural) order in the CFG.
2453-
reverse_children RChildren(S, *Context);
2434+
reverse_children RChildren(S);
24542435
for (Stmt *Child : RChildren) {
24552436
if (Child)
24562437
if (CFGBlock *R = Visit(Child))
@@ -2466,7 +2447,7 @@ CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) {
24662447
}
24672448
CFGBlock *B = Block;
24682449

2469-
reverse_children RChildren(ILE, *Context);
2450+
reverse_children RChildren(ILE);
24702451
for (Stmt *Child : RChildren) {
24712452
if (!Child)
24722453
continue;
@@ -2501,14 +2482,6 @@ static bool isFallthroughStatement(const AttributedStmt *A) {
25012482
return isFallthrough;
25022483
}
25032484

2504-
static bool isCXXAssumeAttr(const AttributedStmt *A) {
2505-
bool hasAssumeAttr = hasSpecificAttr<CXXAssumeAttr>(A->getAttrs());
2506-
2507-
assert((!hasAssumeAttr || isa<NullStmt>(A->getSubStmt())) &&
2508-
"expected [[assume]] not to have children");
2509-
return hasAssumeAttr;
2510-
}
2511-
25122485
CFGBlock *CFGBuilder::VisitAttributedStmt(AttributedStmt *A,
25132486
AddStmtChoice asc) {
25142487
// AttributedStmts for [[likely]] can have arbitrary statements as children,
@@ -2524,11 +2497,6 @@ CFGBlock *CFGBuilder::VisitAttributedStmt(AttributedStmt *A,
25242497
appendStmt(Block, A);
25252498
}
25262499

2527-
if (isCXXAssumeAttr(A) && asc.alwaysAdd(*this, A)) {
2528-
autoCreateBlock();
2529-
appendStmt(Block, A);
2530-
}
2531-
25322500
return VisitChildren(A);
25332501
}
25342502

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

+1-7
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
19411941
// to be explicitly evaluated.
19421942
case Stmt::PredefinedExprClass:
19431943
case Stmt::AddrLabelExprClass:
1944+
case Stmt::AttributedStmtClass:
19441945
case Stmt::IntegerLiteralClass:
19451946
case Stmt::FixedPointLiteralClass:
19461947
case Stmt::CharacterLiteralClass:
@@ -1971,13 +1972,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
19711972
break;
19721973
}
19731974

1974-
case Stmt::AttributedStmtClass: {
1975-
Bldr.takeNodes(Pred);
1976-
VisitAttributedStmt(cast<AttributedStmt>(S), Pred, Dst);
1977-
Bldr.addNodes(Dst);
1978-
break;
1979-
}
1980-
19811975
case Stmt::CXXDefaultArgExprClass:
19821976
case Stmt::CXXDefaultInitExprClass: {
19831977
Bldr.takeNodes(Pred);

clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -794,18 +794,17 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex,
794794

795795
// Find the predecessor block.
796796
ProgramStateRef SrcState = state;
797-
798797
for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
799-
auto Edge = N->getLocationAs<BlockEdge>();
800-
if (!Edge.has_value()) {
798+
ProgramPoint PP = N->getLocation();
799+
if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
801800
// If the state N has multiple predecessors P, it means that successors
802801
// of P are all equivalent.
803802
// In turn, that means that all nodes at P are equivalent in terms
804803
// of observable behavior at N, and we can follow any of them.
805804
// FIXME: a more robust solution which does not walk up the tree.
806805
continue;
807806
}
808-
SrcBlock = Edge->getSrc();
807+
SrcBlock = PP.castAs<BlockEdge>().getSrc();
809808
SrcState = N->getState();
810809
break;
811810
}

clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp

-18
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "clang/AST/AttrIterator.h"
1413
#include "clang/AST/DeclCXX.h"
1514
#include "clang/AST/ParentMap.h"
1615
#include "clang/AST/StmtCXX.h"
@@ -1201,20 +1200,3 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred,
12011200
// FIXME: Move all post/pre visits to ::Visit().
12021201
getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this);
12031202
}
1204-
1205-
void ExprEngine::VisitAttributedStmt(const AttributedStmt *A,
1206-
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1207-
ExplodedNodeSet CheckerPreStmt;
1208-
getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
1209-
1210-
ExplodedNodeSet EvalSet;
1211-
StmtNodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
1212-
1213-
for (const auto *Attr : getSpecificAttrs<CXXAssumeAttr>(A->getAttrs())) {
1214-
for (ExplodedNode *N : CheckerPreStmt) {
1215-
Visit(Attr->getAssumption(), N, EvalSet);
1216-
}
1217-
}
1218-
1219-
getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, A, *this);
1220-
}

clang/test/Analysis/cxx23-assume-attribute.cpp

-58
This file was deleted.

clang/test/Analysis/out-of-bounds-new.cpp

+1-63
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -verify %s \
2-
// RUN: -analyzer-checker=unix,core,alpha.security.ArrayBoundV2,debug.ExprInspection
3-
4-
template <typename T> void clang_analyzer_dump(T);
5-
template <typename T> void clang_analyzer_value(T);
6-
void clang_analyzer_eval(bool);
7-
template <typename T>
8-
void clang_analyzer_explain(T);
1+
// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s
92

103
// Tests doing an out-of-bounds access after the end of an array using:
114
// - constant integer index
@@ -187,58 +180,3 @@ int test_reference_that_might_be_after_the_end(int idx) {
187180
return ref;
188181
}
189182

190-
// From: https://github.com/llvm/llvm-project/issues/100762
191-
extern int arrOf10[10];
192-
void using_builtin(int x) {
193-
__builtin_assume(x > 101); // CallExpr
194-
arrOf10[x] = 404; // expected-warning {{Out of bound access to memory}}
195-
}
196-
197-
void using_assume_attr(int ax) {
198-
[[assume(ax > 100)]]; // NullStmt with an "assume" attribute.
199-
arrOf10[ax] = 405; // expected-warning {{Out of bound access to memory}}
200-
}
201-
202-
void using_many_assume_attr(int yx) {
203-
[[assume(yx > 104), assume(yx > 200), assume(yx < 300)]]; // NullStmt with an attribute
204-
arrOf10[yx] = 406; // expected-warning{{Out of bound access to memory}}
205-
}
206-
207-
208-
int using_builtin_assume_has_no_sideeffects(int y) {
209-
// We should not apply sideeffects of the argument of [[assume(...)]].
210-
// "y" should not get incremented;
211-
__builtin_assume(++y == 43); // expected-warning {{assumption is ignored because it contains (potential) side-effects}}
212-
clang_analyzer_eval(y == 42); // expected-warning {{FALSE}}
213-
return y;
214-
}
215-
216-
217-
218-
int using_assume_attr_has_no_sideeffects(int y) {
219-
220-
// We should not apply sideeffects of the argument of [[assume(...)]].
221-
// "y" should not get incremented;
222-
[[assume(++y == 43)]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}}
223-
224-
clang_analyzer_eval(y == 42); // expected-warning {{TRUE}} expected-warning {{FALSE}} FIXME: This should be only TRUE.
225-
226-
clang_analyzer_eval(y == 43); // expected-warning {{FALSE}} expected-warning {{TRUE}} FIXME: This should be only FALSE.
227-
228-
return y;
229-
}
230-
231-
232-
int using_builtinassume_has_no_sideeffects(int u) {
233-
// We should not apply sideeffects of the argument of __builtin_assume(...)
234-
// "u" should not get incremented;
235-
__builtin_assume(++u == 43); // expected-warning {{assumption is ignored because it contains (potential) side-effects}}
236-
237-
// FIXME: evaluate this to true
238-
clang_analyzer_eval(u == 42); // expected-warning {{FALSE}} current behavior
239-
240-
// FIXME: evaluate this to false
241-
clang_analyzer_eval(u == 43); // expected-warning {{TRUE}} current behavior
242-
243-
return u;
244-
}

0 commit comments

Comments
 (0)