================ @@ -0,0 +1,756 @@ +//===--- IncorrectIteratorsCheck.cpp - clang-tidy -------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "IncorrectIteratorsCheck.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/ErrorHandling.h" +#include <functional> + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +using SVU = llvm::SmallVector<unsigned, 3>; +/// Checks to see if a all the parameters of a template function with a given +/// index refer to the same type. +AST_MATCHER_P(FunctionDecl, areParametersSameTemplateType, SVU, Indexes) { + const FunctionTemplateDecl *TemplateDecl = Node.getPrimaryTemplate(); + if (!TemplateDecl) + return false; + const FunctionDecl *FuncDecl = TemplateDecl->getTemplatedDecl(); + if (!FuncDecl) + return false; + assert(!Indexes.empty()); + if (llvm::any_of(Indexes, [Count(FuncDecl->getNumParams())](unsigned Index) { + return Index >= Count; + })) + return false; + const ParmVarDecl *FirstParam = FuncDecl->getParamDecl(Indexes.front()); + if (!FirstParam) + return false; + QualType Type = FirstParam->getOriginalType(); + for (auto Item : llvm::drop_begin(Indexes)) { + const ParmVarDecl *Param = FuncDecl->getParamDecl(Item); + if (!Param) + return false; + if (Param->getOriginalType() != Type) + return false; + } + return true; +} +AST_MATCHER_P(FunctionDecl, isParameterTypeUnique, unsigned, Index) { + const FunctionTemplateDecl *TemplateDecl = Node.getPrimaryTemplate(); + if (!TemplateDecl) + return false; + const FunctionDecl *FuncDecl = TemplateDecl->getTemplatedDecl(); + if (!FuncDecl) + return false; + if (Index >= FuncDecl->getNumParams()) + return false; + const ParmVarDecl *MainParam = FuncDecl->getParamDecl(Index); + if (!MainParam) + return false; + QualType Type = MainParam->getOriginalType(); + for (unsigned I = 0, E = FuncDecl->getNumParams(); I != E; ++I) { + if (I == Index) + continue; + const ParmVarDecl *Param = FuncDecl->getParamDecl(I); + if (!Param) + continue; + if (Param->getOriginalType() == Type) + return false; + } + return true; +} +struct NameMatchers { + ArrayRef<StringRef> FreeNames; + ArrayRef<StringRef> MethodNames; +}; + +struct NamePairs { + NameMatchers BeginNames; + NameMatchers EndNames; +}; + +struct FullState { + NamePairs Forward; + NamePairs Reversed; + NamePairs Combined; + NameMatchers All; + ArrayRef<StringRef> MakeReverseIterator; +}; + +} // namespace + +static constexpr char FirstRangeArg[] = "FirstRangeArg"; +static constexpr char FirstRangeArgExpr[] = "FirstRangeArgExpr"; +static constexpr char ReverseBeginBind[] = "ReverseBeginBind"; +static constexpr char ReverseEndBind[] = "ReverseEndBind"; +static constexpr char SecondRangeArg[] = "SecondRangeArg"; +static constexpr char SecondRangeArgExpr[] = "SecondRangeArgExpr"; +static constexpr char ArgMismatchBegin[] = "ArgMismatchBegin"; +static constexpr char ArgMismatchEnd[] = "ArgMismatchEnd"; +static constexpr char ArgMismatchExpr[] = "ArgMismatchExpr"; +static constexpr char ArgMismatchRevBind[] = "ArgMismatchRevBind"; +static constexpr char Callee[] = "Callee"; +static constexpr char Internal[] = "Internal"; +static constexpr char InternalOther[] = "InternalOther"; +static constexpr char InternalArgument[] = "InternalArgument"; +static constexpr char OutputRangeEnd[] = "OutputRangeEnd"; +static constexpr char OutputRangeBegin[] = "OutputRangeBegin"; + +static auto +makeExprMatcher(ast_matchers::internal::Matcher<Expr> ArgumentMatcher, + const NameMatchers &Names, ArrayRef<StringRef> MakeReverse, + const NameMatchers &RevNames, StringRef RevBind) { + return expr(anyOf( + cxxMemberCallExpr(argumentCountIs(0), + callee(cxxMethodDecl(hasAnyName(Names.MethodNames))), + on(ArgumentMatcher)), + callExpr(argumentCountIs(1), + hasDeclaration(functionDecl(hasAnyName(Names.FreeNames))), + hasArgument(0, ArgumentMatcher)), + callExpr( + callee(functionDecl(hasAnyName(MakeReverse))), argumentCountIs(1), ---------------- 5chmidti wrote:
It would be better to check the argument count before matching the name https://github.com/llvm/llvm-project/pull/99917 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits