diff options
author | Clement Courbet <courbet@google.com> | 2018-05-23 07:58:41 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2018-05-23 07:58:41 +0000 |
commit | 1c0a15c4449f862711cb0df0548d4c83a6ff8554 (patch) | |
tree | 11b067847a8a8dde752f73cac605aae9e5a357e5 /clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp | |
parent | 9b412153bfc4d3bed29f9b6c259b4b8777cc488f (diff) | |
download | bcm5719-llvm-1c0a15c4449f862711cb0df0548d4c83a6ff8554.tar.gz bcm5719-llvm-1c0a15c4449f862711cb0df0548d4c83a6ff8554.zip |
[clang-tidy] new cppcoreguidelines-narrowing-conversions check.
Summary:
Checks for narrowing conversions, e.g.
int i = 0;
i += 0.1;
This has what some might consider false positives for:
i += ceil(d);
Reviewers: alexfh, hokein
Subscribers: srhines, nemanjai, mgorny, JDevlieghere, xazax.hun, kbarton
Differential Revision: https://reviews.llvm.org/D38455
llvm-svn: 333066
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp')
-rw-r--r-- | clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp new file mode 100644 index 00000000000..ecffba6b844 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp @@ -0,0 +1,103 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t + +float ceil(float); +namespace std { +double ceil(double); +long double floor(long double); +} // namespace std + +namespace floats { + +struct ConvertsToFloat { + operator float() const { return 0.5; } +}; + +float operator "" _Pa(unsigned long long); + +void not_ok(double d) { + int i = 0; + i = d; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + i = 0.5f; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + i = static_cast<float>(d); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + i = ConvertsToFloat(); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + i = 15_Pa; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] +} + +void not_ok_binary_ops(double d) { + int i = 0; + i += 0.5; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + i += 0.5f; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + i += d; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + // We warn on the following even though it's not dangerous because there is no + // reason to use a double literal here. + // TODO(courbet): Provide an automatic fix. + i += 2.0; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] + i += 2.0f; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + + i *= 0.5f; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + i /= 0.5f; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions] + i += (double)0.5f; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions] +} + +void ok(double d) { + int i = 0; + i = 1; + i = static_cast<int>(0.5); + i = static_cast<int>(d); + i = std::ceil(0.5); + i = ::std::floor(0.5); + { + using std::ceil; + i = ceil(0.5f); + } + i = ceil(0.5f); +} + +void ok_binary_ops(double d) { + int i = 0; + i += 1; + i += static_cast<int>(0.5); + i += static_cast<int>(d); + i += (int)d; + i += std::ceil(0.5); + i += ::std::floor(0.5); + { + using std::ceil; + i += ceil(0.5f); + } + i += ceil(0.5f); +} + +// We're bailing out in templates and macros. +template <typename T1, typename T2> +void f(T1 one, T2 two) { + one += two; +} + +void template_context() { + f(1, 2); + f(1, .5); +} + +#define DERP(i, j) (i += j) + +void macro_context() { + int i = 0; + DERP(i, 2); + DERP(i, .5); +} + +} // namespace floats |