================
@@ -275,22 +416,41 @@ void FactsGenerator::handleFunctionCall(const Expr *Call,
         // For explicit arguments, find the corresponding parameter
         // declaration.
         PVD = Method->getParamDecl(I - 1);
-    } else if (I < FD->getNumParams())
+    } else if (I < FD->getNumParams()) {
       // For free functions or static methods.
       PVD = FD->getParamDecl(I);
+    }
     return PVD ? PVD->hasAttr<clang::LifetimeBoundAttr>() : false;
   };
   if (Args.empty())
     return;
-  bool killedSrc = false;
-  for (unsigned I = 0; I < Args.size(); ++I)
-    if (IsGslConstruction || IsArgLifetimeBound(I)) {
-      if (!killedSrc) {
-        killedSrc = true;
-        killAndFlowOrigin(*Call, *Args[I]);
-      } else
-        flowOrigin(*Call, *Args[I]);
+  bool KillSrc = true;
+  for (unsigned I = 0; I < Args.size(); ++I) {
+    OriginList *ArgList = getOriginsList(*Args[I]);
+    if (!ArgList)
+      continue;
+    if (IsGslConstruction) {
+      // TODO: document with code example.
+      // std::string_view(const std::string_view& from)
+      if (isGslPointerType(Args[I]->getType())) {
+        assert(!Args[I]->isGLValue() || ArgList->getLength() >= 2);
+        ArgList = getRValueOrigins(Args[I], ArgList);
+      }
+      if (isGslOwnerType(Args[I]->getType())) {
+        // GSL construction creates a view that borrows from arguments.
+        // This implies flowing origins through the list structure.
+        flow(CallList, ArgList, KillSrc);
+        KillSrc = false;
+      }
+    } else if (IsArgLifetimeBound(I)) {
+      // Lifetimebound on a non-GSL-ctor function means the returned
----------------
Xazax-hun wrote:

Probably not for this PR, but I was wondering if we can sometimes say something 
about the nested origins as well. In Rust, there is this implicit constraint 
that if I have `int * `A * `B`, the outer pointer cannot outlive the inner 
pointer. So, there is an outlives relationship between `A` and `B`. 

So in case `int * `A * `B` has to outlive `int * `C * `D`, so `B` has to 
outlive `D`, I wonder if we can also deduce that `A` also has to outlive `D` 
(since `A` has to outlive `B`). And I wonder if this is helpful in catching any 
bugs. 

https://github.com/llvm/llvm-project/pull/168344
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to