Skip to content

[clang-tidy] swap cppcoreguidelines-narrowing-conversions and bugprone-narrowing-conversions #120245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "../cppcoreguidelines/NarrowingConversionsCheck.h"
#include "ArgumentCommentCheck.h"
#include "AssertSideEffectCheck.h"
#include "AssignmentInIfConditionCheck.h"
#include "BadSignalToKillThreadCheck.h"
#include "BitwisePointerCastCheck.h"
#include "BoolPointerImplicitConversionCheck.h"
#include "BranchCloneCheck.h"
#include "NarrowingConversionsCheck.h"
#include "CastingThroughVoidCheck.h"
#include "ChainedComparisonCheck.h"
#include "ComparePointerToMemberVirtualFunctionCheck.h"
Expand Down Expand Up @@ -183,7 +183,7 @@ class BugproneModule : public ClangTidyModule {
"bugprone-pointer-arithmetic-on-polymorphic-object");
CheckFactories.registerCheck<RedundantBranchConditionCheck>(
"bugprone-redundant-branch-condition");
CheckFactories.registerCheck<cppcoreguidelines::NarrowingConversionsCheck>(
CheckFactories.registerCheck<NarrowingConversionsCheck>(
"bugprone-narrowing-conversions");
CheckFactories.registerCheck<NoEscapeCheck>("bugprone-no-escape");
CheckFactories.registerCheck<NonZeroEnumToBoolConversionCheck>(
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ add_clang_library(clangTidyBugproneModule STATIC
MultiLevelImplicitPointerConversionCheck.cpp
MultipleNewInOneExpressionCheck.cpp
MultipleStatementMacroCheck.cpp
NarrowingConversionsCheck.cpp
NoEscapeCheck.cpp
NonZeroEnumToBoolConversionCheck.cpp
NondeterministicPointerIterationOrderCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

using namespace clang::ast_matchers;

namespace clang::tidy::cppcoreguidelines {
namespace clang::tidy::bugprone {

namespace {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include "../ClangTidyCheck.h"

namespace clang::tidy::cppcoreguidelines {
namespace clang::tidy::bugprone {

/// Checks for narrowing conversions, e.g:
/// int i = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ add_clang_library(clangTidyCppCoreGuidelinesModule STATIC
MacroUsageCheck.cpp
MisleadingCaptureDefaultByValueCheck.cpp
MissingStdForwardCheck.cpp
NarrowingConversionsCheck.cpp
NoMallocCheck.cpp
NoSuspendWithLockCheck.cpp
OwningMemoryCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "MacroUsageCheck.h"
#include "MisleadingCaptureDefaultByValueCheck.h"
#include "MissingStdForwardCheck.h"
#include "NarrowingConversionsCheck.h"
#include "../bugprone/NarrowingConversionsCheck.h"
#include "NoMallocCheck.h"
#include "NoSuspendWithLockCheck.h"
#include "OwningMemoryCheck.h"
Expand Down Expand Up @@ -87,7 +87,7 @@ class CppCoreGuidelinesModule : public ClangTidyModule {
"cppcoreguidelines-misleading-capture-default-by-value");
CheckFactories.registerCheck<MissingStdForwardCheck>(
"cppcoreguidelines-missing-std-forward");
CheckFactories.registerCheck<NarrowingConversionsCheck>(
CheckFactories.registerCheck<bugprone::NarrowingConversionsCheck>(
"cppcoreguidelines-narrowing-conversions");
CheckFactories.registerCheck<NoMallocCheck>("cppcoreguidelines-no-malloc");
CheckFactories.registerCheck<NoSuspendWithLockCheck>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,93 @@
.. title:: clang-tidy - bugprone-narrowing-conversions
.. meta::
:http-equiv=refresh: 5;URL=../cppcoreguidelines/narrowing-conversions.html

bugprone-narrowing-conversions
==============================

The bugprone-narrowing-conversions check is an alias, please see
:doc:`cppcoreguidelines-narrowing-conversions <../cppcoreguidelines/narrowing-conversions>`
for more information.
`cppcoreguidelines-narrowing-conversions` redirects here as an alias for this check.

Checks for silent narrowing conversions, e.g: ``int i = 0; i += 0.1;``. While
the issue is obvious in this former example, it might not be so in the
following: ``void MyClass::f(double d) { int_member_ += d; }``.

We enforce only part of the guideline, more specifically, we flag narrowing conversions from:
- an integer to a narrower integer (e.g. ``char`` to ``unsigned char``)
if WarnOnIntegerNarrowingConversion Option is set,
- an integer to a narrower floating-point (e.g. ``uint64_t`` to ``float``)
if WarnOnIntegerToFloatingPointNarrowingConversion Option is set,
- a floating-point to an integer (e.g. ``double`` to ``int``),
- a floating-point to a narrower floating-point (e.g. ``double`` to ``float``)
if WarnOnFloatingPointNarrowingConversion Option is set.

This check will flag:
- All narrowing conversions that are not marked by an explicit cast (c-style or
``static_cast``). For example: ``int i = 0; i += 0.1;``,
``void f(int); f(0.1);``,
- All applications of binary operators with a narrowing conversions.
For example: ``int i; i+= 0.1;``.


Options
-------

.. option:: WarnOnIntegerNarrowingConversion

When `true`, the check will warn on narrowing integer conversion
(e.g. ``int`` to ``size_t``). `true` by default.

.. option:: WarnOnIntegerToFloatingPointNarrowingConversion

When `true`, the check will warn on narrowing integer to floating-point
conversion (e.g. ``size_t`` to ``double``). `true` by default.

.. option:: WarnOnFloatingPointNarrowingConversion

When `true`, the check will warn on narrowing floating point conversion
(e.g. ``double`` to ``float``). `true` by default.

.. option:: WarnWithinTemplateInstantiation

When `true`, the check will warn on narrowing conversions within template
instantiations. `false` by default.

.. option:: WarnOnEquivalentBitWidth

When `true`, the check will warn on narrowing conversions that arise from
casting between types of equivalent bit width. (e.g.
`int n = uint(0);` or `long long n = double(0);`) `true` by default.

.. option:: IgnoreConversionFromTypes

Narrowing conversions from any type in this semicolon-separated list will be
ignored. This may be useful to weed out commonly occurring, but less commonly
problematic assignments such as `int n = std::vector<char>().size();` or
`int n = std::difference(it1, it2);`. The default list is empty, but one
suggested list for a legacy codebase would be
`size_t;ptrdiff_t;size_type;difference_type`.

.. option:: PedanticMode

When `true`, the check will warn on assigning a floating point constant
to an integer value even if the floating point value is exactly
representable in the destination type (e.g. ``int i = 1.0;``).
`false` by default.

FAQ
---

- What does "narrowing conversion from 'int' to 'float'" mean?

An IEEE754 Floating Point number can represent all integer values in the range
[-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in
the mantissa.

For ``float`` this would be [-2^23, 2^23], where ``int`` can represent values in
the range [-2^31, 2^31-1].

- What does "implementation-defined" mean?

You may have encountered messages like "narrowing conversion from 'unsigned int'
to signed type 'int' is implementation-defined".
The C/C++ standard does not mandate two's complement for signed integers, and so
the compiler is free to define what the semantics are for converting an unsigned
integer to signed integer. Clang's implementation uses the two's complement
format.
Original file line number Diff line number Diff line change
@@ -1,95 +1,14 @@
.. title:: clang-tidy - cppcoreguidelines-narrowing-conversions
.. meta::
:http-equiv=refresh: 5;URL=../cppcoreguidelines/narrowing-conversions.html

cppcoreguidelines-narrowing-conversions
=======================================

Checks for silent narrowing conversions, e.g: ``int i = 0; i += 0.1;``. While
the issue is obvious in this former example, it might not be so in the
following: ``void MyClass::f(double d) { int_member_ += d; }``.

This check implements `ES.46
<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es46-avoid-lossy-narrowing-truncating-arithmetic-conversions>`_
from the C++ Core Guidelines.

We enforce only part of the guideline, more specifically, we flag narrowing conversions from:
- an integer to a narrower integer (e.g. ``char`` to ``unsigned char``)
if WarnOnIntegerNarrowingConversion Option is set,
- an integer to a narrower floating-point (e.g. ``uint64_t`` to ``float``)
if WarnOnIntegerToFloatingPointNarrowingConversion Option is set,
- a floating-point to an integer (e.g. ``double`` to ``int``),
- a floating-point to a narrower floating-point (e.g. ``double`` to ``float``)
if WarnOnFloatingPointNarrowingConversion Option is set.

This check will flag:
- All narrowing conversions that are not marked by an explicit cast (c-style or
``static_cast``). For example: ``int i = 0; i += 0.1;``,
``void f(int); f(0.1);``,
- All applications of binary operators with a narrowing conversions.
For example: ``int i; i+= 0.1;``.


Options
-------

.. option:: WarnOnIntegerNarrowingConversion

When `true`, the check will warn on narrowing integer conversion
(e.g. ``int`` to ``size_t``). `true` by default.

.. option:: WarnOnIntegerToFloatingPointNarrowingConversion

When `true`, the check will warn on narrowing integer to floating-point
conversion (e.g. ``size_t`` to ``double``). `true` by default.

.. option:: WarnOnFloatingPointNarrowingConversion

When `true`, the check will warn on narrowing floating point conversion
(e.g. ``double`` to ``float``). `true` by default.

.. option:: WarnWithinTemplateInstantiation

When `true`, the check will warn on narrowing conversions within template
instantiations. `false` by default.

.. option:: WarnOnEquivalentBitWidth

When `true`, the check will warn on narrowing conversions that arise from
casting between types of equivalent bit width. (e.g.
`int n = uint(0);` or `long long n = double(0);`) `true` by default.

.. option:: IgnoreConversionFromTypes

Narrowing conversions from any type in this semicolon-separated list will be
ignored. This may be useful to weed out commonly occurring, but less commonly
problematic assignments such as `int n = std::vector<char>().size();` or
`int n = std::difference(it1, it2);`. The default list is empty, but one
suggested list for a legacy codebase would be
`size_t;ptrdiff_t;size_type;difference_type`.

.. option:: PedanticMode

When `true`, the check will warn on assigning a floating point constant
to an integer value even if the floating point value is exactly
representable in the destination type (e.g. ``int i = 1.0;``).
`false` by default.

FAQ
---

- What does "narrowing conversion from 'int' to 'float'" mean?

An IEEE754 Floating Point number can represent all integer values in the range
[-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in
the mantissa.

For ``float`` this would be [-2^23, 2^23], where ``int`` can represent values in
the range [-2^31, 2^31-1].

- What does "implementation-defined" mean?

You may have encountered messages like "narrowing conversion from 'unsigned int'
to signed type 'int' is implementation-defined".
The C/C++ standard does not mandate two's complement for signed integers, and so
the compiler is free to define what the semantics are for converting an unsigned
integer to signed integer. Clang's implementation uses the two's complement
format.
The cppcoreguidelines-narrowing-conversions check is an alias, please see
:doc:`bugprone-narrowing-conversions <../bugprone/narrowing-conversions>`
for more information.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
// RUN: %check_clang_tidy %s bugprone-narrowing-conversions %t \
// RUN: -std=c++17 -- -target x86_64-unknown-linux

#define CHAR_BITS 8
Expand Down Expand Up @@ -31,7 +31,7 @@ struct CompleteBitfield {
};

int example_warning(unsigned x) {
// CHECK-MESSAGES: :[[@LINE+1]]:10: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES: :[[@LINE+1]]:10: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
return x;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
// RUN: %check_clang_tidy -check-suffix=DEFAULT %s \
// RUN: cppcoreguidelines-narrowing-conversions %t --
// RUN: bugprone-narrowing-conversions %t --

// RUN: %check_clang_tidy -check-suffix=DISABLED %s \
// RUN: cppcoreguidelines-narrowing-conversions %t -- \
// RUN: bugprone-narrowing-conversions %t -- \
// RUN: -config='{CheckOptions: { \
// RUN: cppcoreguidelines-narrowing-conversions.WarnOnEquivalentBitWidth: 0}}'
// RUN: bugprone-narrowing-conversions.WarnOnEquivalentBitWidth: 0}}'

void narrowing_equivalent_bitwidth() {
int i;
unsigned int ui;
i = ui;
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
// DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0.

float f;
i = f;
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [bugprone-narrowing-conversions]
// DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0.

f = i;
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to 'float' [bugprone-narrowing-conversions]
// DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0.

long long ll;
double d;
ll = d;
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'long long' [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'long long' [bugprone-narrowing-conversions]
// DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0.

d = ll;
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to 'double' [bugprone-narrowing-conversions]
// DISABLED: Warning disabled with WarnOnEquivalentBitWidth=0.
}

void most_narrowing_is_not_ok() {
int i;
long long ui;
i = ui;
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
// CHECK-MESSAGES-DISABLED: :[[@LINE-2]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]
}
Loading
Loading