[PATCH] D20053: [clang-tidy] Add misc-unnecessary-mutable check.
mnbvmar created this revision. mnbvmar added a reviewer: alexfh. mnbvmar added subscribers: krystyna, sbarzowski, Prazek, staronj, cfe-commits. This implements unnecessary-mutable check. It's still bug-prone and might produce false positives, so all suggestions are welcome. http://reviews.llvm.org/D20053 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/UnnecessaryMutableCheck.cpp clang-tidy/misc/UnnecessaryMutableCheck.h docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-unnecessary-mutable.rst test/clang-tidy/misc-unnecessary-mutable.cpp Index: test/clang-tidy/misc-unnecessary-mutable.cpp === --- /dev/null +++ test/clang-tidy/misc-unnecessary-mutable.cpp @@ -0,0 +1,354 @@ +// RUN: %check_clang_tidy %s misc-unnecessary-mutable %t + +struct NothingMutable { + int field1; + unsigned field2; + const int field3; + volatile float field4; + + NothingMutable(int a1, unsigned a2, int a3, float a4) : field1(a1), field2(a2), field3(a3), field4(a4) {} + + void doSomething() { +field1 = 1; +field2 = 2; +field4 = 4; + } +}; + +struct NoMethods { + int field1; + mutable unsigned field2; // These cannot be fixed; they're public + const int field3; + mutable volatile NothingMutable field4; +}; + +class NoMethodsClass { +public: + int field1; + mutable unsigned field2; + +private: + const int field3; + mutable volatile NothingMutable field4; + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'mutable' modifier is unnecessary for field 'field4' [misc-unnecessary-mutable] + // CHECK-FIXES: {{^ }}volatile NothingMutable field4; +}; + +struct PrivateInStruct { +private: + mutable volatile unsigned long long blah; + // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'mutable' modifier is unnecessary for field 'blah' {{..}} + // CHECK-FIXES: {{^ }}volatile unsigned long long blah; +}; + +union PrivateInUnion { +public: + int someField; + +private: + mutable char otherField; +}; + +class UnusedVar { +private: + mutable int x __attribute__((unused)); + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'x' {{..}} + // CHECK-FIXES: {{^ }}int x __attribute__((unused)); +}; + +class NoConstMethodsClass { +public: + int field1; + mutable unsigned field2; + + NoConstMethodsClass() : field2(42), field3(9), field4(NothingMutable(1, 2, 3, 4)) {} + + void doSomething() { +field2 = 8; +field1 = 99; +field4.doSomething(); + } + +private: + const int field3; + mutable NothingMutable field4; + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'mutable' modifier is unnecessary for field 'field4' {{..}} + // CHECK-FIXES: {{^ }}NothingMutable field4; +}; + +class ConstMethods { +private: + mutable int field1, field2; + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'mutable' modifier is unnecessary for field 'field2' {{..}} + mutable int incr, decr, set, mul, constArg1, constArg2, constRef, ref1, ref2; + // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'mutable' modifier is unnecessary for field 'constArg1' {{..}} + // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'mutable' modifier is unnecessary for field 'constArg2' {{..}} + // CHECK-MESSAGES: :[[@LINE-3]]:59: warning: 'mutable' modifier is unnecessary for field 'constRef' {{..}} + + void takeArg(int x) const { x *= 4; } + int takeConstRef(const int &x) const { return x + 99; } + void takeRef(int &) const {} + + template + void takeArgs(Args... args) const {} + template + void takeArgRefs(Args &... args) const {} + +public: + void doSomething() const { +field1 = field2; + } + + void doOtherThing() const { +incr++; +decr--; +set = 42; +mul *= 3; +takeArg(constArg1); +takeConstRef(constRef); +takeRef(ref1); +takeArgs(constArg1, constArg2); +takeArgRefs(ref1, ref2); + } +}; + +class NonFinalClass { +public: + mutable int fPublic; + +protected: + mutable int fProtected; + +private: + mutable int fPrivate; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'fPrivate' {{..}} + // CHECK-FIXES: {{^ }}int fPrivate; +}; + +class FinalClass final { +public: + mutable int fPublic; + +protected: + mutable int fProtected; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'fProtected' {{..}} + // CHECK-FIXES: {{^ }}int fProtected; + +private: + mutable int fPrivate; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'fPrivate' {{..}} + // CHECK-FIXES: {{^ }}int fPrivate; +}; + +class NotAllFuncsKnown { + void doSomething(); + void doSomethingConst() const {} + +private: + mutable int field; + // Can't be fixed. We don't know if doSomething() doesn't declare a *const* NotAllFuncsKnown instance + // and then modify 'field' field. +}; + +class NotAllConstFuncsKnown { + void doSomething() {} + void doSomethingC
Re: [PATCH] D18745: [clang-tidy] Adds modernize-use-bool-literals check.
mnbvmar added a comment. You could also think whether char literals should be converted to true/false, too. Apart from this (and other people's doubts), everything's fine. http://reviews.llvm.org/D18745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18821: Add modernize-bool-to-integer-conversion
mnbvmar added a comment. This check throws a warning also on the conversion to floats (probably very rare ones): double number = true; Even though this behavior is correct, the code warns about the implicit conversion to **integers**. Comment at: docs/ReleaseNotes.rst:119 @@ +118,3 @@ + + Replaces implicit cast from bool literals to integers to int literals. + **with** int literals http://reviews.llvm.org/D18821 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D19165: [clang-tidy] Add modernize-increment-bool check.
mnbvmar created this revision. mnbvmar added reviewers: alexfh, Prazek, staronj, krystyna. mnbvmar added a subscriber: cfe-commits. http://reviews.llvm.org/D19165 Files: clang-tidy/modernize/CMakeLists.txt clang-tidy/modernize/IncrementBoolCheck.cpp clang-tidy/modernize/IncrementBoolCheck.h clang-tidy/modernize/ModernizeTidyModule.cpp docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/modernize-increment-bool.rst test/clang-tidy/modernize-increment-bool.cpp Index: test/clang-tidy/modernize-increment-bool.cpp === --- /dev/null +++ test/clang-tidy/modernize-increment-bool.cpp @@ -0,0 +1,55 @@ +// RUN: %check_clang_tidy %s modernize-increment-bool %t + +template +T& f(T &x) { return x; } + +template +void g() { + T x; + x++; + + bool y; + y++; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment +// CHECK-FIXES: y = true; +} + +int main() { + bool b1 = false, b2 = false, b3 = false; + + b1++; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment +// CHECK-FIXES: b1 = true; + + bool b4 = f(b1)++; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: bool incrementation is deprecated, use assignment + + bool b5 = ++f(b1); +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: bool incrementation is deprecated, use assignment +// CHECK-FIXES: bool b5 = (f(b1) = true); + + (b1 = false)++; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment +// CHECK-FIXES: (b1 = false) = true; + + (b1 = b2 = false)++; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment +// CHECK-FIXES: (b1 = b2 = false) = true; + + ++(b1 = b2 = false); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment +// CHECK-FIXES: (b1 = b2 = false) = true; + + b3 = b1++ && b2; +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: bool incrementation is deprecated, use assignment + + b3 = ++(b1 |= b4) && b3; +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: bool incrementation is deprecated, use assignment +// CHECK-FIXES: b3 = ((b1 |= b4) = true) && b3; + + int x = 8; + x++; + + g(); + g(); +} Index: docs/clang-tidy/checks/modernize-increment-bool.rst === --- /dev/null +++ docs/clang-tidy/checks/modernize-increment-bool.rst @@ -0,0 +1,57 @@ +.. title:: clang-tidy - modernize-increment-bool + +modernize-increment-bool + + +This check detects the deprecated boolean type incrementation, and wherever possible, +converts it into truth assignment. + +C++17 forbids this behavior. Before C++17 this was equivalent to setting the variable +to true. + + +Example +--- + +Original: + +.. code-block:: c++ + + bool variable = false; + variable++; + ++variable; + + bool another = ++variable; + bool third = ++variable && another; + +After applying the check: + +.. code-block:: c++ + + bool variable = false; + variable = true; + variable = true; /* Both postfix and prefix incrementations are supported. */ + + bool another = (variable = true); + bool third = (variable = true) && another; + + +Limitations +--- + +When postfix boolean incrementation is not the outermost operation done in the instruction, +tool will not repair the problem (the fix would have to append some instructions after the +statement). For example: + +.. code-block:: c++ + + bool first = false, second; + + /* Equivalent to: +if (!first) { + second = false; + first = true; +} + */ + if (!first) second = first++; + Index: docs/clang-tidy/checks/list.rst === --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -77,6 +77,7 @@ misc-unused-raii misc-virtual-near-miss modernize-deprecated-headers + modernize-increment-bool modernize-loop-convert modernize-make-unique modernize-pass-by-value Index: clang-tidy/modernize/ModernizeTidyModule.cpp === --- clang-tidy/modernize/ModernizeTidyModule.cpp +++ clang-tidy/modernize/ModernizeTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "DeprecatedHeadersCheck.h" +#include "IncrementBoolCheck.h" #include "LoopConvertCheck.h" #include "MakeUniqueCheck.h" #include "PassByValueCheck.h" @@ -34,6 +35,8 @@ void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck( "modernize-deprecated-headers"); +CheckFactories.registerCheck( +"modernize-increment-bool"); CheckFactories.registerCheck("modernize-loop-convert"); CheckFactories.registerCheck("modernize-make-unique"); CheckFactories.registerCheck("modernize-pass-by-value"); Index: clang-tidy/mod
Re: [PATCH] D19165: [clang-tidy] Add modernize-increment-bool check.
mnbvmar updated this revision to Diff 58940. mnbvmar added a comment. Clang-formatted code. Added a simple macro test. Resolved @Prazek's issues. http://reviews.llvm.org/D19165 Files: clang-tidy/modernize/CMakeLists.txt clang-tidy/modernize/IncrementBoolCheck.cpp clang-tidy/modernize/IncrementBoolCheck.h clang-tidy/modernize/ModernizeTidyModule.cpp docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/modernize-increment-bool.rst test/clang-tidy/modernize-increment-bool.cpp Index: test/clang-tidy/modernize-increment-bool.cpp === --- /dev/null +++ test/clang-tidy/modernize-increment-bool.cpp @@ -0,0 +1,59 @@ +// RUN: %check_clang_tidy %s modernize-increment-bool %t + +#define INCR(var) ((var)++) + +template +T &f(T &x) { return x; } + +template +void g() { + T x; + x++; + + bool y; + y++; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment + // CHECK-FIXES: y = true; +} + +int main() { + bool b1 = false, b2 = false, b3 = false; + + b1++; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment + // CHECK-FIXES: b1 = true; + + bool b4 = f(b1)++; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: bool incrementation is deprecated, use assignment + + bool b5 = ++f(b1); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: bool incrementation is deprecated, use assignment + // CHECK-FIXES: bool b5 = (f(b1) = true); + + (b1 = false)++; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment + // CHECK-FIXES: (b1 = false) = true; + + (b1 = b2 = false)++; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment + // CHECK-FIXES: (b1 = b2 = false) = true; + + ++(b1 = b2 = false); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: bool incrementation is deprecated, use assignment + // CHECK-FIXES: (b1 = b2 = false) = true; + + b3 = b1++ && b2; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: bool incrementation is deprecated, use assignment + + b3 = ++(b1 |= b4) && b3; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: bool incrementation is deprecated, use assignment + // CHECK-FIXES: b3 = ((b1 |= b4) = true) && b3; + + int x = 8; + x++; + + INCR(b1); + + g(); + g(); +} Index: docs/clang-tidy/checks/modernize-increment-bool.rst === --- /dev/null +++ docs/clang-tidy/checks/modernize-increment-bool.rst @@ -0,0 +1,54 @@ +.. title:: clang-tidy - modernize-increment-bool + +modernize-increment-bool + + +This check detects the deprecated boolean type incrementation, and wherever possible, +converts it into truth assignment. + +C++17 forbids this behavior. Before C++17 this was equivalent to setting the variable +to true. + + +Example +--- + +Original: + +.. code-block:: c++ + + bool variable = false; + variable++; + ++variable; + + bool another = ++variable; + bool third = ++variable && another; + +After applying the check: + +.. code-block:: c++ + + bool variable = false; + variable = true; + variable = true; /* Both postfix and prefix incrementations are supported. */ + + bool another = (variable = true); + bool third = (variable = true) && another; + + +Limitations +--- + +When postfix boolean incrementation is not the outermost operation done in the instruction, +tool will not repair the problem (the fix would have to append some instructions after the +statement). For example: + +.. code-block:: c++ + + bool first = false, second; + second = first++; + + // Equivalent to: + second = false; + first = true; + Index: docs/clang-tidy/checks/list.rst === --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -91,6 +91,7 @@ misc-unused-using-decls misc-virtual-near-miss modernize-deprecated-headers + modernize-increment-bool modernize-loop-convert modernize-make-shared modernize-make-unique Index: clang-tidy/modernize/ModernizeTidyModule.cpp === --- clang-tidy/modernize/ModernizeTidyModule.cpp +++ clang-tidy/modernize/ModernizeTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "DeprecatedHeadersCheck.h" +#include "IncrementBoolCheck.h" #include "LoopConvertCheck.h" #include "MakeSharedCheck.h" #include "MakeUniqueCheck.h" @@ -35,6 +36,8 @@ void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck( "modernize-deprecated-headers"); +CheckFactories.registerCheck( +"modernize-increment-bool"); CheckFactories.registerCheck("modernize-loop-convert"); CheckFactories.registerCheck("modernize-make-shared"); CheckFactories.registerCheck("
Re: [PATCH] D20053: [clang-tidy] Add misc-unnecessary-mutable check.
mnbvmar updated this revision to Diff 59445. mnbvmar added a comment. Fixes done. Added macro test. Docs should be working now. Updated docs. http://reviews.llvm.org/D20053 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/MiscTidyModule.cpp clang-tidy/misc/UnnecessaryMutableCheck.cpp clang-tidy/misc/UnnecessaryMutableCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-unnecessary-mutable.rst test/clang-tidy/misc-unnecessary-mutable.cpp Index: test/clang-tidy/misc-unnecessary-mutable.cpp === --- /dev/null +++ test/clang-tidy/misc-unnecessary-mutable.cpp @@ -0,0 +1,377 @@ +// RUN: %check_clang_tidy %s misc-unnecessary-mutable %t + +struct NothingMutable { + int field1; + unsigned field2; + const int field3; + volatile float field4; + + NothingMutable(int a1, unsigned a2, int a3, float a4) : field1(a1), field2(a2), field3(a3), field4(a4) {} + + void doSomething() { +field1 = 1; +field2 = 2; +field4 = 4; + } +}; + +struct NoMethods { + int field1; + mutable unsigned field2; // These cannot be fixed; they're public + const int field3; + mutable volatile NothingMutable field4; +}; + +class NoMethodsClass { +public: + int field1; + mutable unsigned field2; + +private: + const int field3; + mutable volatile NothingMutable field4; + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'mutable' modifier is unnecessary for field 'field4' [misc-unnecessary-mutable] + // CHECK-FIXES: {{^ }}volatile NothingMutable field4; +}; + +struct PrivateInStruct { +private: + mutable volatile unsigned long long blah; + // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'mutable' modifier is unnecessary for field 'blah' {{..}} + // CHECK-FIXES: {{^ }}volatile unsigned long long blah; +}; + +union PrivateInUnion { +public: + int someField; + +private: + mutable char otherField; +}; + +class UnusedVar { +private: + mutable int x __attribute__((unused)); + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'x' {{..}} + // CHECK-FIXES: {{^ }}int x __attribute__((unused)); +}; + +class NoConstMethodsClass { +public: + int field1; + mutable unsigned field2; + + NoConstMethodsClass() : field2(42), field3(9), field4(NothingMutable(1, 2, 3, 4)) {} + + void doSomething() { +field2 = 8; +field1 = 99; +field4.doSomething(); + } + +private: + const int field3; + mutable NothingMutable field4; + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'mutable' modifier is unnecessary for field 'field4' {{..}} + // CHECK-FIXES: {{^ }}NothingMutable field4; +}; + +class ConstMethods { +private: + mutable int field1, field2; + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'mutable' modifier is unnecessary for field 'field2' {{..}} + mutable int incr, decr, set, mul, constArg1, constArg2, constRef, ref1, ref2; + // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'mutable' modifier is unnecessary for field 'constArg1' {{..}} + // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'mutable' modifier is unnecessary for field 'constArg2' {{..}} + // CHECK-MESSAGES: :[[@LINE-3]]:59: warning: 'mutable' modifier is unnecessary for field 'constRef' {{..}} + + void takeArg(int x) const { x *= 4; } + int takeConstRef(const int &x) const { return x + 99; } + void takeRef(int &) const {} + + template + void takeArgs(Args... args) const {} + template + void takeArgRefs(Args &... args) const {} + +public: + void doSomething() const { +field1 = field2; + } + + void doOtherThing() const { +incr++; +decr--; +set = 42; +mul *= 3; +takeArg(constArg1); +takeConstRef(constRef); +takeRef(ref1); +takeArgs(constArg1, constArg2); +takeArgRefs(ref1, ref2); + } +}; + +class NonFinalClass { +public: + mutable int fPublic; + +protected: + mutable int fProtected; + +private: + mutable int fPrivate; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'fPrivate' {{..}} + // CHECK-FIXES: {{^ }}int fPrivate; +}; + +class FinalClass final { +public: + mutable int fPublic; + +protected: + mutable int fProtected; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'fProtected' {{..}} + // CHECK-FIXES: {{^ }}int fProtected; + +private: + mutable int fPrivate; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'mutable' modifier is unnecessary for field 'fPrivate' {{..}} + // CHECK-FIXES: {{^ }}int fPrivate; +}; + +class NotAllFuncsKnown { + void doSomething(); + void doSomethingConst() const {} + +private: + mutable int field; + // Can't be fixed. We don't know if doSomething() doesn't declare a *const* NotAllFuncsKnown instance + // and then modify 'field' field. +}; + +class NotAllConstFuncsKnown { + void doSomething() {} + void doSomethingConst() const; + void doOtherConst() const {} + +private: + mutable int field; +}; + +class ConstFuncOutside
Re: [PATCH] D20053: [clang-tidy] Add misc-unnecessary-mutable check.
mnbvmar marked 14 inline comments as done. mnbvmar added a comment. http://reviews.llvm.org/D20053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20053: [clang-tidy] Add misc-unnecessary-mutable check.
mnbvmar added inline comments. Comment at: clang-tidy/misc/UnnecessaryMutableCheck.cpp:47 @@ +46,3 @@ + + void RunSearch(const Decl *Declaration) { +auto *Body = Declaration->getBody(); Unless I miss something, the moment we set FoundNonConstUse to true, we stop recurring both in FieldUseVisitor and ClassMethodVisitor. http://reviews.llvm.org/D20053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21303: [clang-tidy] Adds performance-returning-type check.
mnbvmar added inline comments. Comment at: clang-tidy/performance/ReturningTypeCheck.cpp:69 @@ +68,3 @@ +AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, + haveOneActiveArgument) { + return anyOf(parameterCountIs(1), Probably hasOneActiveArgument. Comment at: clang-tidy/performance/ReturningTypeCheck.cpp:72 @@ +71,3 @@ + allOf(unless(parameterCountIs(0)), + hasParameter(2, hasDefaultArgument(; +} In hasParameter(N, ...), argument id is 0-based. Did you mean to match the third parameter (1-based)? Repository: rL LLVM http://reviews.llvm.org/D21303 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits