Skip to content

Commit c429df6

Browse files
committed
Use the eager assumption tags only if the decision was ambiguous
1 parent f5815b9 commit c429df6

File tree

5 files changed

+29
-40
lines changed

5 files changed

+29
-40
lines changed

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3771,24 +3771,29 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
37713771
SVal V = state->getSVal(Ex, Pred->getLocationContext());
37723772
std::optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>();
37733773
if (SEV && SEV->isExpression()) {
3774-
const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
3775-
geteagerlyAssumeBinOpBifurcationTags();
3776-
37773774
ProgramStateRef StateTrue, StateFalse;
37783775
std::tie(StateTrue, StateFalse) = state->assume(*SEV);
37793776

3777+
const ProgramPointTag *EagerTrueTag = nullptr;
3778+
const ProgramPointTag *EagerFalseTag = nullptr;
3779+
3780+
// Use the eager assumption tags if the choice was ambiguous.
3781+
if (StateTrue && StateFalse)
3782+
std::tie(EagerTrueTag, EagerFalseTag) =
3783+
geteagerlyAssumeBinOpBifurcationTags();
3784+
37803785
// First assume that the condition is true.
37813786
if (StateTrue) {
37823787
SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
37833788
StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
3784-
Bldr.generateNode(Ex, Pred, StateTrue, tags.first);
3789+
Bldr.generateNode(Ex, Pred, StateTrue, EagerTrueTag);
37853790
}
37863791

37873792
// Next, assume that the condition is false.
37883793
if (StateFalse) {
37893794
SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
37903795
StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
3791-
Bldr.generateNode(Ex, Pred, StateFalse, tags.second);
3796+
Bldr.generateNode(Ex, Pred, StateFalse, EagerFalseTag);
37923797
}
37933798
}
37943799
}

clang/test/Analysis/assuming-unsigned-ge-0.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
// RUN: -analyzer-checker=core -verify %s
33

44
int assuming_unsigned_ge_0(unsigned arg) {
5-
// TODO This testcase demonstrates the current incorrect behavior of Clang
6-
// Static Analyzer: here 'arg' is unsigned, so "arg >= 0" is not a fresh
7-
// assumption, but it still appears in the diagnostics as if it's fresh:
8-
// expected-note@+2 {{Assuming 'arg' is >= 0}}
5+
// expected-note@+2 {{'arg' is >= 0}}
96
// expected-note@+1 {{Taking false branch}}
107
if (arg < 0)
118
return 0;

clang/test/Analysis/cast-value-notes.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,8 @@ void evalNonNullParamNonNullReturnReference(const Shape &S) {
168168
// expected-note@-2 {{Taking true branch}}
169169

170170
(void)(1 / !C);
171-
// expected-note@-1 {{'C' is non-null}}
172-
// expected-note@-2 {{Division by zero}}
173-
// expected-warning@-3 {{Division by zero}}
171+
// expected-note@-1 {{Division by zero}}
172+
// expected-warning@-2 {{Division by zero}}
174173
}
175174
}
176175

@@ -226,9 +225,8 @@ void evalNonNullParamNonNullReturn(const Shape *S) {
226225
// expected-note@-2 {{Taking true branch}}
227226

228227
(void)(1 / !C);
229-
// expected-note@-1 {{'C' is non-null}}
230-
// expected-note@-2 {{Division by zero}}
231-
// expected-warning@-3 {{Division by zero}}
228+
// expected-note@-1 {{Division by zero}}
229+
// expected-warning@-2 {{Division by zero}}
232230
}
233231
}
234232

@@ -243,9 +241,8 @@ void evalNonNullParamNullReturn(const Shape *S) {
243241
// expected-note@-4 {{Taking true branch}}
244242

245243
(void)(1 / !T);
246-
// expected-note@-1 {{'T' is non-null}}
247-
// expected-note@-2 {{Division by zero}}
248-
// expected-warning@-3 {{Division by zero}}
244+
// expected-note@-1 {{Division by zero}}
245+
// expected-warning@-2 {{Division by zero}}
249246
}
250247
}
251248

@@ -265,9 +262,8 @@ void evalZeroParamNonNullReturnPointer(const Shape *S) {
265262
// expected-note@-2 {{'C' initialized here}}
266263

267264
(void)(1 / !C);
268-
// expected-note@-1 {{'C' is non-null}}
269-
// expected-note@-2 {{Division by zero}}
270-
// expected-warning@-3 {{Division by zero}}
265+
// expected-note@-1 {{Division by zero}}
266+
// expected-warning@-2 {{Division by zero}}
271267
}
272268

273269
void evalZeroParamNonNullReturn(const Shape &S) {

clang/test/Analysis/cast-value-state-dump.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ void evalNonNullParamNonNullReturn(const Shape *S) {
4040
// CHECK-NEXT: ] }
4141

4242
(void)(1 / !C);
43-
// expected-note@-1 {{'C' is non-null}}
44-
// expected-note@-2 {{Division by zero}}
45-
// expected-warning@-3 {{Division by zero}}
43+
// expected-note@-1 {{Division by zero}}
44+
// expected-warning@-2 {{Division by zero}}
4645
}
4746

clang/test/Analysis/std-c-library-functions-arg-constraints.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ void test_alnum_symbolic(int x) {
4242
// report-warning{{TRUE}} \
4343
// bugpath-warning{{TRUE}} \
4444
// bugpath-note{{TRUE}} \
45-
// bugpath-note{{Left side of '&&' is true}} \
46-
// bugpath-note{{'x' is <= 255}}
45+
// bugpath-note{{Left side of '&&' is true}}
4746
}
4847

4948
void test_alnum_symbolic2(int x) {
@@ -76,8 +75,7 @@ void test_toupper_symbolic(int x) {
7675
// report-warning{{TRUE}} \
7776
// bugpath-warning{{TRUE}} \
7877
// bugpath-note{{TRUE}} \
79-
// bugpath-note{{Left side of '&&' is true}} \
80-
// bugpath-note{{'x' is <= 255}}
78+
// bugpath-note{{Left side of '&&' is true}}
8179
}
8280

8381
void test_toupper_symbolic2(int x) {
@@ -110,8 +108,7 @@ void test_tolower_symbolic(int x) {
110108
// report-warning{{TRUE}} \
111109
// bugpath-warning{{TRUE}} \
112110
// bugpath-note{{TRUE}} \
113-
// bugpath-note{{Left side of '&&' is true}} \
114-
// bugpath-note{{'x' is <= 255}}
111+
// bugpath-note{{Left side of '&&' is true}}
115112
}
116113

117114
void test_tolower_symbolic2(int x) {
@@ -144,8 +141,7 @@ void test_toascii_symbolic(int x) {
144141
// report-warning{{TRUE}} \
145142
// bugpath-warning{{TRUE}} \
146143
// bugpath-note{{TRUE}} \
147-
// bugpath-note{{Left side of '&&' is true}} \
148-
// bugpath-note{{'x' is <= 255}}
144+
// bugpath-note{{Left side of '&&' is true}}
149145
}
150146

151147
void test_toascii_symbolic2(int x) {
@@ -173,8 +169,7 @@ void test_notnull_symbolic(FILE *fp, int *buf) {
173169
clang_analyzer_eval(buf != 0); // \
174170
// report-warning{{TRUE}} \
175171
// bugpath-warning{{TRUE}} \
176-
// bugpath-note{{TRUE}} \
177-
// bugpath-note{{'buf' is not equal to null}}
172+
// bugpath-note{{TRUE}}
178173
}
179174
void test_notnull_symbolic2(FILE *fp, int *buf) {
180175
if (!buf) // bugpath-note{{Assuming 'buf' is null}} \
@@ -218,8 +213,7 @@ void test_notnull_buffer_3(void *buf) {
218213
clang_analyzer_eval(buf != 0); // \
219214
// report-warning{{TRUE}} \
220215
// bugpath-warning{{TRUE}} \
221-
// bugpath-note{{TRUE}} \
222-
// bugpath-note{{'buf' is not equal to null}}
216+
// bugpath-note{{TRUE}}
223217
}
224218

225219
void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) {
@@ -299,17 +293,15 @@ void test_buf_size_symbolic(int s) {
299293
clang_analyzer_eval(s <= 3); // \
300294
// report-warning{{TRUE}} \
301295
// bugpath-warning{{TRUE}} \
302-
// bugpath-note{{TRUE}} \
303-
// bugpath-note{{'s' is <= 3}}
296+
// bugpath-note{{TRUE}}
304297
}
305298
void test_buf_size_symbolic_and_offset(int s) {
306299
char buf[3];
307300
__buf_size_arg_constraint(buf + 1, s);
308301
clang_analyzer_eval(s <= 2); // \
309302
// report-warning{{TRUE}} \
310303
// bugpath-warning{{TRUE}} \
311-
// bugpath-note{{TRUE}} \
312-
// bugpath-note{{'s' is <= 2}}
304+
// bugpath-note{{TRUE}}
313305
}
314306

315307
int __buf_size_arg_constraint_mul(const void *, size_t, size_t);

0 commit comments

Comments
 (0)