diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1541,11 +1541,6 @@ if (LHSType == RHSType) return LHSType; - // ExtInt types aren't subject to conversions between them or normal integers, - // so this fails. - if(LHSType->isExtIntType() || RHSType->isExtIntType()) - return QualType(); - // At this point, we have two different arithmetic types. // Diagnose attempts to convert between __float128 and long double where diff --git a/clang/test/Sema/ext-int.c b/clang/test/Sema/ext-int.c --- a/clang/test/Sema/ext-int.c +++ b/clang/test/Sema/ext-int.c @@ -1,12 +1,16 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -triple x86_64-gnu-linux +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -Wno-unused -triple x86_64-gnu-linux typedef _ExtInt(31) EI31; void Ternary(_ExtInt(30) s30, EI31 s31a, _ExtInt(31) s31b, _ExtInt(32) s32, int b) { - b ? s30 : s31a; // expected-error{{incompatible operand types}} - b ? s31a : s30; // expected-error{{incompatible operand types}} - b ? s32 : 0; // expected-error{{incompatible operand types}} + b ? s30 : s31a; + b ? s31a : s30; + b ? s32 : 0; (void)(b ? s31a : s31b); (void)(s30 ? s31a : s31b); } + +struct CursedBitField { + _ExtInt(4) A : 8; // expected-error {{width of bit-field 'A' (8 bits) exceeds the width of its type (4 bits)}} +}; diff --git a/clang/test/SemaCXX/ext-int.cpp b/clang/test/SemaCXX/ext-int.cpp --- a/clang/test/SemaCXX/ext-int.cpp +++ b/clang/test/SemaCXX/ext-int.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -triple x86_64-gnu-linux +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -Wno-unused -Wunevaluated-expression -triple x86_64-gnu-linux template struct HasExtInt { @@ -110,72 +110,54 @@ unsigned x_uint = 1, y_uint = 1; bool b; - // Disabling mixed conversions: // Signed/unsigned mixed. - // expected-error@+1{{invalid operands to binary expression}} x43_u + y43_s; - // expected-error@+1{{invalid operands to binary expression}} x4_s - y4_u; - // expected-error@+1{{invalid operands to binary expression}} x43_s * y43_u; - // expected-error@+1{{invalid operands to binary expression}} x4_u / y4_s; // Different Sizes. - // expected-error@+1{{invalid operands to binary expression}} x43_s + y4_s; - // expected-error@+1{{invalid operands to binary expression}} x43_s - y4_u; - // expected-error@+1{{invalid operands to binary expression}} x43_u * y4_u; - // expected-error@+1{{invalid operands to binary expression}} x4_u / y43_u; // Mixed with standard types. - // expected-error@+1{{invalid operands to binary expression}} x43_s + x_int; - // expected-error@+1{{invalid operands to binary expression}} x43_u - x_int; - // expected-error@+1{{invalid operands to binary expression}} x32_s * x_int; - // expected-error@+1{{invalid operands to binary expression}} x32_u / x_int; - // expected-error@+1{{invalid operands to binary expression}} x32_s * x_uint; - // expected-error@+1{{invalid operands to binary expression}} x32_u / x_uint; - // expected-error@+1{{invalid operands to binary expression}} x4_s + x_int; - // expected-error@+1{{invalid operands to binary expression}} x4_u - x_int; - // expected-error@+1{{invalid operands to binary expression}} x4_s + b; - // expected-error@+1{{invalid operands to binary expression}} x4_u - b; - // expected-error@+1{{invalid operands to binary expression}} x43_s + b; - // expected-error@+1{{invalid operands to binary expression}} x43_u - b; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); // Bitwise checks. - // expected-error@+1{{invalid operands to binary expression}} x43_s % y4_u; - // expected-error@+1{{invalid operands to binary expression}} x43_u % y4_s; - // expected-error@+1{{invalid operands to binary expression}} x4_s | y43_u; - // expected-error@+1{{invalid operands to binary expression}} x4_u | y43_s; // compassign. - // expected-error@+1{{invalid operands to binary expression}} x43_s += 33; // Comparisons. - // expected-error@+1{{invalid operands to binary expression}} x43_s > 33; - // expected-error@+1{{invalid operands to binary expression}} - x4_s > 33; + x4_s > 33; // expected-warning {{result of comparison of constant 33 with expression of type '_ExtInt(4)' is always false}} // Same size/sign ops don't change type. static_assert(is_same::value,""); @@ -262,6 +244,10 @@ _ExtInt(3) H : 3; }; +struct CursedBitField { + _ExtInt(4) A : 8; // expected-warning {{width of bit-field 'A' (8 bits) exceeds the width of its type; value will be truncated to 4 bits}} +}; + // expected-error@+1{{mode attribute only supported for integer and floating-point types}} typedef _ExtInt(33) IllegalMode __attribute__((mode(DI))); @@ -279,9 +265,29 @@ void Ternary(_ExtInt(30) s30, _ExtInt(31) s31a, _ExtInt(31) s31b, _ExtInt(32) s32, bool b) { - b ? s30 : s31a; // expected-error{{incompatible operand types}} - b ? s31a : s30; // expected-error{{incompatible operand types}} - b ? s32 : (int)0; // expected-error{{incompatible operand types}} + b ? s30 : s31a; + b ? s31a : s30; + b ? s32 : (int)0; (void)(b ? s31a : s31b); (void)(s30 ? s31a : s31b); + + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); +} + +void FromPaper1() { + // Test the examples of conversion and promotion rules from C2x 6.3.1.8. + _ExtInt(2) a2 = 1; + _ExtInt(3) a3 = 2; + _ExtInt(33) a33 = 1; + char c = 3; + + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); +} + +void FromPaper2(_ExtInt(8) a1, _ExtInt(24) a2) { + static_assert(is_same::value, ""); }