https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108099
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Another question is what with this tolerated extension happens when the typedef is unsigned. // PR c++/108099 // { dg-do compile { target c++11 } } // { dg-options "" } typedef unsigned long long t64; using u64 = unsigned t64; using s64 = signed t64; template <typename T, T v> struct integral_constant { static constexpr T value = v; }; typedef integral_constant <bool, false> false_type; typedef integral_constant <bool, true> true_type; template <class T, class U> struct is_same : false_type {}; template <class T> struct is_same <T, T> : true_type {}; static_assert (is_same <long long, s64>::value, ""); static_assert (is_same <signed long long, s64>::value, ""); static_assert (is_same <unsigned long long, u64>::value, ""); static_assert (sizeof (s64) == sizeof (long long), ""); static_assert (sizeof (u64) == sizeof (unsigned long long), ""); static_assert (s64(-1) < 0, ""); static_assert (u64(-1) > 0, ""); shows 3 assertion failures, the 2 s64 is_same ones and s64(-1) < 0, so s64 was actually unsigned despite the signed keyword. Trunk with the above patch shows 5 assertion failures, all 3 is_same, sizeof (u64) and s64(-1) < 0. If we don't want to error right away, either we should keep the gcc 11 and earlier weirdo behavior, or better fix it such that with signed keyword and unsigned typedef we actually get corresponding unsigned type. But in neither case using just int/unsigned int if the type is wider or narrower.