@@ -402,6 +402,44 @@ _Static_assert(0 == _Generic(inner_anon_tagged.untagged, struct { int i; } : 1,
402402enum { E_Untagged1 } nontag_enum ; // both-note {{previous definition is here}}
403403_Static_assert (0 == _Generic(nontag_enum , enum { E_Untagged1 } : 1 , default : 0 )); // both-error {{redefinition of enumerator 'E_Untagged1'}}
404404
405+ // Test that enumerations with mixed underlying types are properly handled.
406+ enum GH150594_E1 : int { GH150594_Val1 };
407+ enum GH150594_E2 : int { GH150594_Val2 };
408+ enum GH150594_E3 { GH150594_Val3 };
409+ enum GH150594_E4 : int { GH150594_Val4 };
410+ void GH150594 (void ) {
411+ extern enum GH150594_E1 Fn1 (void ); // both-note {{previous declaration is here}}
412+ extern enum GH150594_E2 Fn2 (void ); // c17-note {{previous declaration is here}}
413+ extern enum GH150594_E3 Fn3 (void ); // both-note {{previous declaration is here}}
414+ extern enum GH150594_E4 Fn4 (void ); // both-note {{previous declaration is here}}
415+ enum GH150594_E1 { GH150594_Val1 };
416+ enum GH150594_E2 : int { GH150594_Val2 };
417+ enum GH150594_E3 : int { GH150594_Val3 };
418+ enum GH150594_E4 : short { GH150594_Val4 };
419+ extern enum GH150594_E1 Fn1 (void ); // both-error {{conflicting types for 'Fn1'}}
420+ extern enum GH150594_E2 Fn2 (void ); // c17-error {{conflicting types for 'Fn2'}}
421+ extern enum GH150594_E3 Fn3 (void ); // both-error {{conflicting types for 'Fn3'}}
422+ extern enum GH150594_E4 Fn4 (void ); // both-error {{conflicting types for 'Fn4'}}
423+
424+ // Show that two declarations in the same scope give expected diagnostics.
425+ enum E1 { e1 }; // both-note {{previous declaration is here}}
426+ enum E1 : int { e1 }; // both-error {{enumeration previously declared with nonfixed underlying type}}
427+
428+ enum E2 : int { e2 }; // both-note {{previous declaration is here}}
429+ enum E2 { e2 }; // both-error {{enumeration previously declared with fixed underlying type}}
430+
431+ enum E3 : int { e3 }; // both-note {{previous declaration is here}}
432+ enum E3 : short { e3 }; // both-error {{enumeration redeclared with different underlying type 'short' (was 'int')}}
433+
434+ typedef short foo ;
435+ enum E4 : foo { e4 }; // c17-note 2 {{previous definition is here}}
436+ enum E4 : short { e4 }; // c17-error {{redefinition of 'E4'}} \
437+ c17-error {{redefinition of enumerator 'e4'}}
438+
439+ enum E5 : foo { e5 }; // both-note {{previous declaration is here}}
440+ enum E5 : int { e5 }; // both-error {{enumeration redeclared with different underlying type 'int' (was 'foo' (aka 'short'))}}
441+ }
442+
405443// Test that enumerations are compatible with their underlying type, but still
406444// diagnose when "same type" is required rather than merely "compatible type".
407445enum E1 : int { e1 }; // Fixed underlying type
0 commit comments