Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang-tidy] Improving narrowing conversions
Summary: Newly flagged narrowing conversions: - integer to narrower signed integer (this is compiler implementation defined), - integer - floating point narrowing conversions, - floating point - integer narrowing conversions, - constants with narrowing conversions (even in ternary operator). Reviewers: hokein, alexfh, aaron.ballman, JonasToth Reviewed By: aaron.ballman, JonasToth Subscribers: lebedev.ri, courbet, nemanjai, xazax.hun, kbarton, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D53488 llvm-svn: 347570
- Loading branch information
Showing
9 changed files
with
988 additions
and
66 deletions.
There are no files selected for viewing
439 changes: 408 additions & 31 deletions
439
clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ | ||
// RUN: -- -- -target x86_64-unknown-linux -m32 | ||
|
||
static_assert(sizeof(int) * 8 == 32, "int is 32-bits"); | ||
static_assert(sizeof(long) * 8 == 32, "long is 32-bits"); | ||
static_assert(sizeof(long long) * 8 == 64, "long long is 64-bits"); | ||
|
||
void narrow_integer_to_signed_integer_is_not_ok() { | ||
int i; // i.e. int32_t | ||
long l; // i.e. int32_t | ||
long long ll; // i.e. int64_t | ||
|
||
unsigned int ui; // i.e. uint32_t | ||
unsigned long ul; // i.e. uint32_t | ||
unsigned long long ull; // i.e. uint64_t | ||
|
||
i = l; // int and long are the same type. | ||
i = ll; // int64_t does not fit in an int32_t | ||
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
ll = ul; // uint32_t fits into int64_t | ||
ll = ull; // uint64_t does not fit in an int64_t | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
} |
57 changes: 57 additions & 0 deletions
57
...test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ | ||
// RUN: -- -- -target x86_64-unknown-linux -fsigned-char | ||
|
||
namespace floats { | ||
|
||
void narrow_constant_floating_point_to_int_not_ok(double d) { | ||
int i = 0; | ||
i += 0.5; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions] | ||
i += 0.5f; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] | ||
i *= 0.5f; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] | ||
i /= 0.5f; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions] | ||
i += (double)0.5f; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions] | ||
i += 2.0; | ||
i += 2.0f; | ||
} | ||
|
||
double operator"" _double(unsigned long long); | ||
|
||
float narrow_double_to_float_return() { | ||
return 0.5; | ||
} | ||
|
||
void narrow_double_to_float_not_ok(double d) { | ||
float f; | ||
f = d; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions] | ||
f = 15_double; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions] | ||
f += d; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions] | ||
f = narrow_double_to_float_return(); | ||
} | ||
|
||
void narrow_fp_constants() { | ||
float f; | ||
f = 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing. | ||
|
||
f = __builtin_huge_valf(); // max float is not narrowing. | ||
f = -__builtin_huge_valf(); // -max float is not narrowing. | ||
f = __builtin_inff(); // float infinity is not narrowing. | ||
f = __builtin_nanf("0"); // float NaN is not narrowing. | ||
|
||
f = __builtin_huge_val(); // max double is not within-range of float. | ||
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions] | ||
f = -__builtin_huge_val(); // -max double is not within-range of float. | ||
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions] | ||
f = __builtin_inf(); // double infinity is not within-range of float. | ||
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions] | ||
f = __builtin_nan("0"); // double NaN is not narrowing. | ||
} | ||
|
||
} // namespace floats |
23 changes: 23 additions & 0 deletions
23
...ols-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ | ||
// RUN: -config="{CheckOptions: [ \ | ||
// RUN: {key: "cppcoreguidelines-narrowing-conversions.PedanticMode", value: 1} \ | ||
// RUN: ]}" \ | ||
// RUN: -- -target x86_64-unknown-linux -fsigned-char | ||
|
||
namespace floats { | ||
|
||
void triggers_wrong_constant_type_warning(double d) { | ||
int i = 0.0; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions] | ||
i += 2.0; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions] | ||
i += 2.0f; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'float' [cppcoreguidelines-narrowing-conversions] | ||
} | ||
|
||
void triggers_narrowing_warning_when_overflowing() { | ||
unsigned short us = 65537.0; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: narrowing conversion from constant 'double' to 'unsigned short' [cppcoreguidelines-narrowing-conversions] | ||
} | ||
|
||
} // namespace floats |
83 changes: 83 additions & 0 deletions
83
clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \ | ||
// RUN: -- -- -target x86_64-unknown-linux -funsigned-char | ||
|
||
void narrow_integer_to_unsigned_integer_is_ok() { | ||
signed char sc; | ||
short s; | ||
int i; | ||
long l; | ||
long long ll; | ||
|
||
char c; | ||
unsigned short us; | ||
unsigned int ui; | ||
unsigned long ul; | ||
unsigned long long ull; | ||
|
||
ui = sc; | ||
c = s; | ||
c = i; | ||
c = l; | ||
c = ll; | ||
|
||
c = c; | ||
c = us; | ||
c = ui; | ||
c = ul; | ||
c = ull; | ||
} | ||
|
||
void narrow_integer_to_signed_integer_is_not_ok() { | ||
signed char sc; | ||
short s; | ||
int i; | ||
long l; | ||
long long ll; | ||
|
||
char c; | ||
unsigned short us; | ||
unsigned int ui; | ||
unsigned long ul; | ||
unsigned long long ull; | ||
|
||
sc = sc; | ||
sc = s; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
sc = i; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
sc = l; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
sc = ll; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
|
||
sc = c; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'char' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
sc = us; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
sc = ui; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
sc = ul; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
sc = ull; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
} | ||
|
||
void narrow_constant_to_unsigned_integer_is_ok() { | ||
char c1 = -128; // unsigned dst type is well defined. | ||
char c2 = 127; // unsigned dst type is well defined. | ||
char c3 = -129; // unsigned dst type is well defined. | ||
char c4 = 128; // unsigned dst type is well defined. | ||
unsigned char uc1 = 0; | ||
unsigned char uc2 = 255; | ||
unsigned char uc3 = -1; // unsigned dst type is well defined. | ||
unsigned char uc4 = 256; // unsigned dst type is well defined. | ||
signed char sc = 128; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions] | ||
} | ||
|
||
void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) { | ||
// conversion to unsigned char type is well defined. | ||
char c1 = b ? 1 : 0; | ||
char c2 = b ? 1 : 256; | ||
char c3 = b ? -1 : 0; | ||
} |
Oops, something went wrong.