Author: Zeyi Xu Date: 2026-05-15T08:05:39+08:00 New Revision: 21e436f7ba0fbaa70b9fe5f910d8355b2374ba04
URL: https://github.com/llvm/llvm-project/commit/21e436f7ba0fbaa70b9fe5f910d8355b2374ba04 DIFF: https://github.com/llvm/llvm-project/commit/21e436f7ba0fbaa70b9fe5f910d8355b2374ba04.diff LOG: [LifetimeSafety] Recognize declarations nested under std namespace (#197604) Previously `isInStlNamespace()` only checked the immediate declaration context. This missed declarations nested below `std` through records or intermediate namespaces, such as `std::basic_string_view` constructors. This commit fixes the problem by walking the `DeclContext` chain in `isInStlNamespace`. Closes #197454 Added: Modified: clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp clang/test/Sema/Inputs/lifetime-analysis.h clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp index 393e558fd39c3..546ae852b1ee0 100644 --- a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp +++ b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp @@ -99,17 +99,18 @@ bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) { } bool isInStlNamespace(const Decl *D) { - const DeclContext *DC = D->getDeclContext(); - if (!DC) - return false; - if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) - if (const IdentifierInfo *II = ND->getIdentifier()) { - StringRef Name = II->getName(); - if (Name.size() >= 2 && Name.front() == '_' && - (Name[1] == '_' || isUppercase(Name[1]))) - return true; - } - return DC->isStdNamespace(); + for (const DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) { + if (DC->isStdNamespace()) + return true; + if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) + if (const IdentifierInfo *II = ND->getIdentifier()) { + StringRef Name = II->getName(); + if (Name.size() >= 2 && Name.front() == '_' && + (Name[1] == '_' || isUppercase(Name[1]))) + return true; + } + } + return false; } bool isPointerLikeType(QualType QT) { diff --git a/clang/test/Sema/Inputs/lifetime-analysis.h b/clang/test/Sema/Inputs/lifetime-analysis.h index 79b009170ffd0..2ae6ed38714b7 100644 --- a/clang/test/Sema/Inputs/lifetime-analysis.h +++ b/clang/test/Sema/Inputs/lifetime-analysis.h @@ -192,6 +192,9 @@ struct basic_string_view { }; using string_view = basic_string_view<char>; +template <typename T> +basic_string_view<T>::basic_string_view(const T *) {} + template<typename T> struct span { span(); diff --git a/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp b/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp index 2a5234f91a964..5e22677f5269d 100644 --- a/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp +++ b/clang/test/Sema/warn-lifetime-safety-lifetimebound.cpp @@ -144,3 +144,7 @@ struct AssignementIncorr { return tmp; } }; + +void implicit_lifetimebound_in_nested_std_namespace() { + (void)std::basic_string_view<char>("hello"); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
