From: Gabor Horvath Date: Sun, 11 Aug 2019 08:05:28 +0000 (+0000) Subject: Properly handle reference initialization when detecting gsl::Pointer initialization... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=79b62d4a86a9409196d2d7f22439b9eae7839f9a;p=clang Properly handle reference initialization when detecting gsl::Pointer initialization chains git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368528 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 9411c81745..90b8d4a30d 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -7079,8 +7079,12 @@ static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I, } static bool pathOnlyInitializesGslPointer(IndirectLocalPath &Path) { - return !Path.empty() && - Path.back().Kind == IndirectLocalPathEntry::GslPointerInit; + for (auto It = Path.rbegin(), End = Path.rend(); It != End; ++It) { + if (It->Kind == IndirectLocalPathEntry::VarInit) + continue; + return It->Kind == IndirectLocalPathEntry::GslPointerInit; + } + return false; } void Sema::checkInitializerLifetime(const InitializedEntity &Entity, @@ -7109,8 +7113,8 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity, // a local or temporary owner or the address of a local variable/param. We // do not want to follow the references when returning a pointer originating // from a local owner to avoid the following false positive: - // int &p = *localOwner; - // someContainer.add(std::move(localOwner)); + // int &p = *localUniquePtr; + // someContainer.add(std::move(localUniquePtr)); // return p; if (!IsTempGslOwner && pathOnlyInitializesGslPointer(Path) && !(IsLocalGslOwner && !pathContainsInit(Path))) @@ -7217,7 +7221,7 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity, if (pathContainsInit(Path)) return false; - // Suppress false positives for code like the below: + // Suppress false positives for code like the one below: // Ctor(unique_ptr up) : member(*up), member2(move(up)) {} if (IsLocalGslOwner && pathOnlyInitializesGslPointer(Path)) return false; diff --git a/test/Sema/warn-lifetime-analysis-nocfg.cpp b/test/Sema/warn-lifetime-analysis-nocfg.cpp index c558901cf2..2e85a3f6f7 100644 --- a/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -130,7 +130,7 @@ typename remove_reference::type &&move(T &&t) noexcept; template struct basic_iterator { basic_iterator operator++(); - T& operator*(); + T& operator*() const; }; template @@ -227,8 +227,16 @@ const char *trackThroughMultiplePointer() { } struct X { - X(std::unique_ptr up) : pointee(*up), pointer(std::move(up)) {} - + X(std::unique_ptr up) : + pointee(*up), pointee2(up.get()), pointer(std::move(up)) {} int &pointee; + int *pointee2; std::unique_ptr pointer; }; + +std::vector::iterator getIt(); + +const int &handleGslPtrInitsThroughReference(const std::vector &v) { + const auto &it = getIt(); // Ok, it is lifetime extended. + return *it; +}