https://github.com/martinboehme created https://github.com/llvm/llvm-project/pull/88726
The newly added test causes an assertion failure in `PropagateResultObject()` without the fix added here. >From ffdde99a773e732fbc484a5f7647d78d1f15954e Mon Sep 17 00:00:00 2001 From: Martin Braenne <mboe...@google.com> Date: Mon, 15 Apr 2024 12:51:04 +0000 Subject: [PATCH] [clang][dataflow] Fix result object location for builtin `<=>`. The newly added test causes an assertion failure in `PropagateResultObject()` without the fix added here. --- .../FlowSensitive/DataflowEnvironment.cpp | 5 ++ .../Analysis/FlowSensitive/TransferTest.cpp | 52 +++++++++++++++++++ 2 files changed, 57 insertions(+) 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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits