This is a draft patch for a bug reported by Daniel Marjamäki. For now, I just need to ensure I'm going the right direction.
Test case (I'll add it to the patch later):
// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s void clang_analyzer_warnIfReached(); extern int Min, Max; void testReachabilityFail(int b) { if (!(b >= Min && b < Max)) { return; } else { clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} b++; } }
A quote from mailing list explaining a problem:
There is my understanding of the problem.
We don't handle sym-sym comparisons well. The result of comparison between two symbols is an UnknownVal.
First, analyzer renders "b >= Min" branch and assumes it false. Then, it renders operator '&&', then makes a cleanup which results in a new node with an empty state (1). It proceeds with false branch to operator! and then - to ReturnStmt.Then, it renders branch where (b >= Min) is true. It assigns another UnknownVal to b < Max, cleanups ... and tries to create another empty-stated node before entering operator!. But there is already a node with an empty state and in the ProgramPoint. So, two execution paths are merged unexpectedly. And the analysis finishes since 'operator!' was rendered already for this merged branch.
I tried a quick solution which is the conjuring a symbolic value for comparisons instead of leaving it Unknown. It seems to work but I'm not sure if it is exactly what we need here. Anna, Artem, what is your opinion? Should we proceed with review or it is a bad idea in general?