summaryrefslogtreecommitdiff
path: root/clang-tools-extra/test
diff options
context:
space:
mode:
authorGuillaume Chatelet <gchatelet@google.com>2018-11-26 16:25:55 +0000
committerGuillaume Chatelet <gchatelet@google.com>2018-11-26 16:25:55 +0000
commit8fc7c4411008ea43332b502eb9b622dbad07f6a7 (patch)
treed58c723842010bd85f862a650d7e385729718acc /clang-tools-extra/test
parent342b9b2f9f18dd9d3e0af935bc29ff2b68e40777 (diff)
[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
Diffstat (limited to 'clang-tools-extra/test')
-rw-r--r--clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp23
-rw-r--r--clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp57
-rw-r--r--clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp23
-rw-r--r--clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp83
-rw-r--r--clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp295
5 files changed, 455 insertions, 26 deletions
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
new file mode 100644
index 00000000000..dcf1848a30f
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
@@ -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]
+}
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
new file mode 100644
index 00000000000..14840df18d0
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
@@ -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
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
new file mode 100644
index 00000000000..f28985d2f31
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
@@ -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
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
new file mode 100644
index 00000000000..6bd437f98d4
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
@@ -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;
+}
diff --git a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
index ecffba6b844..cc817a021fd 100644
--- a/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
+++ b/clang-tools-extra/test/clang-tidy/cppcoreguidelines-narrowing-conversions.cpp
@@ -1,4 +1,8 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN: {key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}, \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
float ceil(float);
namespace std {
@@ -9,47 +13,282 @@ long double floor(long double);
namespace floats {
struct ConvertsToFloat {
- operator float() const { return 0.5; }
+ operator float() const { return 0.5f; }
};
-float operator "" _Pa(unsigned long long);
+float operator"" _float(unsigned long long);
-void not_ok(double d) {
+void narrow_fp_to_int_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]
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant '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;
+ i = 15_float;
// 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 += d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
i += 0.5;
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant '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]
-
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
i *= 0.5f;
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
i /= 0.5f;
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant '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]
+ // 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; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+}
+
+void narrow_double_to_float_ok(double d) {
+ float f;
+ f = d;
+ f = 15_double;
+}
+
+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.
+ f = -__builtin_huge_val(); // -max double is not within-range of float.
+ f = __builtin_inf(); // double infinity is not within-range of float.
+ f = __builtin_nan("0"); // double NaN is not narrowing.
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+ float f;
+ f += 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f += 2.0; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f *= 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f /= 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f += (double)0.5f; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+ f += d; // We do not warn about floating point narrowing by default.
+}
+
+void narrow_fp_constant_to_bool_not_ok() {
+ bool b1 = 1.0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'double' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ bool b2 = 1.0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+ {
+ long long ll; // 64 bits
+ float f = ll; // doesn't fit in 24 bits
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+ double d = ll; // doesn't fit in 53 bits.
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+ }
+ {
+ int i; // 32 bits
+ float f = i; // doesn't fit in 24 bits
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+ double d = i; // fits in 53 bits.
+ }
+ {
+ short n1, n2;
+ float f = n1 + n2; // 'n1 + n2' is of type 'int' because of integer rules
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+ }
+ {
+ short s; // 16 bits
+ float f = s; // fits in 24 bits
+ double d = s; // fits in 53 bits.
+ }
+}
+
+void narrow_integer_to_unsigned_integer_is_ok() {
+ char c;
+ short s;
+ int i;
+ long l;
+ long long ll;
+
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long long ull;
+
+ ui = c;
+ uc = s;
+ uc = i;
+ uc = l;
+ uc = ll;
+
+ uc = uc;
+ uc = us;
+ uc = ui;
+ uc = ul;
+ uc = ull;
+}
+
+void narrow_integer_to_signed_integer_is_not_ok() {
+ char c;
+ short s;
+ int i;
+ long l;
+ long long ll;
+
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long long ull;
+
+ c = c;
+ c = s;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = i;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ll;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ c = uc;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned char' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = us;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ui;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ c = ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ i = c;
+ i = s;
+ i = i;
+ i = l;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ i = ll;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ i = uc;
+ i = us;
+ i = ui;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ i = ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ i = ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ ll = c;
+ ll = s;
+ ll = i;
+ ll = l;
+ ll = ll;
+
+ ll = uc;
+ ll = us;
+ ll = ui;
+ ll = ul;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ ll = ull;
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_unsigned_integer_is_ok() {
+ 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.
+ unsigned short us1 = 0;
+ unsigned short us2 = 65535;
+ unsigned short us3 = -1; // unsigned dst type is well defined.
+ unsigned short us4 = 65536; // unsigned dst type is well defined.
+}
+
+void narrow_constant_to_signed_integer_is_not_ok() {
+ char c1 = -128;
+ char c2 = 127;
+ char c3 = -129;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ char c4 = 128;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+ short s1 = -32768;
+ short s2 = 32767;
+ short s3 = -32769;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value -32769 (0xFFFF7FFF) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ short s4 = 32768;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value 32768 (0x00008000) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) {
+ // conversion to unsigned dst type is well defined.
+ unsigned char c1 = b ? 1 : 0;
+ unsigned char c2 = b ? 1 : 256;
+ unsigned char c3 = b ? -1 : 0;
+}
+
+void narrow_conditional_operator_contant_to_signed_is_not_ok(bool b) {
+ char uc1 = b ? 1 : 0;
+ char uc2 = b ? 1 : 128;
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ char uc3 = b ? -129 : 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ unsigned long long ysize;
+ long long mirror = b ? -1 : ysize - 1;
+ // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: narrowing conversion from constant value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) of type 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+ // CHECK-MESSAGES: :[[@LINE-2]]:37: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_floating_point() {
+ float f_ok = 1ULL << 24; // fits in 24 bits mantissa.
+ float f_not_ok = (1ULL << 24) + 1ULL; // doesn't fit in 24 bits mantissa.
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 16777217 of type 'unsigned long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+ double d_ok = 1ULL << 53; // fits in 53 bits mantissa.
+ double d_not_ok = (1ULL << 53) + 1ULL; // doesn't fit in 53 bits mantissa.
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: narrowing conversion from constant value 9007199254740993 of type 'unsigned long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+}
+
+void casting_integer_to_bool_is_ok() {
+ int i;
+ while (i) {
+ }
+ for (; i;) {
+ }
+ if (i) {
+ }
+}
+
+void casting_float_to_bool_is_not_ok() {
+ float f;
+ while (f) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ }
+ for (; f;) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ }
+ if (f) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+ }
+}
+
+void legitimate_comparison_do_not_warn(unsigned long long size) {
+ for (int i = 0; i < size; ++i) {
+ }
}
void ok(double d) {
@@ -89,7 +328,9 @@ void f(T1 one, T2 two) {
void template_context() {
f(1, 2);
+ f(1, .5f);
f(1, .5);
+ f(1, .5l);
}
#define DERP(i, j) (i += j)
@@ -97,7 +338,9 @@ void template_context() {
void macro_context() {
int i = 0;
DERP(i, 2);
+ DERP(i, .5f);
DERP(i, .5);
+ DERP(i, .5l);
}
-} // namespace floats
+} // namespace floats