Now it doesn't warn about macros in system headers.
I have now tested it on 18045 files in 381 debian projects.
I saw warnings in 4 projects. In two projects I believe there are bugs. Imo the
other two projects had false positives for these reasons:
1. repeated side effects is intended.
2. argument with side effects is repeated in macro, but in different
conditional code paths, side effect is not repeated
For #1 I think the only reasonable solution is that this checker must be
disabled by the user.
For #2 I think we could maybe fix some FPs in clang tidy by analysing the
tokens. But it's not going to be easy and solid imho. I recommend that these
users disable this warning. If we bailout when there are different conditional
code paths there will be false negatives.
http://reviews.llvm.org/D9496
Files:
clang-tidy/misc/CMakeLists.txt
clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
clang-tidy/misc/MacroRepeatedSideEffectsCheck.h
clang-tidy/misc/MiscTidyModule.cpp
test/clang-tidy/misc-repeated-side-effects-in-macro.c
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: test/clang-tidy/misc-repeated-side-effects-in-macro.c
===================================================================
--- test/clang-tidy/misc-repeated-side-effects-in-macro.c
+++ test/clang-tidy/misc-repeated-side-effects-in-macro.c
@@ -0,0 +1,32 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-macro-repeated-side-effects %t
+// REQUIRES: shell
+
+#define MIN(A,B) (((A)<(B)) ? (A) : (B))
+
+void plusplus1() {
+ int j = 0;
+ int i = 0;
+ int min = MIN(i++, j);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: side effects in macro argument is repeated in macro expansion [misc-macro-repeated-side-effects]
+}
+
+void plusplus2() {
+ int j = 0;
+ int i = 0;
+ int min = MIN(++i, j);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: side effects in macro argument is repeated in macro expansion [misc-macro-repeated-side-effects]
+}
+
+void minusminus1() {
+ int j = 0;
+ int i = 0;
+ int min = MIN(i--, j);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: side effects in macro argument is repeated in macro expansion [misc-macro-repeated-side-effects]
+}
+
+void minusminus2() {
+ int j = 0;
+ int i = 0;
+ int min = MIN(--i, j);
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: side effects in macro argument is repeated in macro expansion [misc-macro-repeated-side-effects]
+}
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -16,6 +16,7 @@
#include "BoolPointerImplicitConversionCheck.h"
#include "InaccurateEraseCheck.h"
#include "InefficientAlgorithmCheck.h"
+#include "MacroRepeatedSideEffectsCheck.h"
#include "StaticAssertCheck.h"
#include "SwappedArgumentsCheck.h"
#include "UndelegatedConstructor.h"
@@ -41,6 +42,8 @@
"misc-inaccurate-erase");
CheckFactories.registerCheck<InefficientAlgorithmCheck>(
"misc-inefficient-algorithm");
+ CheckFactories.registerCheck<MacroRepeatedSideEffectsCheck>(
+ "misc-macro-repeated-side-effects");
CheckFactories.registerCheck<StaticAssertCheck>(
"misc-static-assert");
CheckFactories.registerCheck<SwappedArgumentsCheck>(
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -7,6 +7,7 @@
BoolPointerImplicitConversionCheck.cpp
InaccurateEraseCheck.cpp
InefficientAlgorithmCheck.cpp
+ MacroRepeatedSideEffectsCheck.cpp
MiscTidyModule.cpp
StaticAssertCheck.cpp
SwappedArgumentsCheck.cpp
Index: clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
===================================================================
--- clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
+++ clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
@@ -0,0 +1,100 @@
+//===--- 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/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/MacroArgs.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+namespace {
+class MacroRepeatedPPCallbacks : public PPCallbacks {
+public:
+ MacroRepeatedPPCallbacks(ClangTidyCheck &Check, SourceManager &SM,
+ Preprocessor &PP)
+ : Check(Check), SM(SM), PP(PP) {}
+
+ void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
+ SourceRange Range, const MacroArgs *Args) override;
+
+private:
+ ClangTidyCheck &Check;
+ SourceManager &SM;
+ Preprocessor &PP;
+};
+} // namespace
+
+void MacroRepeatedPPCallbacks::MacroExpands(const Token &MacroNameTok,
+ const MacroDefinition &MD,
+ SourceRange Range,
+ const MacroArgs *Args) {
+ clang::SourceLocation Loc = Range.getBegin();
+ // Ignore macro argument expansions.
+ if (!Loc.isFileID())
+ return;
+
+ const clang::MacroInfo *MI = MD.getMacroInfo();
+
+ typedef clang::MacroInfo::tokens_iterator TokIter;
+ typedef clang::MacroInfo::arg_iterator ArgIter;
+ for (ArgIter AI = MI->arg_begin(), AE = MI->arg_end(); AI != AE; ++AI) {
+ const clang::Token *ResultArgToks =
+ Args->getUnexpArgument(MI->getArgumentNum((*AI)));
+ int CountInMacro = 0;
+ for (TokIter TI = MI->tokens_begin(), TE = MI->tokens_end(); TI != TE;
+ ++TI) {
+ clang::IdentifierInfo *TII = TI->getIdentifierInfo();
+ int ArgNo = (TII ? MI->getArgumentNum(TII) : -1);
+ if (ArgNo == -1) {
+ // This isn't an argument, continue.
+ continue;
+ }
+ const clang::Token *Res = Args->getUnexpArgument(ArgNo);
+ if (ResultArgToks == Res)
+ CountInMacro++;
+ }
+
+ if (CountInMacro < 2)
+ continue;
+
+ // If the arg token didn't expand into anything, ignore it.
+ if (ResultArgToks->is(clang::tok::eof))
+ continue;
+ unsigned NumToks = clang::MacroArgs::getArgLength(ResultArgToks);
+
+ // Check for sideeffects in the argument expansions.
+ for (unsigned ArgumentIndex = 0; ArgumentIndex < NumToks; ++ArgumentIndex) {
+ const clang::Token &AT = ResultArgToks[ArgumentIndex];
+
+ if (AT.is(clang::tok::plusplus) || AT.is(clang::tok::minusminus)) {
+ Check.diag(
+ ResultArgToks->getLocation(),
+ "side effects in macro argument is repeated in macro expansion");
+ Check.diag(MI->getDefinitionLoc(), "%0 macro defined here",
+ DiagnosticIDs::Note)
+ << MacroNameTok.getIdentifierInfo();
+ }
+ }
+ }
+}
+
+void MacroRepeatedSideEffectsCheck::registerPPCallbacks(
+ CompilerInstance &Compiler) {
+ Compiler.getPreprocessor().addPPCallbacks(
+ ::llvm::make_unique<MacroRepeatedPPCallbacks>(
+ *this, Compiler.getSourceManager(), Compiler.getPreprocessor()));
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/MacroRepeatedSideEffectsCheck.h
===================================================================
--- clang-tidy/misc/MacroRepeatedSideEffectsCheck.h
+++ clang-tidy/misc/MacroRepeatedSideEffectsCheck.h
@@ -0,0 +1,32 @@
+//===--- MacroRepeatedSideEffectsCheck.h - clang-tidy -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MACRO_REPEATED_SIDE_EFFECTS_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MACRO_REPEATED_SIDE_EFFECTS_CHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// \brief Checks for repeated side effects in macros.
+///
+class MacroRepeatedSideEffectsCheck : public ClangTidyCheck {
+public:
+ MacroRepeatedSideEffectsCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerPPCallbacks(CompilerInstance &Compiler) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MACRO_REPEATED_SIDE_EFFECTS_CHECK_H
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits