diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 17ec1fe0b946de..69b2aea52aa9d3 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -305,6 +305,8 @@ Improvements to Clang's diagnostics - Clang now diagnose when importing module implementation partition units in module interface units. +- Don't emit bogus dangling diagnostics when ``[[gsl::Owner]]`` and `[[clang::lifetimebound]]` are used together (#GH108272). + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index f62e18543851c1..c98fbca849faba 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -269,7 +269,8 @@ static bool isInStlNamespace(const Decl *D) { static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { if (auto *Conv = dyn_cast_or_null(Callee)) - if (isRecordWithAttr(Conv->getConversionType())) + if (isRecordWithAttr(Conv->getConversionType()) && + Callee->getParent()->hasAttr()) return true; if (!isInStlNamespace(Callee->getParent())) return false; diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index 59357d0730a7d9..69e5395a78a57e 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -553,3 +553,37 @@ void test() { std::string_view svjkk1 = ReturnStringView(StrCat("bar", "x")); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} } } // namespace GH100549 + +namespace GH108272 { +template +struct [[gsl::Owner]] StatusOr { + const T &value() [[clang::lifetimebound]]; +}; + +template +class Wrapper1 { + public: + operator V() const; + V value; +}; +std::string_view test1() { + StatusOr> k; + // Be conservative in this case, as there is not enough information available + // to infer the lifetime relationship for the Wrapper1 type. + std::string_view good = StatusOr>().value(); + return k.value(); +} + +template +class Wrapper2 { + public: + operator V() const [[clang::lifetimebound]]; + V value; +}; +std::string_view test2() { + StatusOr> k; + // We expect dangling issues as the conversion operator is lifetimebound。 + std::string_view bad = StatusOr>().value(); // expected-warning {{temporary whose address is used as value of}} + return k.value(); // expected-warning {{address of stack memory associated}} +} +} // namespace GH108272