summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2018-02-28 14:47:20 +0000
committerAlexander Kornienko <alexfh@google.com>2018-02-28 14:47:20 +0000
commita1a29336340080d33893f82d5bf369df11615d58 (patch)
tree201f199921c8ee58b8abe9665390d829128af9f8 /clang-tools-extra/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
parent7e4eee98311dcecc782a93265e62934570e096c1 (diff)
downloadbcm5719-llvm-a1a29336340080d33893f82d5bf369df11615d58.tar.gz
bcm5719-llvm-a1a29336340080d33893f82d5bf369df11615d58.zip
Rename a few checks from misc- to bugprone-.
Summary: rename_check.py {misc,bugprone}-forwarding-reference-overload rename_check.py {misc,bugprone}-macro-repeated-side-effects rename_check.py {misc,bugprone}-lambda-function-name rename_check.py {misc,bugprone}-misplaced-widening-cast Reviewers: hokein, sammccall, aaron.ballman Reviewed By: aaron.ballman Subscribers: klimek, cfe-commits, mgorny Differential Revision: https://reviews.llvm.org/D43867 llvm-svn: 326327
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp184
1 files changed, 0 insertions, 184 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp b/clang-tools-extra/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
deleted file mode 100644
index 1bbed46b3dd..00000000000
--- a/clang-tools-extra/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-//===--- MacroRepeatedSideEffectsCheck.cpp - clang-tidy--------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MacroRepeatedSideEffectsCheck.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Lex/MacroArgs.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/Preprocessor.h"
-
-namespace clang {
-namespace tidy {
-namespace misc {
-
-namespace {
-class MacroRepeatedPPCallbacks : public PPCallbacks {
-public:
- MacroRepeatedPPCallbacks(ClangTidyCheck &Check, Preprocessor &PP)
- : Check(Check), PP(PP) {}
-
- void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
- SourceRange Range, const MacroArgs *Args) override;
-
-private:
- ClangTidyCheck &Check;
- Preprocessor &PP;
-
- unsigned countArgumentExpansions(const MacroInfo *MI,
- const IdentifierInfo *Arg) const;
-
- bool hasSideEffects(const Token *ResultArgToks) const;
-};
-} // End of anonymous namespace.
-
-void MacroRepeatedPPCallbacks::MacroExpands(const Token &MacroNameTok,
- const MacroDefinition &MD,
- SourceRange Range,
- const MacroArgs *Args) {
- // Ignore macro argument expansions.
- if (!Range.getBegin().isFileID())
- return;
-
- const MacroInfo *MI = MD.getMacroInfo();
-
- // Bail out if the contents of the macro are containing keywords that are
- // making the macro too complex.
- if (std::find_if(
- MI->tokens().begin(), MI->tokens().end(), [](const Token &T) {
- return T.isOneOf(tok::kw_if, tok::kw_else, tok::kw_switch,
- tok::kw_case, tok::kw_break, tok::kw_while,
- tok::kw_do, tok::kw_for, tok::kw_continue,
- tok::kw_goto, tok::kw_return);
- }) != MI->tokens().end())
- return;
-
- for (unsigned ArgNo = 0U; ArgNo < MI->getNumParams(); ++ArgNo) {
- const IdentifierInfo *Arg = *(MI->param_begin() + ArgNo);
- const Token *ResultArgToks = Args->getUnexpArgument(ArgNo);
-
- if (hasSideEffects(ResultArgToks) &&
- countArgumentExpansions(MI, Arg) >= 2) {
- Check.diag(ResultArgToks->getLocation(),
- "side effects in the %ordinal0 macro argument %1 are "
- "repeated in macro expansion")
- << (ArgNo + 1) << Arg;
- Check.diag(MI->getDefinitionLoc(), "macro %0 defined here",
- DiagnosticIDs::Note)
- << MacroNameTok.getIdentifierInfo();
- }
- }
-}
-
-unsigned MacroRepeatedPPCallbacks::countArgumentExpansions(
- const MacroInfo *MI, const IdentifierInfo *Arg) const {
- // Current argument count. When moving forward to a different control-flow
- // path this can decrease.
- unsigned Current = 0;
- // Max argument count.
- unsigned Max = 0;
- bool SkipParen = false;
- int SkipParenCount = 0;
- // Has a __builtin_constant_p been found?
- bool FoundBuiltin = false;
- bool PrevTokenIsHash = false;
- // Count when "?" is reached. The "Current" will get this value when the ":"
- // is reached.
- std::stack<unsigned, SmallVector<unsigned, 8>> CountAtQuestion;
- for (const auto &T : MI->tokens()) {
- // The result of __builtin_constant_p(x) is 0 if x is a macro argument
- // with side effects. If we see a __builtin_constant_p(x) followed by a
- // "?" "&&" or "||", then we need to reason about control flow to report
- // warnings correctly. Until such reasoning is added, bail out when this
- // happens.
- if (FoundBuiltin && T.isOneOf(tok::question, tok::ampamp, tok::pipepipe))
- return Max;
-
- // Skip stringified tokens.
- if (T.is(tok::hash)) {
- PrevTokenIsHash = true;
- continue;
- }
- if (PrevTokenIsHash) {
- PrevTokenIsHash = false;
- continue;
- }
-
- // Handling of ? and :.
- if (T.is(tok::question)) {
- CountAtQuestion.push(Current);
- } else if (T.is(tok::colon)) {
- if (CountAtQuestion.empty())
- return 0;
- Current = CountAtQuestion.top();
- CountAtQuestion.pop();
- }
-
- // If current token is a parenthesis, skip it.
- if (SkipParen) {
- if (T.is(tok::l_paren))
- SkipParenCount++;
- else if (T.is(tok::r_paren))
- SkipParenCount--;
- SkipParen = (SkipParenCount != 0);
- if (SkipParen)
- continue;
- }
-
- IdentifierInfo *TII = T.getIdentifierInfo();
- // If not existent, skip it.
- if (TII == nullptr)
- continue;
-
- // If a __builtin_constant_p is found within the macro definition, don't
- // count arguments inside the parentheses and remember that it has been
- // seen in case there are "?", "&&" or "||" operators later.
- if (TII->getBuiltinID() == Builtin::BI__builtin_constant_p) {
- FoundBuiltin = true;
- SkipParen = true;
- continue;
- }
-
- // If another macro is found within the macro definition, skip the macro
- // and the eventual arguments.
- if (TII->hasMacroDefinition()) {
- const MacroInfo *M = PP.getMacroDefinition(TII).getMacroInfo();
- if (M != nullptr && M->isFunctionLike())
- SkipParen = true;
- continue;
- }
-
- // Count argument.
- if (TII == Arg) {
- Current++;
- if (Current > Max)
- Max = Current;
- }
- }
- return Max;
-}
-
-bool MacroRepeatedPPCallbacks::hasSideEffects(
- const Token *ResultArgToks) const {
- for (; ResultArgToks->isNot(tok::eof); ++ResultArgToks) {
- if (ResultArgToks->isOneOf(tok::plusplus, tok::minusminus))
- return true;
- }
- return false;
-}
-
-void MacroRepeatedSideEffectsCheck::registerPPCallbacks(
- CompilerInstance &Compiler) {
- Compiler.getPreprocessor().addPPCallbacks(
- ::llvm::make_unique<MacroRepeatedPPCallbacks>(
- *this, Compiler.getPreprocessor()));
-}
-
-} // namespace misc
-} // namespace tidy
-} // namespace clang
OpenPOWER on IntegriCloud