[clang] 3c6f91e - [clang][dataflow] Fix result object location for builtin `<=>`. (#88726)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 15 23:49:49 PDT 2024
Author: martinboehme
Date: 2024-04-16T08:49:45+02:00
New Revision: 3c6f91e5b671321c95259dabecdbdfe4a6d69ce1
URL: https://github.com/llvm/llvm-project/commit/3c6f91e5b671321c95259dabecdbdfe4a6d69ce1
DIFF: https://github.com/llvm/llvm-project/commit/3c6f91e5b671321c95259dabecdbdfe4a6d69ce1.diff
LOG: [clang][dataflow] Fix result object location for builtin `<=>`. (#88726)
The newly added test causes an assertion failure in
`PropagateResultObject()`
without the fix added here.
Added:
Modified:
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index bea15ce9bd24d1..ee2581143e1141 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -508,6 +508,11 @@ class ResultObjectVisitor : public RecursiveASTVisitor<ResultObjectVisitor> {
isa<CXXStdInitializerListExpr>(E)) {
return;
}
+ if (auto *Op = dyn_cast<BinaryOperator>(E);
+ Op && Op->getOpcode() == BO_Cmp) {
+ // Builtin `<=>` returns a `std::strong_ordering` object.
+ return;
+ }
if (auto *InitList = dyn_cast<InitListExpr>(E)) {
if (!InitList->isSemanticForm())
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 00dafb2988c690..d8bcc3da4b8b1c 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3098,6 +3098,58 @@ TEST(TransferTest, ResultObjectLocationForCXXOperatorCallExpr) {
});
}
+// Check that the `std::strong_ordering` object returned by builtin `<=>` has a
+// correctly modeled result object location.
+TEST(TransferTest, ResultObjectLocationForBuiltinSpaceshipOperator) {
+ std::string Code = R"(
+ namespace std {
+ // This is the minimal definition required to get
+ // `Sema::CheckComparisonCategoryType()` to accept this fake.
+ struct strong_ordering {
+ enum class ordering { less, equal, greater };
+ ordering o;
+ static const strong_ordering less;
+ static const strong_ordering equivalent;
+ static const strong_ordering equal;
+ static const strong_ordering greater;
+ };
+
+ inline constexpr strong_ordering strong_ordering::less =
+ { strong_ordering::ordering::less };
+ inline constexpr strong_ordering strong_ordering::equal =
+ { strong_ordering::ordering::equal };
+ inline constexpr strong_ordering strong_ordering::equivalent =
+ { strong_ordering::ordering::equal };
+ inline constexpr strong_ordering strong_ordering::greater =
+ { strong_ordering::ordering::greater };
+ }
+ void target(int i, int j) {
+ auto ordering = i <=> j;
+ // [[p]]
+ }
+ )";
+ using ast_matchers::binaryOperator;
+ using ast_matchers::hasOperatorName;
+ using ast_matchers::match;
+ using ast_matchers::selectFirst;
+ using ast_matchers::traverse;
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+ auto *Spaceship = selectFirst<BinaryOperator>(
+ "op",
+ match(binaryOperator(hasOperatorName("<=>")).bind("op"), ASTCtx));
+
+ EXPECT_EQ(
+ &Env.getResultObjectLocation(*Spaceship),
+ &getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "ordering"));
+ },
+ LangStandard::lang_cxx20);
+}
+
TEST(TransferTest, ResultObjectLocationForStdInitializerListExpr) {
std::string Code = R"(
namespace std {
More information about the cfe-commits
mailing list