================ @@ -453,22 +453,108 @@ static bool areEqualIntegers(const Expr *E1, const Expr *E2, ASTContext &Ctx) { } } +// Providing that `Ptr` is a pointer and `Size` is an unsigned-integral +// expression, returns true iff they follow one of the following safe +// patterns: +// 1. Ptr is `DRE.data()` and Size is `DRE.size()`, where DRE is a hardened +// container or view; +// +// 2. Ptr is `a` and Size is `n`, where `a` is of an array-of-T with constant +// size `n`; +// +// 3. Ptr is `&var` and Size is `1`; or +// Ptr is `std::addressof(...)` and Size is `1`; +// +// 4. Size is `0`; +static bool isPtrBufferSafe(const Expr *Ptr, const Expr *Size, + ASTContext &Ctx) { + // Pattern 1: + if (auto *MCEPtr = dyn_cast<CXXMemberCallExpr>(Ptr->IgnoreParenImpCasts())) + if (auto *MCESize = + dyn_cast<CXXMemberCallExpr>(Size->IgnoreParenImpCasts())) { + auto *DREOfPtr = dyn_cast<DeclRefExpr>( + MCEPtr->getImplicitObjectArgument()->IgnoreParenImpCasts()); + auto *DREOfSize = dyn_cast<DeclRefExpr>( + MCESize->getImplicitObjectArgument()->IgnoreParenImpCasts()); + + if (!DREOfPtr || !DREOfSize) + return false; // not in safe pattern + if (DREOfPtr->getDecl() != DREOfSize->getDecl()) + return false; + if (MCEPtr->getMethodDecl()->getName() != "data") + return false; + // `MCEPtr->getRecordDecl()` must be non-null as `DREOfPtr` is non-null: + if (!MCEPtr->getRecordDecl()->isInStdNamespace()) + return false; + + auto *ObjII = MCEPtr->getRecordDecl()->getIdentifier(); ---------------- ziqingluo-90 wrote:
I guess it is possible that the standard library implementation uses any kind of anonymous records. https://github.com/llvm/llvm-project/pull/145626 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits