diff options
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 693d759db2..44504971d8 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -6564,6 +6564,25 @@ template <typename T> static bool isRecordWithAttr(QualType Type) { return false; } +static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { + if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee)) + if (isRecordWithAttr<PointerAttr>(Conv->getConversionType())) + return true; + if (!Callee->getParent()->isInStdNamespace() || !Callee->getIdentifier()) + return false; + if (!isRecordWithAttr<PointerAttr>(Callee->getThisObjectType()) && + !isRecordWithAttr<OwnerAttr>(Callee->getThisObjectType())) + return false; + if (!isRecordWithAttr<PointerAttr>(Callee->getReturnType()) && + !Callee->getReturnType()->isPointerType()) + return false; + return llvm::StringSwitch<bool>(Callee->getName()) + .Cases("begin", "rbegin", "cbegin", "crbegin", true) + .Cases("end", "rend", "cend", "crend", true) + .Cases("c_str", "data", "get", true) + .Default(false); +} + static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call, LocalVisitor Visit) { auto VisitPointerArg = [&](const Decl *D, Expr *Arg) { @@ -6577,10 +6596,9 @@ static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call, }; if (auto *MCE = dyn_cast<CXXMemberCallExpr>(Call)) { - const FunctionDecl *Callee = MCE->getDirectCallee(); - if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee)) - if (isRecordWithAttr<PointerAttr>(Conv->getConversionType())) - VisitPointerArg(Callee, MCE->getImplicitObjectArgument()); + const auto *MD = cast_or_null<CXXMethodDecl>(MCE->getDirectCallee()); + if (MD && shouldTrackImplicitObjectArg(MD)) + VisitPointerArg(MD, MCE->getImplicitObjectArgument()); return; } |