https://github.com/ymand updated https://github.com/llvm/llvm-project/pull/76746
>From 3524e2bc42aa6f83a8ecb3ad892d4a7a33f31f03 Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum <yitzh...@google.com> Date: Tue, 2 Jan 2024 19:27:21 +0000 Subject: [PATCH 1/4] [clang][dataflow] Fix bug in `Value` comparison. Makes value equivalence require that the values have no properties, except in the case of equivalence by pointer equality (if the pointers are equal, nothing else is checked). Fixes issue #76459. --- clang/lib/Analysis/FlowSensitive/Value.cpp | 10 +++++++--- clang/unittests/Analysis/FlowSensitive/ValueTest.cpp | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/Value.cpp b/clang/lib/Analysis/FlowSensitive/Value.cpp index 349f873f1e6c4d..a22156e79ec801 100644 --- a/clang/lib/Analysis/FlowSensitive/Value.cpp +++ b/clang/lib/Analysis/FlowSensitive/Value.cpp @@ -27,9 +27,13 @@ static bool areEquivalentIndirectionValues(const Value &Val1, } bool areEquivalentValues(const Value &Val1, const Value &Val2) { - return &Val1 == &Val2 || (Val1.getKind() == Val2.getKind() && - (isa<TopBoolValue>(&Val1) || - areEquivalentIndirectionValues(Val1, Val2))); + // If values are distinct and have properties, we don't consider them equal, + // leaving equality up to the user model. + return &Val1 == &Val2 || + (Val1.getKind() == Val2.getKind() && + (Val1.properties().empty() && Val2.properties().empty()) && + (isa<TopBoolValue>(&Val1) || + areEquivalentIndirectionValues(Val1, Val2))); } raw_ostream &operator<<(raw_ostream &OS, const Value &Val) { diff --git a/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp b/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp index c5d18ba74c3ed6..2060b7eb264f74 100644 --- a/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp @@ -53,8 +53,8 @@ TEST(ValueTest, EquivalentValuesWithDifferentPropsEquivalent) { TopBoolValue V2(A.makeAtomRef(Atom(3))); V1.setProperty("foo", Prop1); V2.setProperty("bar", Prop2); - EXPECT_TRUE(areEquivalentValues(V1, V2)); - EXPECT_TRUE(areEquivalentValues(V2, V1)); + EXPECT_FALSE(areEquivalentValues(V1, V2)); + EXPECT_FALSE(areEquivalentValues(V2, V1)); } TEST(ValueTest, DifferentKindsNotEquivalent) { >From b2a6821ea88f6ed3b38c6dca1e5c7aaeef4159a2 Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum <ym...@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:30:38 -0500 Subject: [PATCH 2/4] Update clang/lib/Analysis/FlowSensitive/Value.cpp Co-authored-by: martinboehme <mboe...@google.com> --- clang/lib/Analysis/FlowSensitive/Value.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/Value.cpp b/clang/lib/Analysis/FlowSensitive/Value.cpp index a22156e79ec801..fa86874af3f836 100644 --- a/clang/lib/Analysis/FlowSensitive/Value.cpp +++ b/clang/lib/Analysis/FlowSensitive/Value.cpp @@ -27,13 +27,13 @@ static bool areEquivalentIndirectionValues(const Value &Val1, } bool areEquivalentValues(const Value &Val1, const Value &Val2) { + if (&Val1 == &Val2) return true; + if (Val1.getKind() != Val2.getKind()) return false; // If values are distinct and have properties, we don't consider them equal, // leaving equality up to the user model. - return &Val1 == &Val2 || - (Val1.getKind() == Val2.getKind() && - (Val1.properties().empty() && Val2.properties().empty()) && - (isa<TopBoolValue>(&Val1) || - areEquivalentIndirectionValues(Val1, Val2))); + if (!Val1.properties().empty() || !Val2.properties().empty()) return false; + if (isa<TopBoolValue>(&Val1)) return true; + return areEquivalentIndirectionValues(Val1, Val2); } raw_ostream &operator<<(raw_ostream &OS, const Value &Val) { >From d08fdac30f842f4dea5fbee55c37843f9bf15da0 Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum <yitzh...@google.com> Date: Wed, 10 Jan 2024 19:51:23 +0000 Subject: [PATCH 3/4] fixup! Update clang/lib/Analysis/FlowSensitive/Value.cpp add tests --- .../Analysis/FlowSensitive/ValueTest.cpp | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp b/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp index 2060b7eb264f74..b07328d2a56215 100644 --- a/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/ValueTest.cpp @@ -45,7 +45,20 @@ TEST(ValueTest, TopsEquivalent) { EXPECT_TRUE(areEquivalentValues(V2, V1)); } -TEST(ValueTest, EquivalentValuesWithDifferentPropsEquivalent) { +// The framework does not (currently) consider equivalence for values with +// properties, leaving such to individual analyses. +TEST(ValueTest, ValuesWithSamePropsDifferent) { + Arena A; + TopBoolValue Prop(A.makeAtomRef(Atom(0))); + TopBoolValue V1(A.makeAtomRef(Atom(2))); + TopBoolValue V2(A.makeAtomRef(Atom(3))); + V1.setProperty("foo", Prop); + V2.setProperty("foo", Prop); + EXPECT_FALSE(areEquivalentValues(V1, V2)); + EXPECT_FALSE(areEquivalentValues(V2, V1)); +} + +TEST(ValueTest, ValuesWithDifferentPropsDifferent) { Arena A; TopBoolValue Prop1(A.makeAtomRef(Atom(0))); TopBoolValue Prop2(A.makeAtomRef(Atom(1))); @@ -57,6 +70,17 @@ TEST(ValueTest, EquivalentValuesWithDifferentPropsEquivalent) { EXPECT_FALSE(areEquivalentValues(V2, V1)); } +TEST(ValueTest, ValuesWithDifferentNumberPropsDifferent) { + Arena A; + TopBoolValue Prop(A.makeAtomRef(Atom(0))); + TopBoolValue V1(A.makeAtomRef(Atom(2))); + TopBoolValue V2(A.makeAtomRef(Atom(3))); + // Only set a property on `V1`. + V1.setProperty("foo", Prop); + EXPECT_FALSE(areEquivalentValues(V1, V2)); + EXPECT_FALSE(areEquivalentValues(V2, V1)); +} + TEST(ValueTest, DifferentKindsNotEquivalent) { Arena A; auto L = ScalarStorageLocation(QualType()); >From ac3c298c71d73b18918f191e84fcf618548f91f6 Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum <yitzh...@google.com> Date: Wed, 10 Jan 2024 19:54:45 +0000 Subject: [PATCH 4/4] fixup! fixup! Update clang/lib/Analysis/FlowSensitive/Value.cpp clang format --- clang/lib/Analysis/FlowSensitive/Value.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/Value.cpp b/clang/lib/Analysis/FlowSensitive/Value.cpp index fa86874af3f836..7fad6deb0e918f 100644 --- a/clang/lib/Analysis/FlowSensitive/Value.cpp +++ b/clang/lib/Analysis/FlowSensitive/Value.cpp @@ -27,12 +27,16 @@ static bool areEquivalentIndirectionValues(const Value &Val1, } bool areEquivalentValues(const Value &Val1, const Value &Val2) { - if (&Val1 == &Val2) return true; - if (Val1.getKind() != Val2.getKind()) return false; + if (&Val1 == &Val2) + return true; + if (Val1.getKind() != Val2.getKind()) + return false; // If values are distinct and have properties, we don't consider them equal, // leaving equality up to the user model. - if (!Val1.properties().empty() || !Val2.properties().empty()) return false; - if (isa<TopBoolValue>(&Val1)) return true; + if (!Val1.properties().empty() || !Val2.properties().empty()) + return false; + if (isa<TopBoolValue>(&Val1)) + return true; return areEquivalentIndirectionValues(Val1, Val2); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits