================
@@ -521,8 +563,75 @@ class FactGeneratorVisitor : public
ConstStmtVisitor<FactGeneratorVisitor> {
}
private:
+ static bool isGslPointerType(QualType QT) {
+ if (const auto *RD = QT->getAsCXXRecordDecl()) {
+ // We need to check the template definition for specializations.
+ if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
+ return CTSD->getSpecializedTemplate()
+ ->getTemplatedDecl()
+ ->hasAttr<PointerAttr>();
+ return RD->hasAttr<PointerAttr>();
+ }
+ return false;
+ }
+
// Check if a type has an origin.
- bool hasOrigin(QualType QT) { return QT->isPointerOrReferenceType(); }
+ static bool hasOrigin(QualType QT) {
+ if (QT->isFunctionPointerType())
+ return false;
+ return QT->isPointerOrReferenceType() || isGslPointerType(QT);
+ }
+
+ /// Checks if a call-like expression creates a borrow by passing a local
+ /// value to a reference parameter, creating an IssueFact if it does.
+ void checkForBorrows(const Expr *Call, const FunctionDecl *FD,
+ ArrayRef<const Expr *> Args) {
+ if (!FD)
+ return;
+
+ for (unsigned I = 0; I < Args.size(); ++I) {
+ if (I >= FD->getNumParams())
+ break;
+
+ const ParmVarDecl *Param = FD->getParamDecl(I);
+ const Expr *Arg = Args[I];
+
+ // This is the core condition for a new borrow: a value type (no origin)
+ // is passed to a reference parameter.
+ if (Param->getType()->isReferenceType() && !hasOrigin(Arg->getType())) {
+ if (const Loan *L = createLoanFrom(Arg, Call)) {
+ OriginID OID = FactMgr.getOriginMgr().getOrCreate(*Call);
+ CurrentBlockFacts.push_back(
+ FactMgr.createFact<IssueFact>(L->ID, OID));
+ // For view creation, we assume the first borrow is the significant
+ // one.
+ return;
+ }
+ }
+ }
+ }
+
+ /// Attempts to create a loan by analyzing the source expression of a borrow.
+ /// This method is the single point for creating loans, allowing for future
+ /// expansion to handle temporaries, field members, etc.
+ /// \param SourceExpr The expression representing the object being borrowed
+ /// from.
+ /// \param IssueExpr The expression that triggers the borrow (e.g., a
+ /// constructor call).
+ /// \return The new Loan on success, nullptr on failure.
+ const Loan *createLoanFrom(const Expr *SourceExpr, const Expr *IssueExpr) {
+ // For now, we only handle direct borrows from local variables.
+ // In the future, this can be extended to handle MaterializeTemporaryExpr,
----------------
usx95 wrote:
Did some renaming of the params.
A loan to a path is issued to some origin. This path would always be some
expression (example a DRE `a`, field `a.field`, array subscript `a[0]`). This
loan is issued to a an origin of the expression triggering the loan (`IssuedTo`
expr). We could have directly used the origin of this expression but loan needs
to be aware of the underlying issueTo expression for diagnostic purposes as
this is the expression at which the diagnostic is shown.
https://github.com/llvm/llvm-project/pull/154009
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits