Fix type compatiblity of enums and ints

an enum must be compatible with one or more integer type,
so adjust the test accordingly.  That means the following
redeclarations should work:

  enum e6 { E1 = -1, E0 };
  void f3(enum e6);
  void f3(int);        // should work as int and e6 are compatible

while the following should not:

  void f4(enum e6 e);
  void f4(unsigned e); // should error as unsigned and e6 are incompatible
This commit is contained in:
Michael Matz 2020-06-05 16:02:08 +02:00
parent 068d5b3d20
commit 9eef33993a
3 changed files with 41 additions and 29 deletions

View File

@ -3009,7 +3009,9 @@ static int compare_types(CType *type1, CType *type2, int unqualified)
return (type1->ref == type2->ref);
} else if (bt1 == VT_FUNC) {
return is_compatible_func(type1, type2);
} else if (IS_ENUM(type1->t) || IS_ENUM(type2->t)) {
} else if (IS_ENUM(type1->t) && IS_ENUM(type2->t)) {
/* If both are enums then they must be the same, if only one is then
t1 and t2 must be equal, which was checked above already. */
return type1->ref == type2->ref;
} else {
return 1;

View File

@ -118,6 +118,13 @@ enum e5;
void f3(enum e4 e);
void f3(enum e5 e);
#elif defined test_enum_compat_2
enum e6 { E1 = -1, E0 };
void f3(enum e6);
void f3(int); // should work as int and e6 are compatible
void f4(enum e6 e);
void f4(unsigned e); // should error as unsigned and e6 are incompatible
#elif defined test_ptr_to_str
void f() { _Generic((int const *[]){0}, int:0); }
#elif defined test_fnptr_to_str

View File

@ -46,73 +46,76 @@
[test_enum_compat]
60_errors_and_warnings.c:119: error: incompatible types for redefinition of 'f3'
[test_enum_compat_2]
60_errors_and_warnings.c:126: error: incompatible types for redefinition of 'f4'
[test_ptr_to_str]
60_errors_and_warnings.c:122: error: type 'const int **' does not match any association
60_errors_and_warnings.c:129: error: type 'const int **' does not match any association
[test_fnptr_to_str]
60_errors_and_warnings.c:124: error: type 'int (*(*)(float, char))(double, int)' does not match any association
60_errors_and_warnings.c:131: error: type 'int (*(*)(float, char))(double, int)' does not match any association
[test_array_to_str]
60_errors_and_warnings.c:126: error: type 'int (*)[3]' does not match any association
60_errors_and_warnings.c:133: error: type 'int (*)[3]' does not match any association
[test_duplicate_def_1]
60_errors_and_warnings.c:128: error: redefinition of 'L'
60_errors_and_warnings.c:135: error: redefinition of 'L'
[test_duplicate_def_2]
60_errors_and_warnings.c:131: error: redeclaration of 'L'
60_errors_and_warnings.c:138: error: redeclaration of 'L'
[test_abstract_decls]
60_errors_and_warnings.c:141: error: identifier expected
60_errors_and_warnings.c:148: error: identifier expected
[test_invalid_1]
60_errors_and_warnings.c:146: error: identifier expected
60_errors_and_warnings.c:153: error: identifier expected
[test_invalid_2]
60_errors_and_warnings.c:149: error: ';' expected (got "{")
60_errors_and_warnings.c:156: error: ';' expected (got "{")
[test_invalid_3]
60_errors_and_warnings.c:153: error: ',' expected (got "a")
60_errors_and_warnings.c:160: error: ',' expected (got "a")
[test_invalid_4]
60_errors_and_warnings.c:157: error: division by zero in constant
60_errors_and_warnings.c:164: error: division by zero in constant
[test_conflicting_types]
60_errors_and_warnings.c:163: error: incompatible types for redefinition of 'i'
60_errors_and_warnings.c:170: error: incompatible types for redefinition of 'i'
[test_nested_types]
60_errors_and_warnings.c:170: error: struct/union/enum already defined
60_errors_and_warnings.c:177: error: struct/union/enum already defined
[test_vla_1]
60_errors_and_warnings.c:177: error: need explicit inner array size in VLAs
60_errors_and_warnings.c:184: error: need explicit inner array size in VLAs
[test_invalid_alignas]
60_errors_and_warnings.c:181: error: identifier expected
60_errors_and_warnings.c:188: error: identifier expected
[test_static_assert]
60_errors_and_warnings.c:187: error: ONE is not 1
60_errors_and_warnings.c:194: error: ONE is not 1
[test_static_assert_2]
60_errors_and_warnings.c:191: error: 0 is 0
60_errors_and_warnings.c:198: error: 0 is 0
[test_static_assert_c2x]
60_errors_and_warnings.c:195: error: _Static_assert fail
60_errors_and_warnings.c:202: error: _Static_assert fail
[test_void_array]
60_errors_and_warnings.c:198: error: declaration of an array of incomplete type elements
60_errors_and_warnings.c:205: error: declaration of an array of incomplete type elements
[test_incomplete_enum_array]
60_errors_and_warnings.c:201: error: declaration of an array of incomplete type elements
60_errors_and_warnings.c:208: error: declaration of an array of incomplete type elements
[test_incomplete_struct_array]
60_errors_and_warnings.c:204: error: declaration of an array of incomplete type elements
60_errors_and_warnings.c:211: error: declaration of an array of incomplete type elements
[test_const_fun_array]
60_errors_and_warnings.c:208: error: declaration of an array of functions
60_errors_and_warnings.c:215: error: declaration of an array of functions
[test_incomplete_array_array]
[test_extern_array]
60_errors_and_warnings.c:224: error: incompatible types for redefinition of 'x'
60_errors_and_warnings.c:231: error: incompatible types for redefinition of 'x'
[test_func_1]
hello: a = 123
@ -121,17 +124,17 @@ hello: a = 123
hello: a = 123
[test_func_3]
60_errors_and_warnings.c:254: warning: static storage ignored for redefinition of 'hello'
60_errors_and_warnings.c:261: warning: static storage ignored for redefinition of 'hello'
hello: a = 123
[test_func_4]
hello: a = 123
[test_func_5]
60_errors_and_warnings.c:254: error: incompatible types for redefinition of 'hello'
60_errors_and_warnings.c:261: error: incompatible types for redefinition of 'hello'
[test_func_6]
60_errors_and_warnings.c:242: error: function without file scope cannot be static
60_errors_and_warnings.c:249: error: function without file scope cannot be static
[test_var_1]
main : 1 ; 1
@ -144,12 +147,12 @@ main : 2 ; 2
bar : 3 ; 3
[test_var_3]
60_errors_and_warnings.c:286: error: incompatible types for redefinition of 'xxx'
60_errors_and_warnings.c:293: error: incompatible types for redefinition of 'xxx'
[test_var_4]
[test_long_double_type_for_win32]
60_errors_and_warnings.c:317: warning: assignment from incompatible pointer type
60_errors_and_warnings.c:324: warning: assignment from incompatible pointer type
[test_stray_backslash]
60_errors_and_warnings.c:323: error: stray '\' in program
60_errors_and_warnings.c:330: error: stray '\' in program