llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.76k stars 10.96k forks source link

clang-tidy: cppcoreguidelines-narrowing-conversions wrongly flags unsigned -> signed conversions in C++20 #60443

Open richardebeling opened 1 year ago

richardebeling commented 1 year ago

With C++20, we are guaranteed two's complement representation for signed integers, and that the conversion from unsigned to signed results in the value that's equal modulo 2^n (cppreference).

However, the documentation page for the cppcoreguidelines-narrowing-conversions check still says:

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.

and this check triggers for code even when compiling for C++20.

Sample code (godbolt):

#include <cstdint>

void process_signed(int32_t val);

void caller(uint32_t val) {
    static_assert(__cplusplus >= 202002L, "ensure c++20");
    process_signed(val);
}

triggers:

<source>:7:20: warning: narrowing conversion from 'uint32_t' (aka 'unsigned int') to signed type 'int32_t' (aka 'int') is implementation-defined [cppcoreguidelines-narrowing-conversions]]
    process_signed(val);
                   ^
1 warning generated.

From the documentation page, it doesn't seem like there is an option to just disable just this unsigned->signed check in a C++20 code base.

Related to #51855.

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-tidy