| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,232 @@ | ||
| // RUN: %clang_cc1 -std=c++2a -verify=both,ref %s -fcxx-exceptions | ||
| // RUN: %clang_cc1 -std=c++2a -verify=both,expected %s -fcxx-exceptions -fexperimental-new-constant-interpreter | ||
|
|
||
| namespace std { | ||
| struct strong_ordering { // both-note 6{{candidate}} | ||
| int n; | ||
| constexpr operator int() const { return n; } | ||
| static const strong_ordering less, equal, greater; | ||
| }; | ||
| constexpr strong_ordering strong_ordering::less{-1}, | ||
| strong_ordering::equal{0}, strong_ordering::greater{1}; | ||
|
|
||
| struct weak_ordering { | ||
| int n; | ||
| constexpr weak_ordering(int n) : n(n) {} | ||
| constexpr weak_ordering(strong_ordering o) : n(o.n) {} | ||
| constexpr operator int() const { return n; } | ||
| static const weak_ordering less, equivalent, greater; | ||
| }; | ||
| constexpr weak_ordering weak_ordering::less{-1}, | ||
| weak_ordering::equivalent{0}, weak_ordering::greater{1}; | ||
|
|
||
| struct partial_ordering { | ||
| double d; | ||
| constexpr partial_ordering(double d) : d(d) {} | ||
| constexpr partial_ordering(strong_ordering o) : d(o.n) {} | ||
| constexpr partial_ordering(weak_ordering o) : d(o.n) {} | ||
| constexpr operator double() const { return d; } | ||
| static const partial_ordering less, equivalent, greater, unordered; | ||
| }; | ||
| constexpr partial_ordering partial_ordering::less{-1}, | ||
| partial_ordering::equivalent{0}, partial_ordering::greater{1}, | ||
| partial_ordering::unordered{__builtin_nan("")}; | ||
|
|
||
| static_assert(!(partial_ordering::unordered < 0)); | ||
| static_assert(!(partial_ordering::unordered == 0)); | ||
| static_assert(!(partial_ordering::unordered > 0)); | ||
| } | ||
|
|
||
| namespace Deletedness { | ||
| struct A { | ||
| std::strong_ordering operator<=>(const A&) const; | ||
| }; | ||
| struct B { | ||
| bool operator==(const B&) const; | ||
| bool operator<(const B&) const; | ||
| }; | ||
| struct C { | ||
| std::strong_ordering operator<=>(const C&) const = delete; // both-note 2{{deleted}} | ||
| }; | ||
| struct D1 { | ||
| bool operator==(const D1&) const; | ||
| std::strong_ordering operator<=>(int) const; // both-note 2{{function not viable}} both-note 2{{function (with reversed parameter order) not viable}} | ||
| bool operator<(int) const; // both-note 2{{function not viable}} | ||
| }; | ||
| struct D2 { | ||
| bool operator<(const D2&) const; | ||
| std::strong_ordering operator<=>(int) const; // both-note 2{{function not viable}} both-note 2{{function (with reversed parameter order) not viable}} | ||
| bool operator==(int) const; // both-note 2{{function not viable}} | ||
| }; | ||
| struct E { | ||
| bool operator==(const E&) const; | ||
| bool operator<(const E&) const = delete; // both-note 2{{deleted}} | ||
| }; | ||
| struct F { | ||
| std::strong_ordering operator<=>(const F&) const; // both-note 2{{candidate}} | ||
| std::strong_ordering operator<=>(F) const; // both-note 2{{candidate}} | ||
| }; | ||
| struct G1 { | ||
| bool operator==(const G1&) const; | ||
| void operator<(const G1&) const; | ||
| }; | ||
| struct G2 { | ||
| void operator==(const G2&) const; | ||
| bool operator<(const G2&) const; | ||
| }; | ||
| struct H { | ||
| void operator<=>(const H&) const; | ||
| }; | ||
|
|
||
| // both-note@#base {{deleted comparison function for base class 'C'}} | ||
| // both-note@#base {{no viable three-way comparison function for base class 'D1'}} | ||
| // both-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}} | ||
| // both-note@#base {{no viable 'operator==' for base class 'D2'}} | ||
| // both-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}} | ||
| // both-note@#base {{deleted comparison function for base class 'E'}} | ||
| // both-note@#base {{implied comparison for base class 'F' is ambiguous}} | ||
| template<typename T> struct Cmp : T { // #base | ||
| std::strong_ordering operator<=>(const Cmp&) const = default; // #cmp both-note 5{{here}} | ||
| }; | ||
|
|
||
| void use(...); | ||
| void f() { | ||
| use( | ||
| Cmp<A>() <=> Cmp<A>(), | ||
| Cmp<B>() <=> Cmp<B>(), | ||
| Cmp<C>() <=> Cmp<C>(), // both-error {{deleted}} | ||
| Cmp<D1>() <=> Cmp<D1>(), // both-error {{deleted}} | ||
| Cmp<D2>() <=> Cmp<D2>(), // both-error {{deleted}} | ||
| Cmp<E>() <=> Cmp<E>(), // both-error {{deleted}} | ||
| Cmp<F>() <=> Cmp<F>(), // both-error {{deleted}} | ||
| // FIXME: The following three errors are not very good. | ||
| // both-error@#cmp {{value of type 'void' is not contextually convertible to 'bool'}} | ||
| Cmp<G1>() <=> Cmp<G1>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}G1>' first required here}}j | ||
| // both-error@#cmp {{value of type 'void' is not contextually convertible to 'bool'}} | ||
| Cmp<G2>() <=> Cmp<G2>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}G2>' first required here}}j | ||
| // both-error@#cmp {{no matching conversion for static_cast from 'void' to 'std::strong_ordering'}} | ||
| Cmp<H>() <=> Cmp<H>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}H>' first required here}}j | ||
| 0 | ||
| ); | ||
| } | ||
|
|
||
| // both-note@#arr {{deleted comparison function for member 'arr'}} | ||
| // both-note@#arr {{no viable three-way comparison function for member 'arr'}} | ||
| // both-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}} | ||
| // both-note@#arr {{no viable 'operator==' for member 'arr'}} | ||
| // both-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}} | ||
| // both-note@#arr {{deleted comparison function for member 'arr'}} | ||
| // both-note@#arr {{implied comparison for member 'arr' is ambiguous}} | ||
| template<typename T> struct CmpArray { | ||
| T arr[3]; // #arr | ||
| std::strong_ordering operator<=>(const CmpArray&) const = default; // #cmparray both-note 5{{here}} | ||
| }; | ||
| void g() { | ||
| use( | ||
| CmpArray<A>() <=> CmpArray<A>(), | ||
| CmpArray<B>() <=> CmpArray<B>(), | ||
| CmpArray<C>() <=> CmpArray<C>(), // both-error {{deleted}} | ||
| CmpArray<D1>() <=> CmpArray<D1>(), // both-error {{deleted}} | ||
| CmpArray<D2>() <=> CmpArray<D2>(), // both-error {{deleted}} | ||
| CmpArray<E>() <=> CmpArray<E>(), // both-error {{deleted}} | ||
| CmpArray<F>() <=> CmpArray<F>(), // both-error {{deleted}} | ||
| // FIXME: The following three errors are not very good. | ||
| // both-error@#cmparray {{value of type 'void' is not contextually convertible to 'bool'}} | ||
| CmpArray<G1>() <=> CmpArray<G1>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}G1>' first required here}}j | ||
| // both-error@#cmparray {{value of type 'void' is not contextually convertible to 'bool'}} | ||
| CmpArray<G2>() <=> CmpArray<G2>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}G2>' first required here}}j | ||
| // both-error@#cmparray {{no matching conversion for static_cast from 'void' to 'std::strong_ordering'}} | ||
| CmpArray<H>() <=> CmpArray<H>(), // both-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}H>' first required here}}j | ||
| 0 | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| namespace Access { | ||
| class A { | ||
| std::strong_ordering operator<=>(const A &) const; // both-note {{here}} | ||
| public: | ||
| bool operator==(const A &) const; | ||
| bool operator<(const A &) const; | ||
| }; | ||
| struct B { | ||
| A a; // both-note {{would invoke a private 'operator<=>'}} | ||
| friend std::strong_ordering operator<=>(const B &, const B &) = default; // both-warning {{deleted}} both-note{{replace 'default'}} | ||
| }; | ||
|
|
||
| class C { | ||
| std::strong_ordering operator<=>(const C &); // not viable (not const) | ||
| bool operator==(const C &) const; // both-note {{here}} | ||
| bool operator<(const C &) const; | ||
| }; | ||
| struct D { | ||
| C c; // both-note {{would invoke a private 'operator=='}} | ||
| friend std::strong_ordering operator<=>(const D &, const D &) = default; // both-warning {{deleted}} both-note{{replace 'default'}} | ||
| }; | ||
| } | ||
|
|
||
| namespace Synthesis { | ||
| enum Result { False, True, Mu }; | ||
|
|
||
| constexpr bool toBool(Result R) { | ||
| if (R == Mu) throw "should not ask this question"; | ||
| return R == True; | ||
| } | ||
|
|
||
| struct Val { | ||
| Result equal, less; | ||
| constexpr bool operator==(const Val&) const { return toBool(equal); } | ||
| constexpr bool operator<(const Val&) const { return toBool(less); } | ||
| }; | ||
|
|
||
| template<typename T> struct Cmp { | ||
| Val val; | ||
| friend T operator<=>(const Cmp&, const Cmp&) = default; // both-note {{deleted}} | ||
| }; | ||
|
|
||
| template<typename T> constexpr auto cmp(Result equal, Result less = Mu, Result reverse_less = Mu) { | ||
| return Cmp<T>{equal, less} <=> Cmp<T>{Mu, reverse_less}; | ||
| } | ||
|
|
||
| static_assert(cmp<std::strong_ordering>(True) == 0); | ||
| static_assert(cmp<std::strong_ordering>(False, True) < 0); | ||
| static_assert(cmp<std::strong_ordering>(False, False) > 0); | ||
|
|
||
| static_assert(cmp<std::weak_ordering>(True) == 0); | ||
| static_assert(cmp<std::weak_ordering>(False, True) < 0); | ||
| static_assert(cmp<std::weak_ordering>(False, False) > 0); | ||
|
|
||
| static_assert(cmp<std::partial_ordering>(True) == 0); | ||
| static_assert(cmp<std::partial_ordering>(False, True) < 0); | ||
| static_assert(cmp<std::partial_ordering>(False, False, True) > 0); | ||
| static_assert(!(cmp<std::partial_ordering>(False, False, False) > 0)); | ||
| static_assert(!(cmp<std::partial_ordering>(False, False, False) == 0)); | ||
| static_assert(!(cmp<std::partial_ordering>(False, False, False) < 0)); | ||
|
|
||
| // No synthesis is performed for a custom return type, even if it can be | ||
| // converted from a standard ordering. | ||
| struct custom_ordering { | ||
| custom_ordering(std::strong_ordering o); | ||
| }; | ||
| void f(Cmp<custom_ordering> c) { | ||
| c <=> c; // both-error {{deleted}} | ||
| } | ||
| } | ||
|
|
||
| namespace Preference { | ||
| struct A { | ||
| A(const A&) = delete; // both-note {{deleted}} | ||
| // "usable" candidate that can't actually be called | ||
| friend void operator<=>(A, A); // both-note {{passing}} | ||
| // Callable candidates for synthesis not considered. | ||
| friend bool operator==(A, A); | ||
| friend bool operator<(A, A); | ||
| }; | ||
|
|
||
| struct B { | ||
| B(); | ||
| A a; | ||
| std::strong_ordering operator<=>(const B&) const = default; // both-error {{call to deleted constructor of 'A'}} | ||
| }; | ||
| bool x = B() < B(); // both-note {{in defaulted three-way comparison operator for 'B' first required here}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // RUN: %clang_cc1 -emit-llvm -triple mips -target-feature +soft-float %s -o - | FileCheck %s --check-prefix=SOFT_FLOAT | ||
|
|
||
| // SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(float %1) | ||
| void read_float(float *p) { | ||
| __asm__("" ::"r"(*p)); | ||
| } | ||
|
|
||
| // SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(double %1) | ||
| void read_double(double *p) { | ||
| __asm__("" :: "r"(*p)); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| // RUN: %clang_cc1 -ffixed-point -fsyntax-only -verify -Wformat -isystem %S/Inputs %s | ||
| // RUN: %clang_cc1 -fsyntax-only -verify -Wformat -isystem %S/Inputs %s -DWITHOUT_FIXED_POINT | ||
|
|
||
| int printf(const char *restrict, ...); | ||
|
|
||
| short s; | ||
| unsigned short us; | ||
| int i; | ||
| unsigned int ui; | ||
| long l; | ||
| unsigned long ul; | ||
| float fl; | ||
| double d; | ||
| char c; | ||
| unsigned char uc; | ||
|
|
||
| #ifndef WITHOUT_FIXED_POINT | ||
| short _Fract sf; | ||
| _Fract f; | ||
| long _Fract lf; | ||
| unsigned short _Fract usf; | ||
| unsigned _Fract uf; | ||
| unsigned long _Fract ulf; | ||
| short _Accum sa; | ||
| _Accum a; | ||
| long _Accum la; | ||
| unsigned short _Accum usa; | ||
| unsigned _Accum ua; | ||
| unsigned long _Accum ula; | ||
| _Sat short _Fract sat_sf; | ||
| _Sat _Fract sat_f; | ||
| _Sat long _Fract sat_lf; | ||
| _Sat unsigned short _Fract sat_usf; | ||
| _Sat unsigned _Fract sat_uf; | ||
| _Sat unsigned long _Fract sat_ulf; | ||
| _Sat short _Accum sat_sa; | ||
| _Sat _Accum sat_a; | ||
| _Sat long _Accum sat_la; | ||
| _Sat unsigned short _Accum sat_usa; | ||
| _Sat unsigned _Accum sat_ua; | ||
| _Sat unsigned long _Accum sat_ula; | ||
|
|
||
| void test_invalid_args(void) { | ||
| /// None of these should match against a fixed point type. | ||
| printf("%r", s); // expected-warning{{format specifies type '_Fract' but the argument has type 'short'}} | ||
| printf("%r", us); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned short'}} | ||
| printf("%r", i); // expected-warning{{format specifies type '_Fract' but the argument has type 'int'}} | ||
| printf("%r", ui); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned int'}} | ||
| printf("%r", l); // expected-warning{{format specifies type '_Fract' but the argument has type 'long'}} | ||
| printf("%r", ul); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned long'}} | ||
| printf("%r", fl); // expected-warning{{format specifies type '_Fract' but the argument has type 'float'}} | ||
| printf("%r", d); // expected-warning{{format specifies type '_Fract' but the argument has type 'double'}} | ||
| printf("%r", c); // expected-warning{{format specifies type '_Fract' but the argument has type 'char'}} | ||
| printf("%r", uc); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned char'}} | ||
| } | ||
|
|
||
| void test_fixed_point_specifiers(void) { | ||
| printf("%r", f); | ||
| printf("%R", uf); | ||
| printf("%k", a); | ||
| printf("%K", ua); | ||
|
|
||
| /// Test different sizes. | ||
| printf("%r", sf); // expected-warning{{format specifies type '_Fract' but the argument has type 'short _Fract'}} | ||
| printf("%r", lf); // expected-warning{{format specifies type '_Fract' but the argument has type 'long _Fract'}} | ||
| printf("%R", usf); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type 'unsigned short _Fract'}} | ||
| printf("%R", ulf); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type 'unsigned long _Fract'}} | ||
| printf("%k", sa); // expected-warning{{format specifies type '_Accum' but the argument has type 'short _Accum'}} | ||
| printf("%k", la); // expected-warning{{format specifies type '_Accum' but the argument has type 'long _Accum'}} | ||
| printf("%K", usa); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type 'unsigned short _Accum'}} | ||
| printf("%K", ula); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type 'unsigned long _Accum'}} | ||
|
|
||
| /// Test signs. | ||
| printf("%r", uf); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned _Fract'}} | ||
| printf("%R", f); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type '_Fract'}} | ||
| printf("%k", ua); // expected-warning{{format specifies type '_Accum' but the argument has type 'unsigned _Accum'}} | ||
| printf("%K", a); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type '_Accum'}} | ||
|
|
||
| /// Test between types. | ||
| printf("%r", a); // expected-warning{{format specifies type '_Fract' but the argument has type '_Accum'}} | ||
| printf("%R", ua); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type 'unsigned _Accum'}} | ||
| printf("%k", f); // expected-warning{{format specifies type '_Accum' but the argument has type '_Fract'}} | ||
| printf("%K", uf); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type 'unsigned _Fract'}} | ||
|
|
||
| /// Test saturated types. | ||
| printf("%r", sat_f); | ||
| printf("%R", sat_uf); | ||
| printf("%k", sat_a); | ||
| printf("%K", sat_ua); | ||
| } | ||
|
|
||
| void test_length_modifiers_and_flags(void) { | ||
| printf("%hr", sf); | ||
| printf("%lr", lf); | ||
| printf("%hR", usf); | ||
| printf("%lR", ulf); | ||
| printf("%hk", sa); | ||
| printf("%lk", la); | ||
| printf("%hK", usa); | ||
| printf("%lK", ula); | ||
|
|
||
| printf("%hr", sat_sf); | ||
| printf("%lr", sat_lf); | ||
| printf("%hR", sat_usf); | ||
| printf("%lR", sat_ulf); | ||
| printf("%hk", sat_sa); | ||
| printf("%lk", sat_la); | ||
| printf("%hK", sat_usa); | ||
| printf("%lK", sat_ula); | ||
|
|
||
| printf("%10r", f); | ||
| printf("%10.10r", f); | ||
| printf("%010r", f); | ||
| printf("%-10r", f); | ||
| printf("%.10r", f); | ||
| printf("%+r", f); | ||
| printf("% r", f); | ||
| printf("%#r", f); | ||
| printf("%#.r", f); | ||
| printf("%#.0r", f); | ||
|
|
||
| /// Test some invalid length modifiers. | ||
| printf("%zr", f); // expected-warning{{length modifier 'z' results in undefined behavior or no effect with 'r' conversion specifier}} | ||
| printf("%llr", f); // expected-warning{{length modifier 'll' results in undefined behavior or no effect with 'r' conversion specifier}} | ||
| printf("%hhr", f); // expected-warning{{length modifier 'hh' results in undefined behavior or no effect with 'r' conversion specifier}} | ||
|
|
||
| // + on an unsigned fixed point type. | ||
| printf("%+hR", usf); // expected-warning{{flag '+' results in undefined behavior with 'R' conversion specifier}} | ||
| printf("%+R", uf); // expected-warning{{flag '+' results in undefined behavior with 'R' conversion specifier}} | ||
| printf("%+lR", ulf); // expected-warning{{flag '+' results in undefined behavior with 'R' conversion specifier}} | ||
| printf("%+hK", usa); // expected-warning{{flag '+' results in undefined behavior with 'K' conversion specifier}} | ||
| printf("%+K", ua); // expected-warning{{flag '+' results in undefined behavior with 'K' conversion specifier}} | ||
| printf("%+lK", ula); // expected-warning{{flag '+' results in undefined behavior with 'K' conversion specifier}} | ||
| printf("% hR", usf); // expected-warning{{flag ' ' results in undefined behavior with 'R' conversion specifier}} | ||
| printf("% R", uf); // expected-warning{{flag ' ' results in undefined behavior with 'R' conversion specifier}} | ||
| printf("% lR", ulf); // expected-warning{{flag ' ' results in undefined behavior with 'R' conversion specifier}} | ||
| printf("% hK", usa); // expected-warning{{flag ' ' results in undefined behavior with 'K' conversion specifier}} | ||
| printf("% K", ua); // expected-warning{{flag ' ' results in undefined behavior with 'K' conversion specifier}} | ||
| printf("% lK", ula); // expected-warning{{flag ' ' results in undefined behavior with 'K' conversion specifier}} | ||
| } | ||
| #else | ||
| void test_fixed_point_specifiers_no_printf() { | ||
| printf("%k", i); // expected-warning{{invalid conversion specifier 'k'}} | ||
| printf("%K", i); // expected-warning{{invalid conversion specifier 'K'}} | ||
| printf("%r", i); // expected-warning{{invalid conversion specifier 'r'}} | ||
| printf("%R", i); // expected-warning{{invalid conversion specifier 'R'}} | ||
| } | ||
| #endif // WITHOUT_FIXED_POINT |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| // RUN: %clang_cc1 -triple mips64 -fsyntax-only -verify %s | ||
| // RUN: %clang_cc1 -triple mips64 -target-feature +soft-float -fsyntax-only -verify=softfloat %s | ||
|
|
||
| // expected-no-diagnostics | ||
|
|
||
| void test_f(float p) { | ||
| float result = p; | ||
| __asm__("" :: "f"(result)); // softfloat-error{{invalid input constraint 'f' in asm}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // RUN: %clang_cc1 -x c -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s | ||
| // RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wenum-compare -Wno-unused-comparison %s | ||
|
|
||
| typedef enum EnumA { | ||
| A | ||
| } EnumA; | ||
|
|
||
| enum EnumB { | ||
| B | ||
| }; | ||
|
|
||
| enum { | ||
| C | ||
| }; | ||
|
|
||
| void foo(void) { | ||
| enum EnumA a = A; | ||
| enum EnumB b = B; | ||
| A == B; | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| a == (B); | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| a == b; | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| A > B; | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| A >= b; | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| a > b; | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| (A) <= ((B)); | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| a < B; | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
| a < b; | ||
| // expected-warning@-1 {{comparison of different enumeration types}} | ||
|
|
||
| // In the following cases we purposefully differ from GCC and dont warn | ||
| a == C; | ||
| A < C; | ||
| b >= C; | ||
| } |