diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2018-08-12 14:35:13 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2018-08-12 14:35:13 +0000 |
commit | bc8f5ac7541c863f83b53ed819292d79882ffe67 (patch) | |
tree | fec4d85effc5fbac5bb39cbedbdf7fc284dbfb5a /clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp | |
parent | bae6aab6fbe9fb655dd0f87d5075f4fc25d96491 (diff) | |
download | bcm5719-llvm-bc8f5ac7541c863f83b53ed819292d79882ffe67.tar.gz bcm5719-llvm-bc8f5ac7541c863f83b53ed819292d79882ffe67.zip |
Add a new check to the readability module that flags uses of "magic numbers" (both floating-point and integral).
Patch by Florin Iucha <florin@signbit.net>
llvm-svn: 339516
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp')
-rw-r--r-- | clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp b/clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp new file mode 100644 index 00000000000..3cf9dc52ea2 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp @@ -0,0 +1,199 @@ +// RUN: %check_clang_tidy %s readability-magic-numbers %t \ +// RUN: -config='{CheckOptions: \ +// RUN: [{key: readability-magic-numbers.IgnoredIntegerValues, value: "0;1;2;10;100;"}, \ +// RUN: {key: readability-magic-numbers.IgnoredFloatingPointValues, value: "3.14;2.71828;9.81;10000.0;101.0;0x1.2p3"}, \ +// RUN: {key: readability-magic-numbers.IgnorePowersOf2IntegerValues, value: 1}]}' \ +// RUN: -- + +template <typename T, int V> +struct ValueBucket { + T value[V]; +}; + +int BadGlobalInt = 5; +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 5 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + +int IntSquarer(int param) { + return param * param; +} + +void BuggyFunction() { + int BadLocalInt = 6; + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 6 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + + (void)IntSquarer(7); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 7 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + + int LocalArray[15]; + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 15 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + + for (int ii = 0; ii < 22; ++ii) + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 22 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + { + LocalArray[ii] = 3 * ii; + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + } + + ValueBucket<int, 66> Bucket; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 66 is a magic number; consider replacing it with a named constant [readability-magic-numbers] +} + +class TwoIntContainer { +public: + TwoIntContainer(int val) : anotherMember(val * val), yetAnotherMember(6), anotherConstant(val + val) {} + // CHECK-MESSAGES: :[[@LINE-1]]:73: warning: 6 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + + int getValue() const; + +private: + int oneMember = 9; + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 9 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + + int anotherMember; + + int yetAnotherMember; + + const int oneConstant = 2; + + const int anotherConstant; +}; + +int ValueArray[] = {3, 5}; +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers] +// CHECK-MESSAGES: :[[@LINE-2]]:24: warning: 5 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + +float FloatPiVariable = 3.1415926535f; +// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 3.1415926535f is a magic number; consider replacing it with a named constant [readability-magic-numbers] +double DoublePiVariable = 6.283185307; +// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 6.283185307 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + +float SomeFloats[] = {0.5, 0x1.2p4}; +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 0.5 is a magic number; consider replacing it with a named constant [readability-magic-numbers] +// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: 0x1.2p4 is a magic number; consider replacing it with a named constant [readability-magic-numbers] + +int getAnswer() { + if (ValueArray[0] < ValueArray[1]) + return ValueArray[1]; + + return -3; // FILENOTFOUND + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers] +} + +/* + * Clean code + */ + +#define INT_MACRO 5 + +const int GoodGlobalIntConstant = 42; + +constexpr int AlsoGoodGlobalIntConstant = 42; + +int InitializedByMacro = INT_MACRO; + +void SolidFunction() { + const int GoodLocalIntConstant = 43; + + (void)IntSquarer(GoodLocalIntConstant); + + int LocalArray[INT_MACRO]; + + ValueBucket<int, INT_MACRO> Bucket; +} + +const int ConstValueArray[] = {7, 9}; + +const int ConstValueArray2D[2][2] = {{7, 9}, {13, 15}}; + +/* + * no warnings for ignored values (specified in the configuration above) + */ +int GrandfatheredIntegerValues[] = {0, 1, 2, 10, 100, -1, -10, -100, 65536}; + +float GrandfatheredFloatValues[] = {3.14f, 3.14, 2.71828, 2.71828f, -1.01E2, 1E4, 0x1.2p3}; + +/* + * no warnings for enums + */ +enum Smorgasbord { + STARTER, + ALPHA = 3, + BETA = 1 << 5, +}; + +const float FloatPiConstant = 3.1415926535f; +const double DoublePiConstant = 6.283185307; + +const float Angles[] = {45.0f, 90.0f, 135.0f}; + +double DoubleZeroIsAccepted = 0.0; +float FloatZeroIsAccepted = 0.0f; + +namespace geometry { + +template <typename T> +struct Point { + T x; + T y; + + explicit Point(T xval, T yval) noexcept : x{xval}, y{yval} { + } +}; + +template <typename T> +struct Dimension { + T x; + T y; + + explicit Dimension(T xval, T yval) noexcept : x{xval}, y{yval} { + } +}; + +template <typename T> +struct Rectangle { + Point<T> origin; + Dimension<T> size; + T rotation; // angle of rotation around origin + + Rectangle(Point<T> origin_, Dimension<T> size_, T rotation_ = 0) noexcept : origin{origin_}, size{size_}, rotation{rotation_} { + } + + bool contains(Point<T> point) const; +}; + +} // namespace geometry + +const geometry::Rectangle<double> mandelbrotCanvas{geometry::Point<double>{-2.5, -1}, geometry::Dimension<double>{3.5, 2}}; + +// Simulate the macro magic in Google Test internal headers +class AssertionHelper { +public: + AssertionHelper(const char *Message, int LineNumber) : Message(Message), LineNumber(LineNumber) {} + +private: + const char *Message; + int LineNumber; +}; + +#define ASSERTION_HELPER_AT(M, L) AssertionHelper(M, L) + +#define ASSERTION_HELPER(M) ASSERTION_HELPER_AT(M, __LINE__) + +void FunctionWithCompilerDefinedSymbol(void) { + ASSERTION_HELPER("here and now"); +} + +// prove that integer literals introduced by the compiler are accepted silently +extern int ConsumeString(const char *Input); + +const char *SomeStrings[] = {"alpha", "beta", "gamma"}; + +int TestCheckerOverreach() { + int Total = 0; + + for (const auto *Str : SomeStrings) { + Total += ConsumeString(Str); + } + + return Total; +} |