llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-analysis Author: Utkarsh Saxena (usx95) <details> <summary>Changes</summary> Add support for handling parenthesized expressions in lifetime safety analysis. Modified the `OriginManager::get` method to ignore parentheses when retrieving origins by recursively calling itself on the unparenthesized expression. This ensures that expressions with extra parentheses are properly analyzed for lifetime safety issues. --- Full diff: https://github.com/llvm/llvm-project/pull/167245.diff 3 Files Affected: - (modified) clang/lib/Analysis/LifetimeSafety/Origins.cpp (+2) - (modified) clang/test/Sema/warn-lifetime-safety.cpp (+24) - (modified) clang/unittests/Analysis/LifetimeSafetyTest.cpp (+17) ``````````diff diff --git a/clang/lib/Analysis/LifetimeSafety/Origins.cpp b/clang/lib/Analysis/LifetimeSafety/Origins.cpp index ea51a75324e06..0f2eaa94a5987 100644 --- a/clang/lib/Analysis/LifetimeSafety/Origins.cpp +++ b/clang/lib/Analysis/LifetimeSafety/Origins.cpp @@ -34,6 +34,8 @@ Origin &OriginManager::addOrigin(OriginID ID, const clang::Expr &E) { // TODO: Mark this method as const once we remove the call to getOrCreate. OriginID OriginManager::get(const Expr &E) { + if (auto *ParenIgnored = E.IgnoreParens(); ParenIgnored != &E) + return get(*ParenIgnored); auto It = ExprToOriginID.find(&E); if (It != ExprToOriginID.end()) return It->second; diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp index 3057ac9385736..52165c4236988 100644 --- a/clang/test/Sema/warn-lifetime-safety.cpp +++ b/clang/test/Sema/warn-lifetime-safety.cpp @@ -635,3 +635,27 @@ void conditional_operator(bool cond) { } // expected-note 4 {{destroyed here}} (void)*p; // expected-note 4 {{later used here}} } + +void parentheses(bool cond) { + MyObj* p; + { + MyObj a; + p = &((((a)))); // expected-warning {{object whose reference is captured does not live long enough}} + } // expected-note {{destroyed here}} + (void)*p; // expected-note {{later used here}} + + { + MyObj a; + p = ((GetPointer((a)))); // expected-warning {{object whose reference is captured does not live long enough}} + } // expected-note {{destroyed here}} + (void)*p; // expected-note {{later used here}} + + { + MyObj a, b, c, d; + p = &(cond ? cond ? a // expected-warning {{object whose reference is captured does not live long enough}}. + : b // expected-warning {{object whose reference is captured does not live long enough}}. + : cond ? c // expected-warning {{object whose reference is captured does not live long enough}}. + : d); // expected-warning {{object whose reference is captured does not live long enough}}. + } // expected-note 4 {{destroyed here}} + (void)*p; // expected-note 4 {{later used here}} +} diff --git a/clang/unittests/Analysis/LifetimeSafetyTest.cpp b/clang/unittests/Analysis/LifetimeSafetyTest.cpp index 9d61d56e078e3..601308c53f9a9 100644 --- a/clang/unittests/Analysis/LifetimeSafetyTest.cpp +++ b/clang/unittests/Analysis/LifetimeSafetyTest.cpp @@ -700,6 +700,23 @@ TEST_F(LifetimeAnalysisTest, GslPointerInConditionalOperator) { EXPECT_THAT(Origin("v"), HasLoansTo({"a", "b"}, "p1")); } +TEST_F(LifetimeAnalysisTest, ExtraParenthesis) { + SetupTest(R"( + void target() { + MyObj a; + View x = ((View((((a)))))); + View y = ((View{(((x)))})); + View z = ((View(((y))))); + View p = ((View{((x))})); + POINT(p1); + } + )"); + EXPECT_THAT(Origin("x"), HasLoansTo({"a"}, "p1")); + EXPECT_THAT(Origin("y"), HasLoansTo({"a"}, "p1")); + EXPECT_THAT(Origin("z"), HasLoansTo({"a"}, "p1")); + EXPECT_THAT(Origin("p"), HasLoansTo({"a"}, "p1")); +} + // FIXME: Handle temporaries. TEST_F(LifetimeAnalysisTest, ViewFromTemporary) { SetupTest(R"( `````````` </details> https://github.com/llvm/llvm-project/pull/167245 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
