forked from OSchip/llvm-project
Fix bug in ConditionBRVisitor where for C++ (and not C) we were not ignoring
implicit pointer-to-boolean conversions in condition expressions. This would result in inconsistent diagnostic emission between C and C++. A consequence of this is now ConditionBRVisitor and TrackConstraintBRVisitor may emit redundant diagnostics, for example: "Assuming pointer value is null" (TrackConstraintBRVisitor) "Assuming 'p' is null" (ConditionBRVisitor) We need to reconcile the two, and perhaps prefer one over the other in some cases. llvm-svn: 163372
This commit is contained in:
parent
1cb637cc37
commit
7c15040e98
|
@ -696,8 +696,7 @@ ConditionBRVisitor::VisitTerminator(const Stmt *Term,
|
|||
assert(Cond);
|
||||
assert(srcBlk->succ_size() == 2);
|
||||
const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
|
||||
return VisitTrueTest(Cond->IgnoreParenNoopCasts(BRC.getASTContext()),
|
||||
tookTrue, BRC, R, N);
|
||||
return VisitTrueTest(Cond, tookTrue, BRC, R, N);
|
||||
}
|
||||
|
||||
PathDiagnosticPiece *
|
||||
|
@ -710,7 +709,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
|
|||
const Expr *Ex = Cond;
|
||||
|
||||
while (true) {
|
||||
Ex = Ex->IgnoreParens();
|
||||
Ex = Ex->IgnoreParenCasts();
|
||||
switch (Ex->getStmtClass()) {
|
||||
default:
|
||||
return 0;
|
||||
|
@ -724,7 +723,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
|
|||
const UnaryOperator *UO = cast<UnaryOperator>(Ex);
|
||||
if (UO->getOpcode() == UO_LNot) {
|
||||
tookTrue = !tookTrue;
|
||||
Ex = UO->getSubExpr()->IgnoreParenNoopCasts(BRC.getASTContext());
|
||||
Ex = UO->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -11,6 +11,7 @@ void test(S *p) {
|
|||
if (p) return;
|
||||
//expected-note@-1{{Taking false branch}}
|
||||
//expected-note@-2{{Assuming pointer value is null}}
|
||||
//expected-note@-3{{Assuming 'p' is null}}
|
||||
r.y = 5; // expected-warning {{Access to field 'y' results in a dereference of a null pointer (loaded from variable 'r')}}
|
||||
// expected-note@-1{{Access to field 'y' results in a dereference of a null pointer (loaded from variable 'r')}}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ void test_ic_set_to_null() {
|
|||
}
|
||||
|
||||
void test_ic_null(TestInstanceCall *p) {
|
||||
if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}}
|
||||
if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Assuming 'p' is null}} expected-note {{Taking true branch}}
|
||||
p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ void test_ic_member_ptr() {
|
|||
}
|
||||
|
||||
void test_cast(const TestInstanceCall *p) {
|
||||
if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}}
|
||||
if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Assuming 'p' is null}} expected-note {{Taking true branch}}
|
||||
const_cast<TestInstanceCall *>(p)->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue