================
@@ -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
----------------
usx95 wrote:
Interesting idea. Started a thread to discuss this further. Postponing for a
future PR to try this out.
https://github.com/llvm/llvm-project/pull/168344
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits