diff --git a/src/denum.d b/src/denum.d index d7eddddc9ccf..9479f4900db0 100644 --- a/src/denum.d +++ b/src/denum.d @@ -568,7 +568,14 @@ extern (C++) final class EnumMember : VarDeclaration protection = ed.isAnonymous() ? ed.protection : Prot(PROTpublic); linkage = LINKd; storage_class = STCmanifest; - userAttribDecl = ed.isAnonymous() ? ed.userAttribDecl : null; + + if(ed.isAnonymous()) + { + if(userAttribDecl) + userAttribDecl.userAttribDecl = ed.userAttribDecl; + else + userAttribDecl = ed.userAttribDecl; + } semanticRun = PASSsemantic; diff --git a/src/parse.d b/src/parse.d index cc251fbd268d..dc77206c4fec 100644 --- a/src/parse.d +++ b/src/parse.d @@ -2977,6 +2977,17 @@ final class Parser : Lexer Type type = null; Identifier ident = null; + Expressions* udas = null; + + while(token.value == TOKat) + { + if(StorageClass stc = parseAttribute(&udas)) + { + error("only user defined attributes can appear in enums, not %s", stcToChars(stc)); + nextToken(); + } + } + Token* tp = peek(&token); if (token.value == TOKidentifier && (tp.value == TOKassign || tp.value == TOKcomma || tp.value == TOKrcurly)) { @@ -3007,6 +3018,8 @@ final class Parser : Lexer } auto em = new EnumMember(loc, ident, value, type); + if(udas) + em.userAttribDecl = new UserAttributeDeclaration(udas, new Dsymbols()); e.members.push(em); if (token.value == TOKrcurly) diff --git a/test/compilable/test9701.d b/test/compilable/test9701.d new file mode 100644 index 000000000000..dc1066d4beaf --- /dev/null +++ b/test/compilable/test9701.d @@ -0,0 +1,25 @@ + +import std.meta; + +enum Enum +{ + withoutUda, + @("first") valueWithUda, + @("second", "extra", 3) secondValueWithUda, +} + +@("outter") +enum +{ + @("first") anonFirst, + anonSecond, + @("third") @("extra") anonThird, +} + +static assert(__traits(getAttributes, Enum.withoutUda).length == 0); +static assert(__traits(getAttributes, Enum.valueWithUda) == AliasSeq!("first")); +static assert(__traits(getAttributes, Enum.secondValueWithUda) == AliasSeq!("second", "extra", 3)); + +static assert(__traits(getAttributes, anonFirst) == AliasSeq!("outter", "first")); +static assert(__traits(getAttributes, anonSecond) == AliasSeq!("outter")); +static assert(__traits(getAttributes, anonThird) == AliasSeq!("outter", "third", "extra")); diff --git a/test/fail_compilation/fail9701.d b/test/fail_compilation/fail9701.d new file mode 100644 index 000000000000..72b6461e705b --- /dev/null +++ b/test/fail_compilation/fail9701.d @@ -0,0 +1,12 @@ +/* +TEST_OUTPUT +--- +fail_compilation/fail9701.d(11): Error: only user defined attributes can appear in enums, not @nogc +fail_compilation/fail9701.d(11): Error: only user defined attributes can appear in enums, not @disable +--- +*/ + +enum Enum +{ + @("string") @nogc @(117) @disable @("value", 2525) value, +}