@@ -401,3 +401,39 @@ _Static_assert(0 == _Generic(inner_anon_tagged.untagged, struct { int i; } : 1,
401
401
// unions and structures are both RecordDecl objects, whereas EnumDecl is not).
402
402
enum { E_Untagged1 } nontag_enum ; // both-note {{previous definition is here}}
403
403
_Static_assert (0 == _Generic(nontag_enum , enum { E_Untagged1 } : 1 , default : 0 )); // both-error {{redefinition of enumerator 'E_Untagged1'}}
404
+
405
+ // Test that enumerations are compatible with their underlying type, but still
406
+ // diagnose when "same type" is required rather than merely "compatible type".
407
+ enum E1 : int { e1 }; // Fixed underlying type
408
+ enum E2 { e2 }; // Unfixed underlying type, defaults to int or unsigned int
409
+
410
+ struct GH149965_1 { int h ; };
411
+ // This typeof trick is used to get the underlying type of the enumeration in a
412
+ // platform agnostic way.
413
+ struct GH149965_2 { __typeof__ (+ (enum E2 ){}) h ; };
414
+ void gh149965 (void ) {
415
+ extern struct GH149965_1 x1 ; // c17-note {{previous declaration is here}}
416
+ extern struct GH149965_2 x2 ; // c17-note {{previous declaration is here}}
417
+
418
+ // Both the structure and the variable declarations are fine because only a
419
+ // compatible type is required, not the same type, because the structures are
420
+ // declared in different scopes.
421
+ struct GH149965_1 { enum E1 h ; };
422
+ struct GH149965_2 { enum E2 h ; };
423
+
424
+ extern struct GH149965_1 x1 ; // c17-error {{redeclaration of 'x1'}}
425
+ extern struct GH149965_2 x2 ; // c17-error {{redeclaration of 'x2'}}
426
+
427
+ // However, in the same scope, the same type is required, not just compatible
428
+ // types.
429
+ // FIXME: this should be an error in both C17 and C23 mode.
430
+ struct GH149965_3 { int h ; }; // c17-note {{previous definition is here}}
431
+ struct GH149965_3 { enum E1 h ; }; // c17-error {{redefinition of 'GH149965_3'}}
432
+
433
+ // For Clang, the composite type after declaration merging is the enumeration
434
+ // type rather than an integer type.
435
+ enum E1 * eptr ;
436
+ [[maybe_unused ]] __typeof__ (x1 .h ) * ptr = eptr ;
437
+ enum E2 * eptr2 ;
438
+ [[maybe_unused ]] __typeof__ (x2 .h ) * ptr2 = eptr2 ;
439
+ }
0 commit comments