]> granicus.if.org Git - clang/commitdiff
Properly handle reference initialization when detecting gsl::Pointer initialization...
authorGabor Horvath <xazax.hun@gmail.com>
Sun, 11 Aug 2019 08:05:28 +0000 (08:05 +0000)
committerGabor Horvath <xazax.hun@gmail.com>
Sun, 11 Aug 2019 08:05:28 +0000 (08:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368528 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaInit.cpp
test/Sema/warn-lifetime-analysis-nocfg.cpp

index 9411c817451668f5e63774a9abc34be427cef248..90b8d4a30dc41276857255803ea429fe4b095964 100644 (file)
@@ -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<T> up) : member(*up), member2(move(up)) {}
         if (IsLocalGslOwner && pathOnlyInitializesGslPointer(Path))
           return false;
index c558901cf2e6cc2257d361df41f584dbca00ee09..2e85a3f6f745e8116340111e8f1e3ffcc07b251d 100644 (file)
@@ -130,7 +130,7 @@ typename remove_reference<T>::type &&move(T &&t) noexcept;
 template <typename T>
 struct basic_iterator {
   basic_iterator operator++();
-  T& operator*();
+  T& operator*() const;
 };
 
 template<typename T>
@@ -227,8 +227,16 @@ const char *trackThroughMultiplePointer() {
 }
 
 struct X {
-  X(std::unique_ptr<int> up) : pointee(*up), pointer(std::move(up)) {}
-
+  X(std::unique_ptr<int> up) :
+    pointee(*up), pointee2(up.get()), pointer(std::move(up)) {}
   int &pointee;
+  int *pointee2;
   std::unique_ptr<int> pointer;
 };
+
+std::vector<int>::iterator getIt();
+
+const int &handleGslPtrInitsThroughReference(const std::vector<int> &v) {
+  const auto &it = getIt(); // Ok, it is lifetime extended.
+  return *it;
+}