Properly detect temporary gsl::Owners through reference initialization chains.
authorGabor Horvath <xazax.hun@gmail.com>
Sun, 11 Aug 2019 14:39:42 +0000 (14:39 +0000)
committerGabor Horvath <xazax.hun@gmail.com>
Sun, 11 Aug 2019 14:39:42 +0000 (14:39 +0000)
llvm-svn: 368534

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

index 90b8d4a..980696f 100644 (file)
@@ -7104,7 +7104,8 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity,
     SourceLocation DiagLoc = DiagRange.getBegin();
 
     auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
-    bool IsTempGslOwner = MTE && isRecordWithAttr<OwnerAttr>(MTE->getType());
+    bool IsTempGslOwner = MTE && !MTE->getExtendingDecl() &&
+                          isRecordWithAttr<OwnerAttr>(MTE->getType());
     bool IsLocalGslOwner =
         isa<DeclRefExpr>(L) && isRecordWithAttr<OwnerAttr>(L->getType());
 
index 2e85a3f..6503f41 100644 (file)
@@ -141,7 +141,7 @@ struct vector {
   typedef basic_iterator<T> iterator;
   iterator begin();
   iterator end();
-  T *data();
+  const T *data() const;
   T &at(int n);
 };
 
@@ -235,8 +235,14 @@ struct X {
 };
 
 std::vector<int>::iterator getIt();
+std::vector<int> getVec();
 
-const int &handleGslPtrInitsThroughReference(const std::vector<int> &v) {
+const int &handleGslPtrInitsThroughReference() {
   const auto &it = getIt(); // Ok, it is lifetime extended.
   return *it;
 }
+
+void handleGslPtrInitsThroughReference2() {
+  const std::vector<int> &v = getVec();
+  const int *val = v.data(); // Ok, it is lifetime extended.
+}