Author: Adam Balogh Date: 2020-07-01T09:04:27+02:00 New Revision: 4da65c2920b68a1cf47054a7d655cc2a19a4aa28
URL: https://github.com/llvm/llvm-project/commit/4da65c2920b68a1cf47054a7d655cc2a19a4aa28 DIFF: https://github.com/llvm/llvm-project/commit/4da65c2920b68a1cf47054a7d655cc2a19a4aa28.diff LOG: [clang-tidy] New util `Aliasing` factored out from `bugprone-infinite-loop` Function `hasPtrOrReferenceInfFunc()` of `bugprone-infinite-loop` is a generic function which could be reused in another checks. This patch moves this function into a newly created utility module. Differential Revision: https://reviews.llvm.org/D81396 Added: clang-tools-extra/clang-tidy/utils/Aliasing.cpp clang-tools-extra/clang-tidy/utils/Aliasing.h Modified: clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp clang-tools-extra/clang-tidy/utils/CMakeLists.txt Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp index c9dd47ef0cf9..310fbec72a50 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp @@ -10,8 +10,10 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Analysis/Analyses/ExprMutationAnalyzer.h" +#include "../utils/Aliasing.h" using namespace clang::ast_matchers; +using clang::tidy::utils::hasPtrOrReferenceInFunc; namespace clang { namespace tidy { @@ -24,54 +26,6 @@ loopEndingStmt(internal::Matcher<Stmt> Internal) { callExpr(Internal, callee(functionDecl(isNoReturn()))))); } -/// Return whether `S` is a reference to the declaration of `Var`. -static bool isAccessForVar(const Stmt *S, const VarDecl *Var) { - if (const auto *DRE = dyn_cast<DeclRefExpr>(S)) - return DRE->getDecl() == Var; - - return false; -} - -/// Return whether `Var` has a pointer or reference in `S`. -static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) { - if (const auto *DS = dyn_cast<DeclStmt>(S)) { - for (const Decl *D : DS->getDeclGroup()) { - if (const auto *LeftVar = dyn_cast<VarDecl>(D)) { - if (LeftVar->hasInit() && LeftVar->getType()->isReferenceType()) { - return isAccessForVar(LeftVar->getInit(), Var); - } - } - } - } else if (const auto *UnOp = dyn_cast<UnaryOperator>(S)) { - if (UnOp->getOpcode() == UO_AddrOf) - return isAccessForVar(UnOp->getSubExpr(), Var); - } - - return false; -} - -/// Return whether `Var` has a pointer or reference in `S`. -static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) { - if (isPtrOrReferenceForVar(S, Var)) - return true; - - for (const Stmt *Child : S->children()) { - if (!Child) - continue; - - if (hasPtrOrReferenceInStmt(Child, Var)) - return true; - } - - return false; -} - -/// Return whether `Var` has a pointer or reference in `Func`. -static bool hasPtrOrReferenceInFunc(const FunctionDecl *Func, - const VarDecl *Var) { - return hasPtrOrReferenceInStmt(Func->getBody(), Var); -} - /// Return whether `Var` was changed in `LoopStmt`. static bool isChanged(const Stmt *LoopStmt, const VarDecl *Var, ASTContext *Context) { diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp new file mode 100644 index 000000000000..3a88126a9ee6 --- /dev/null +++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp @@ -0,0 +1,65 @@ +//===------------- Aliasing.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 "Aliasing.h" + +#include "clang/AST/Expr.h" + +namespace clang { +namespace tidy { +namespace utils { + +/// Return whether \p S is a reference to the declaration of \p Var. +static bool isAccessForVar(const Stmt *S, const VarDecl *Var) { + if (const auto *DRE = dyn_cast<DeclRefExpr>(S)) + return DRE->getDecl() == Var; + + return false; +} + +/// Return whether \p Var has a pointer or reference in \p S. +static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) { + if (const auto *DS = dyn_cast<DeclStmt>(S)) { + for (const Decl *D : DS->getDeclGroup()) { + if (const auto *LeftVar = dyn_cast<VarDecl>(D)) { + if (LeftVar->hasInit() && LeftVar->getType()->isReferenceType()) { + return isAccessForVar(LeftVar->getInit(), Var); + } + } + } + } else if (const auto *UnOp = dyn_cast<UnaryOperator>(S)) { + if (UnOp->getOpcode() == UO_AddrOf) + return isAccessForVar(UnOp->getSubExpr(), Var); + } + + return false; +} + +/// Return whether \p Var has a pointer or reference in \p S. +static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) { + if (isPtrOrReferenceForVar(S, Var)) + return true; + + for (const Stmt *Child : S->children()) { + if (!Child) + continue; + + if (hasPtrOrReferenceInStmt(Child, Var)) + return true; + } + + return false; +} + +bool hasPtrOrReferenceInFunc(const FunctionDecl *Func, const VarDecl *Var) { + return hasPtrOrReferenceInStmt(Func->getBody(), Var); +} + +} // namespace utils +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.h b/clang-tools-extra/clang-tidy/utils/Aliasing.h new file mode 100644 index 000000000000..e43995a6714a --- /dev/null +++ b/clang-tools-extra/clang-tidy/utils/Aliasing.h @@ -0,0 +1,36 @@ +//===------------- Aliasing.h - 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_ALIASING_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_ALIASING_H + +#include "clang/AST/Decl.h" + +namespace clang { +namespace tidy { +namespace utils { + +/// Returns whether \p Var has a pointer or reference in \p Func. +/// +/// Example: +/// void f() { +/// int n; +/// ... +/// int *p = &n; +/// } +/// +/// For `f()` and `n` the function returns ``true`` because `p` is a +/// pointer to `n` created in `f()`. + +bool hasPtrOrReferenceInFunc(const FunctionDecl *Func, const VarDecl *Var); + +} // namespace utils +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_ALIASING_H diff --git a/clang-tools-extra/clang-tidy/utils/CMakeLists.txt b/clang-tools-extra/clang-tidy/utils/CMakeLists.txt index e42d6922f469..70edb9c33d74 100644 --- a/clang-tools-extra/clang-tidy/utils/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/utils/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangTidyUtils + Aliasing.cpp ASTUtils.cpp DeclRefExprUtils.cpp ExceptionAnalyzer.cpp _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits