Fix Issue 24224 - __traits(initSymbol) treats aggregate-derived enum as base type (#15776)

This commit is contained in:
Paul Backus 2023-11-03 09:17:37 -04:00 committed by GitHub
parent 9266f92fe5
commit d24a8859b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 4 deletions

View file

@ -1875,16 +1875,24 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
return dimError(1);
auto o = (*e.args)[0];
Type t = isType(o);
AggregateDeclaration ad = t ? isAggregate(t) : null;
// Interfaces don't have an init symbol and hence cause linker errors
if (!ad || ad.isInterfaceDeclaration())
ErrorExp badArgument()
{
error(e.loc, "struct / class type expected as argument to __traits(initSymbol) instead of `%s`", o.toChars());
return ErrorExp.get();
}
Type t = isType(o);
if (!t || t.isTypeEnum())
return badArgument();
AggregateDeclaration ad = isAggregate(t);
// Interfaces don't have an init symbol and hence cause linker errors
if (!ad || ad.isInterfaceDeclaration())
return badArgument();
Declaration d = new SymbolDeclaration(ad.loc, ad);
d.type = Type.tvoid.arrayOf().constOf();
d.storage_class |= STC.rvalue;

View file

@ -0,0 +1,22 @@
/+
TEST_OUTPUT:
---
fail_compilation/fail24224.d(19): Error: struct / class type expected as argument to __traits(initSymbol) instead of `ES`
fail_compilation/fail24224.d(20): Error: struct / class type expected as argument to __traits(initSymbol) instead of `EU`
fail_compilation/fail24224.d(21): Error: struct / class type expected as argument to __traits(initSymbol) instead of `EC`
---
+/
struct S {}
union U {}
class C {}
enum ES : S { a = S.init }
enum EU : U { a = U.init }
enum EC : C { a = C.init }
void test()
{
auto init1 = __traits(initSymbol, ES);
auto init2 = __traits(initSymbol, EU);
auto init3 = __traits(initSymbol, EC);
}