Skip to content

[libc] Add -Wno-sign-conversion & re-attempt -Wconversion #129811

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
merged 14 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
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 libc/cmake/modules/LLVMLibCTestRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ function(_get_common_test_compile_options output_var c_test flags)
if(NOT LIBC_WNO_ERROR)
# list(APPEND compile_options "-Werror")
endif()
# list(APPEND compile_options "-Wconversion")
# list(APPEND compile_options "-Wno-sign-conversion")
list(APPEND compile_options "-Wconversion")
list(APPEND compile_options "-Wsign-conversion")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because -Wno-sign-conversion is effectively "silencing" it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this PR and there are still many warnings from -Wsign-conversion:

$ ninja check-libc &> test.txt
$ grep -c "Wsign-conversion" test.txt
12651

Some example:

In file included from /usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/FEnvImpl.h:31:
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:169:12: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
  mxcsr &= ~(bit_mask << internal::MXCSR_EXCEPTION_CONTOL_BIT_POISTION);
        ~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:193:22: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
  mxcsr |= (bit_mask << internal::MXCSR_EXCEPTION_CONTOL_BIT_POISTION);
        ~~  ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:341:26: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
                         << internal::MXCSR_ROUNDING_CONTROL_BIT_POSITION;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:344:20: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
                   ~(0x3 << internal::MXCSR_ROUNDING_CONTROL_BIT_POSITION)) |
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:610:14: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
    mxcsr &= ~uint16_t(0x3F);        // Clear exception flags.
          ~~ ^~~~~~~~~~~~~~~
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:611:14: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
    mxcsr &= ~(uint16_t(0x1) << 6);  // Reset denormals-are-zero
          ~~ ^~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:613:14: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
    mxcsr &= ~(uint16_t(0x3) << 13); // Round to nearest.
          ~~ ^~~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/lntue/experiment/llvm-project/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:614:14: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
    mxcsr &= ~(uint16_t(0x1) << 15); // Reset flush-to-zero
          ~~ ^~~~~~~~~~~~~~~~~~~~~~

Probably you should change to -Wno-sign-conversion in this PR, add a TODO comment to clean it up, and then fix the remaining -Wsign-conversion in a followup PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to reproduce these in the PR checks?

I don't have a x86 64 machine at the moment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made it -Wno-sign-conversion

