-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Reland [clang][dataflow] Fix unsupported types always being equal #131575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Previously when the framework encountered unsupported values, they were always treated as equal when comparing with `==`, regardless of their actual values being different. Now the two sides are only equal if there's a Value assigned to them. Added handling for the special case of `nullptr == nullptr`, and preserved untyped `nullptr` having no value.
@llvm/pr-subscribers-clang-analysis @llvm/pr-subscribers-clang Author: Discookie (Discookie) ChangesRelands #129502. Previously when the framework encountered unsupported values (such as enum classes), they were always treated as equal when comparing with Added handling for the special case of Full diff: https://github.com/llvm/llvm-project/pull/131575.diff 2 Files Affected:
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index 9c54eb16d2224..6403190723e69 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -60,7 +60,14 @@ static BoolValue &evaluateBooleanEquality(const Expr &LHS, const Expr &RHS,
Value *LHSValue = Env.getValue(LHS);
Value *RHSValue = Env.getValue(RHS);
- if (LHSValue == RHSValue)
+ // When two unsupported values are compared, both are nullptr. Only supported
+ // values should evaluate to equal.
+ if (LHSValue == RHSValue && LHSValue)
+ return Env.getBoolLiteralValue(true);
+
+ // Special case: `NullPtrLiteralExpr == itself`. When both sides are untyped
+ // nullptr, they do not have an assigned Value, but they compare equal.
+ if (LHS.getType()->isNullPtrType() && RHS.getType()->isNullPtrType())
return Env.getBoolLiteralValue(true);
if (auto *LHSBool = dyn_cast_or_null<BoolValue>(LHSValue))
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 0f731f4532535..f52b73dbbdc57 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -4974,6 +4974,41 @@ TEST(TransferTest, IntegerLiteralEquality) {
});
}
+TEST(TransferTest, UnsupportedValueEquality) {
+ std::string Code = R"(
+ // An explicitly unsupported type by the framework.
+ enum class EC {
+ A,
+ B
+ };
+
+ void target() {
+ EC ec = EC::A;
+
+ bool unsupported_eq_same = (EC::A == EC::A);
+ bool unsupported_eq_other = (EC::A == EC::B);
+ bool unsupported_eq_var = (ec == EC::B);
+
+ (void)0; // [[p]]
+ }
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+ // We do not model the values of unsupported types, so this
+ // seemingly-trivial case will not be true either.
+ EXPECT_TRUE(isa<AtomicBoolValue>(
+ getValueForDecl<BoolValue>(ASTCtx, Env, "unsupported_eq_same")));
+ EXPECT_TRUE(isa<AtomicBoolValue>(
+ getValueForDecl<BoolValue>(ASTCtx, Env, "unsupported_eq_other")));
+ EXPECT_TRUE(isa<AtomicBoolValue>(
+ getValueForDecl<BoolValue>(ASTCtx, Env, "unsupported_eq_var")));
+ });
+}
+
TEST(TransferTest, CorrelatedBranches) {
std::string Code = R"(
void target(bool B, bool C) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Hi, just checking if you wanted to merge this, or if there were any other issues. Thanks! |
No other issues, thanks for checking! |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/18905 Here is the relevant piece of the build log for the reference
|
Relands #129502.
Previously when the framework encountered unsupported values (such as enum classes), they were always treated as equal when comparing with
==
, regardless of their actual values being different.Now the two sides are only equal if there's a Value assigned to them.
Added handling for the special case of
nullptr == nullptr
, to preserve the behavior of untypednullptr
having no value.