Skip to content

Commit 6c81b57

Browse files
committed
[clang][dataflow] Perform structural comparison of indirection values in join.
This patch changes `Environment::join`, in the case that two values at the same location are not (pointer) equal, to structurally compare indirection values (pointers and references) for equivalence (that is, equivalent pointees) before resorting to merging. This change makes join consistent with equivalence, which also performs structural comparison. It also fixes a bug where the values are `ReferenceValue` but the merge creates a non-reference value. This case arises when the `ReferenceValue`s were created to represent an lvalue, so the "reference-ness" is not reflected in the type. In this case, the pointees will always be equivalent, because lvalues at the same code location point to the location of a fixed declaration, whose location is itself stable across blocks. We were unable to reproduce a unit test for this latter bug, but have verified the fix in the context of a larger piece of code that triggers the bug. Differential Revision: https://reviews.llvm.org/D124540
1 parent 1462e63 commit 6c81b57

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/Analysis/FlowSensitive/Value.h"
2222
#include "llvm/ADT/DenseMap.h"
2323
#include "llvm/ADT/DenseSet.h"
24+
#include "llvm/Support/Casting.h"
2425
#include "llvm/Support/ErrorHandling.h"
2526
#include <cassert>
2627
#include <memory>
@@ -105,6 +106,15 @@ static Value *mergeDistinctValues(QualType Type, Value *Val1,
105106
return &MergedEnv.makeOr(*Expr1, *Expr2);
106107
}
107108

109+
// FIXME: add unit tests that cover this statement.
110+
if (auto *IndVal1 = dyn_cast<IndirectionValue>(Val1)) {
111+
auto *IndVal2 = cast<IndirectionValue>(Val2);
112+
assert(IndVal1->getKind() == IndVal2->getKind());
113+
if (&IndVal1->getPointeeLoc() == &IndVal2->getPointeeLoc()) {
114+
return Val1;
115+
}
116+
}
117+
108118
// FIXME: Consider destroying `MergedValue` immediately if `ValueModel::merge`
109119
// returns false to avoid storing unneeded values in `DACtx`.
110120
if (Value *MergedVal = MergedEnv.createValue(Type))

0 commit comments

Comments
 (0)