list(APPEND compile_options "-Wimplicit-fallthrough")
list(APPEND compile_options "-Wwrite-strings")
# Silence this warning because _Complex is a part of C99.
Expand Down
8 changes: 4 additions & 4 deletions libc/src/__support/CPP/bit.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ countr_zero(T value) {
shift >>= 1;
mask >>= shift;
}
return zero_bits;
return static_cast<int>(zero_bits);
}
#if __has_builtin(__builtin_ctzs)
ADD_SPECIALIZATION(countr_zero, unsigned short, __builtin_ctzs)
Expand Down Expand Up @@ -140,7 +140,7 @@ countl_zero(T value) {
else
zero_bits |= shift;
}
return zero_bits;
return static_cast<int>(zero_bits);
}
#if __has_builtin(__builtin_clzs)
ADD_SPECIALIZATION(countl_zero, unsigned short, __builtin_clzs)
Expand Down Expand Up @@ -226,7 +226,7 @@ rotr(T value, int rotate);
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
rotl(T value, int rotate) {
constexpr unsigned N = cpp::numeric_limits<T>::digits;
constexpr int N = cpp::numeric_limits<T>::digits;
rotate = rotate % N;
if (!rotate)
return value;
Expand All @@ -238,7 +238,7 @@ rotl(T value, int rotate) {
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
rotr(T value, int rotate) {
constexpr unsigned N = cpp::numeric_limits<T>::digits;
constexpr int N = cpp::numeric_limits<T>::digits;
rotate = rotate % N;
if (!rotate)
return value;
Expand Down
6 changes: 4 additions & 2 deletions libc/src/__support/CPP/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stddef.h> // For size_t

#include "array.h" // For array
#include "limits.h"
#include "src/__support/macros/config.h"
#include "type_traits.h" // For remove_cv_t, enable_if_t, is_same_v, is_const_v

Expand Down Expand Up @@ -48,7 +49,8 @@ template <typename T> class span {
using const_reference = const T &;
using iterator = T *;

LIBC_INLINE_VAR static constexpr size_type dynamic_extent = -1;
LIBC_INLINE_VAR static constexpr size_type dynamic_extent =
cpp::numeric_limits<size_type>::max();

LIBC_INLINE constexpr span() : span_data(nullptr), span_size(0) {}

Expand All @@ -58,7 +60,7 @@ template <typename T> class span {
: span_data(first), span_size(count) {}

LIBC_INLINE constexpr span(pointer first, pointer end)
: span_data(first), span_size(end - first) {}
: span_data(first), span_size(static_cast<size_t>(end - first)) {}

template <typename U, size_t N,
cpp::enable_if_t<is_compatible_v<U>, bool> = true>
Expand Down
3 changes: 2 additions & 1 deletion libc/src/__support/CPP/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ class string {
: string(cstr, ::LIBC_NAMESPACE::internal::string_length(cstr)) {}
LIBC_INLINE string(size_t size_, char value) {
resize(size_);
inline_memset((void *)buffer_, value, size_);
static_assert(sizeof(char) == sizeof(uint8_t));
inline_memset((void *)buffer_, static_cast<uint8_t>(value), size_);
}

LIBC_INLINE string &operator=(const string &other) {
Expand Down
6 changes: 4 additions & 2 deletions libc/src/__support/CPP/string_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H

#include "limits.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"

Expand Down Expand Up @@ -40,7 +41,7 @@ class string_view {
LIBC_INLINE static constexpr size_t length(const char *Str) {
for (const char *End = Str;; ++End)
if (*End == '\0')
return End - Str;
return static_cast<size_t>(End - Str);
}

LIBC_INLINE bool equals(string_view Other) const {
Expand All @@ -61,7 +62,8 @@ class string_view {

// special value equal to the maximum value representable by the type
// size_type.
LIBC_INLINE_VAR static constexpr size_t npos = -1;
LIBC_INLINE_VAR static constexpr size_t npos =
cpp::numeric_limits<size_t>::max();

LIBC_INLINE constexpr string_view() : Data(nullptr), Len(0) {}

Expand Down
6 changes: 3 additions & 3 deletions libc/src/__support/FPUtil/FPBits.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> {
using UP::UP;

LIBC_INLINE constexpr BiasedExponent(Exponent exp)
: UP(static_cast<int32_t>(exp) + EXP_BIAS) {}
: UP(static_cast<uint32_t>(static_cast<int32_t>(exp) + EXP_BIAS)) {}

// Cast operator to get convert from BiasedExponent to Exponent.
LIBC_INLINE constexpr operator Exponent() const {
return Exponent(UP::value - EXP_BIAS);
return Exponent(static_cast<int32_t>(UP::value - EXP_BIAS));
}

LIBC_INLINE constexpr BiasedExponent &operator++() {
Expand Down Expand Up @@ -686,7 +686,7 @@ struct FPRepImpl : public FPRepSem<fp_type, RetT> {
}

LIBC_INLINE constexpr void set_biased_exponent(StorageType biased) {
UP::set_biased_exponent(BiasedExponent((int32_t)biased));
UP::set_biased_exponent(BiasedExponent(static_cast<uint32_t>(biased)));
}

LIBC_INLINE constexpr int get_exponent() const {
Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/FPUtil/NormalFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ template <typename T> struct NormalFloat {

constexpr int SUBNORMAL_EXPONENT = -FPBits<T>::EXP_BIAS + 1;
if (exponent < SUBNORMAL_EXPONENT) {
unsigned shift = SUBNORMAL_EXPONENT - exponent;
unsigned shift = static_cast<unsigned>(SUBNORMAL_EXPONENT - exponent);
// Since exponent > subnormalExponent, shift is strictly greater than
// zero.
if (shift <= FPBits<T>::FRACTION_LEN + 1) {
Expand Down Expand Up @@ -160,7 +160,7 @@ template <typename T> struct NormalFloat {
if (bits.is_subnormal()) {
unsigned shift = evaluate_normalization_shift(bits.get_mantissa());
mantissa = static_cast<StorageType>(bits.get_mantissa() << shift);
exponent = 1 - FPBits<T>::EXP_BIAS - shift;
exponent = 1 - FPBits<T>::EXP_BIAS - static_cast<int32_t>(shift);
} else {
exponent = bits.get_biased_exponent() - FPBits<T>::EXP_BIAS;
mantissa = ONE | bits.get_mantissa();
Expand Down
12 changes: 7 additions & 5 deletions libc/src/__support/FPUtil/aarch64/FEnvImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ LIBC_INLINE int enable_except(int excepts) {
(controlWord >> FEnv::ExceptionControlFlagsBitPosition) & 0x1F;
controlWord |= (newExcepts << FEnv::ExceptionControlFlagsBitPosition);
FEnv::writeControlWord(controlWord);
return FEnv::exceptionStatusToMacro(oldExcepts);
return FEnv::exceptionStatusToMacro(static_cast<uint32_t>(oldExcepts));
}

LIBC_INLINE int disable_except(int excepts) {
Expand All @@ -120,12 +120,12 @@ LIBC_INLINE int disable_except(int excepts) {
(controlWord >> FEnv::ExceptionControlFlagsBitPosition) & 0x1F;
controlWord &= ~(disabledExcepts << FEnv::ExceptionControlFlagsBitPosition);
FEnv::writeControlWord(controlWord);
return FEnv::exceptionStatusToMacro(oldExcepts);
return FEnv::exceptionStatusToMacro(static_cast<uint32_t>(oldExcepts));
}

LIBC_INLINE int get_except() {
uint32_t controlWord = FEnv::getControlWord();
int enabledExcepts =
uint32_t enabledExcepts =
(controlWord >> FEnv::ExceptionControlFlagsBitPosition) & 0x1F;
return FEnv::exceptionStatusToMacro(enabledExcepts);
}
Expand Down Expand Up @@ -250,8 +250,10 @@ LIBC_INLINE int set_round(int mode) {
}

uint32_t controlWord = FEnv::getControlWord();
controlWord &= ~(0x3 << FEnv::RoundingControlBitPosition);
controlWord |= (bitValue << FEnv::RoundingControlBitPosition);
controlWord &=
static_cast<uint32_t>(~(0x3 << FEnv::RoundingControlBitPosition));
controlWord |=
static_cast<uint32_t>(bitValue << FEnv::RoundingControlBitPosition);
FEnv::writeControlWord(controlWord);

return 0;
Expand Down
39 changes: 23 additions & 16 deletions libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct FEnv {
// __fpcr_flush_to_zero bit in the FPCR register. This control bit is
// located in a different place from FE_FLUSHTOZERO status bit relative to
// the other exceptions.
LIBC_INLINE static uint32_t exception_value_from_status(int status) {
LIBC_INLINE static uint32_t exception_value_from_status(uint32_t status) {
return ((status & FE_INVALID) ? EX_INVALID : 0) |
((status & FE_DIVBYZERO) ? EX_DIVBYZERO : 0) |
((status & FE_OVERFLOW) ? EX_OVERFLOW : 0) |
Expand All @@ -72,7 +72,7 @@ struct FEnv {
((status & FE_FLUSHTOZERO) ? EX_FLUSHTOZERO : 0);
}

LIBC_INLINE static uint32_t exception_value_from_control(int control) {
LIBC_INLINE static uint32_t exception_value_from_control(uint32_t control) {
return ((control & __fpcr_trap_invalid) ? EX_INVALID : 0) |
((control & __fpcr_trap_divbyzero) ? EX_DIVBYZERO : 0) |
((control & __fpcr_trap_overflow) ? EX_OVERFLOW : 0) |
Expand All @@ -81,7 +81,7 @@ struct FEnv {
((control & __fpcr_flush_to_zero) ? EX_FLUSHTOZERO : 0);
}

LIBC_INLINE static int exception_value_to_status(uint32_t excepts) {
LIBC_INLINE static uint32_t exception_value_to_status(uint32_t excepts) {
return ((excepts & EX_INVALID) ? FE_INVALID : 0) |
((excepts & EX_DIVBYZERO) ? FE_DIVBYZERO : 0) |
((excepts & EX_OVERFLOW) ? FE_OVERFLOW : 0) |
Expand All @@ -90,7 +90,7 @@ struct FEnv {
((excepts & EX_FLUSHTOZERO) ? FE_FLUSHTOZERO : 0);
}

LIBC_INLINE static int exception_value_to_control(uint32_t excepts) {
LIBC_INLINE static uint32_t exception_value_to_control(uint32_t excepts) {
return ((excepts & EX_INVALID) ? __fpcr_trap_invalid : 0) |
((excepts & EX_DIVBYZERO) ? __fpcr_trap_divbyzero : 0) |
((excepts & EX_OVERFLOW) ? __fpcr_trap_overflow : 0) |
Expand All @@ -113,48 +113,54 @@ struct FEnv {
};

LIBC_INLINE int enable_except(int excepts) {
uint32_t new_excepts = FEnv::exception_value_from_status(excepts);
uint32_t new_excepts =
FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
uint32_t control_word = FEnv::get_control_word();
uint32_t old_excepts = FEnv::exception_value_from_control(control_word);
if (new_excepts != old_excepts) {
control_word |= FEnv::exception_value_to_control(new_excepts);
FEnv::set_control_word(control_word);
}
return FEnv::exception_value_to_status(old_excepts);
return static_cast<int>(FEnv::exception_value_to_status(old_excepts));
}

LIBC_INLINE int disable_except(int excepts) {
uint32_t disabled_excepts = FEnv::exception_value_from_status(excepts);
uint32_t disabled_excepts =
FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
uint32_t control_word = FEnv::get_control_word();
uint32_t old_excepts = FEnv::exception_value_from_control(control_word);
control_word &= ~FEnv::exception_value_to_control(disabled_excepts);
FEnv::set_control_word(control_word);
return FEnv::exception_value_to_status(old_excepts);
return static_cast<int>(FEnv::exception_value_to_status(old_excepts));
}

LIBC_INLINE int get_except() {
uint32_t control_word = FEnv::get_control_word();
uint32_t enabled_excepts = FEnv::exception_value_from_control(control_word);
return FEnv::exception_value_to_status(enabled_excepts);
return static_cast<int>(FEnv::exception_value_to_status(enabled_excepts));
}

LIBC_INLINE int clear_except(int excepts) {
uint32_t status_word = FEnv::get_status_word();
uint32_t except_value = FEnv::exception_value_from_status(excepts);
uint32_t except_value =
FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
status_word &= ~FEnv::exception_value_to_status(except_value);
FEnv::set_status_word(status_word);
return 0;
}

LIBC_INLINE int test_except(int excepts) {
uint32_t statusWord = FEnv::get_status_word();
uint32_t ex_value = FEnv::exception_value_from_status(excepts);
return statusWord & FEnv::exception_value_to_status(ex_value);
uint32_t ex_value =
FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
return static_cast<int>(statusWord &
FEnv::exception_value_to_status(ex_value));
}

LIBC_INLINE int set_except(int excepts) {
uint32_t status_word = FEnv::get_status_word();
uint32_t new_exceptions = FEnv::exception_value_from_status(excepts);
uint32_t new_exceptions =
FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
status_word |= FEnv::exception_value_to_status(new_exceptions);
FEnv::set_status_word(status_word);
return 0;
Expand All @@ -174,7 +180,8 @@ LIBC_INLINE int raise_except(int excepts) {
: "s0", "s1" /* s0 and s1 are clobbered */);
};

uint32_t to_raise = FEnv::exception_value_from_status(excepts);
uint32_t to_raise =
FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
int result = 0;

if (to_raise & FEnv::EX_INVALID) {
Expand Down Expand Up @@ -237,7 +244,7 @@ LIBC_INLINE int get_round() {
}

LIBC_INLINE int set_round(int mode) {
uint16_t bit_value;
uint32_t bit_value;
switch (mode) {
case FE_TONEAREST:
bit_value = FEnv::TONEAREST;
Expand All @@ -256,7 +263,7 @@ LIBC_INLINE int set_round(int mode) {
}

uint32_t control_word = FEnv::get_control_word();
control_word &= ~(0x3 << FEnv::ROUNDING_CONTROL_BIT_POSITION);
control_word &= ~(0x3u << FEnv::ROUNDING_CONTROL_BIT_POSITION);
control_word |= (bit_value << FEnv::ROUNDING_CONTROL_BIT_POSITION);
FEnv::set_control_word(control_word);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace x86 {
LIBC_INLINE void normalize(int &exponent,
FPBits<long double>::StorageType &mantissa) {
const unsigned int shift = static_cast<unsigned int>(
cpp::countl_zero(static_cast<uint64_t>(mantissa)) -
static_cast<size_t>(cpp::countl_zero(static_cast<uint64_t>(mantissa))) -
(8 * sizeof(uint64_t) - 1 - FPBits<long double>::FRACTION_LEN));
exponent -= shift;
mantissa <<= shift;
Expand Down
3 changes: 2 additions & 1 deletion libc/src/__support/OSUtil/darwin/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace LIBC_NAMESPACE_DECL {

LIBC_INLINE void write_to_stderr(cpp::string_view msg) {
LIBC_NAMESPACE::syscall_impl(4 /*SYS_write*/, 2 /* stderr */,
reinterpret_cast<long>(msg.data()), msg.size());
reinterpret_cast<long>(msg.data()),
static_cast<long>(msg.size()));
}

} // namespace LIBC_NAMESPACE_DECL
Expand Down
Loading
Loading