|
| 1 | +// RUN: %clang_cc1 -fsyntax-only -verify -Wimplicit-int-enum-cast %s |
| 2 | +// RUN: %clang_cc1 -fsyntax-only -verify -Wc++-compat %s |
| 3 | +// RUN: %clang_cc1 -fsyntax-only -verify=cxx -x c++ %s |
| 4 | +// RUN: %clang_cc1 -fsyntax-only -verify=good -Wno-implicit-enum-enum-cast %s |
| 5 | +// RUN: %clang_cc1 -fsyntax-only -verify=good -Wc++-compat -Wno-implicit-enum-enum-cast -Wno-implicit-int-enum-cast %s |
| 6 | +// good-no-diagnostics |
| 7 | + |
| 8 | +enum E1 { |
| 9 | + E1_Zero, |
| 10 | + E1_One |
| 11 | +}; |
| 12 | + |
| 13 | +enum E2 { |
| 14 | + E2_Zero |
| 15 | +}; |
| 16 | + |
| 17 | +struct S { |
| 18 | + enum E1 e; |
| 19 | +} s = { 12 }; // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ |
| 20 | + cxx-error {{cannot initialize a member subobject of type 'enum E1' with an rvalue of type 'int'}} |
| 21 | + |
| 22 | +enum E1 foo(void) { |
| 23 | + int x; |
| 24 | + enum E1 e = 12; // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ |
| 25 | + cxx-error {{cannot initialize a variable of type 'enum E1' with an rvalue of type 'int'}} |
| 26 | + |
| 27 | + // Enum to integer is fine. |
| 28 | + x = e; |
| 29 | + |
| 30 | + // Integer to enum is not fine. |
| 31 | + e = x; // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ |
| 32 | + cxx-error {{assigning to 'enum E1' from incompatible type 'int'}} |
| 33 | + return x; // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ |
| 34 | + cxx-error {{cannot initialize return object of type 'enum E1' with an lvalue of type 'int'}} |
| 35 | +} |
| 36 | + |
| 37 | +// Returning with the correct types is fine. |
| 38 | +enum E1 bar(void) { |
| 39 | + return E1_Zero; |
| 40 | +} |
| 41 | + |
| 42 | +// Enum to different-enum conversion is also a C++ incompatibility, but is |
| 43 | +// handled via a more general diagnostic, -Wimplicit-enum-enum-cast, which is |
| 44 | +// on by default. |
| 45 | +enum E1 quux(void) { |
| 46 | + enum E1 e1 = E2_Zero; // expected-warning {{implicit conversion from enumeration type 'enum E2' to different enumeration type 'enum E1'}} \ |
| 47 | + cxx-error {{cannot initialize a variable of type 'enum E1' with an rvalue of type 'E2'}} |
| 48 | + e1 = E2_Zero; // expected-warning {{implicit conversion from enumeration type 'enum E2' to different enumeration type 'enum E1'}} \ |
| 49 | + cxx-error {{assigning to 'enum E1' from incompatible type 'E2'}} |
| 50 | + return E2_Zero; // expected-warning {{implicit conversion from enumeration type 'enum E2' to different enumeration type 'enum E1'}} \ |
| 51 | + cxx-error {{cannot initialize return object of type 'enum E1' with an rvalue of type 'E2'}} |
| 52 | +} |
0 commit comments