================ @@ -0,0 +1,365 @@ +//===- AssignmentQuery.cpp - C++ Lifetime Safety Checker --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the LifetimeChecker, which detects use-after-free +// errors by checking if live origins hold loans that have expired. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/Analyses/LifetimeSafety/AssignmentQuery.h" +#include "clang/AST/Decl.h" +#include "clang/AST/ParentMap.h" +#include "clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h" +#include "clang/Analysis/Analyses/LifetimeSafety/Origins.h" +#include "clang/Analysis/AnalysisDeclContext.h" +#include "clang/Analysis/CFG.h" +#include "llvm/ADT/SmallPtrSet.h" +#include <cstddef> + +namespace { + +using namespace clang; +using namespace clang::lifetimes; +using namespace clang::lifetimes::internal; + +std::optional<const Expr *> GetPureSrcExpr(const Expr *TargetExpr) { + if (!TargetExpr) + return std::nullopt; + const Expr *SExpr = TargetExpr->IgnoreParenCasts(); + if (!SExpr) + return std::nullopt; + + if (llvm::isa<DeclRefExpr, CXXTemporaryObjectExpr, ConditionalOperator, + CXXConstructExpr>(SExpr) && + !SExpr->getExprLoc().isInvalid()) + return SExpr; + + if (const auto *SCExpr = llvm::dyn_cast<CallExpr>(SExpr); + SCExpr && !SCExpr->getExprLoc().isInvalid() && + !SCExpr->getCallee()->IgnoreParenCasts()->getExprLoc().isInvalid()) + return SCExpr; + + if (const auto *SMExpr = llvm::dyn_cast<MemberExpr>(SExpr)) + return GetPureSrcExpr(SMExpr->getBase()); + if (const auto *SCExpr = llvm::dyn_cast<CXXMemberCallExpr>(SExpr)) + return GetPureSrcExpr(SCExpr->getCallee()); + if (const auto *SUOExpr = llvm::dyn_cast<UnaryOperator>(SExpr)) + return GetPureSrcExpr(SUOExpr->getSubExpr()); + if (const auto *SCBExpr = llvm::dyn_cast<CXXBindTemporaryExpr>(SExpr)) + return GetPureSrcExpr(SCBExpr->getSubExpr()); + + return std::nullopt; +} + +/// Specifically handles assignments involving a FieldDecl. +/// +/// Since we currently only store the FieldDecl without its corresponding +/// LHS expression, this function attempts to recover or resolve the LHS +/// context by analyzing the RHS. +const MemberExpr *getFieldFromAssignmentExpr(const Expr *RHS, + const ParentMap &CurrParentMap) { + + const Stmt *CurrStmt = CurrParentMap.getParent(RHS); ---------------- Xazax-hun wrote:
In general, trying to rely on the parents here could be a bit unreliable. I think the lifetime analysis might skip certain AST nodes, so what we are looking for might not be the direct parent. I guess this is OK for a best effort solution, but I am wondering if it would be better to store the actual assignment instead of the RHS during the analysis. https://github.com/llvm/llvm-project/pull/188467 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
