[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-20 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai added a comment.

Submitted for review https://reviews.llvm.org/D38109 - [fixup][Sema] Allow in C 
to define tags inside enumerations.


Repository:
  rL LLVM

https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-20 Thread Alberto Magni via Phabricator via cfe-commits
alberto_magni added a comment.

Yes, restricting the error to C++ would work. Many thanks.


Repository:
  rL LLVM

https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-20 Thread Aaron Ballman via cfe-commits
On Wed, Sep 20, 2017 at 2:17 PM, Volodymyr Sapsai via Phabricator via
cfe-commits  wrote:
> vsapsai added a comment.
>
> Thanks for following up, Alberto. I haven't expected such a use case. It is 
> possible to achieve the same with `LSA_SIZEOF_SA = sizeof(((len_and_sockaddr 
> *)0)->u)` but I don't like it and don't want to force developers using such 
> approach.
>
> For solving this problem I think to restrict error only to C++ and to allow 
> tags inside enums for C. Alberto, what do you think, will it work for you? 
> And from implementation perspective allowing tags in enums for C should be 
> safe because things go haywire for C++ while checking access rules and C 
> doesn't have access rules.

That construct is well-formed C code, but isn't in C++ (C++ restricts
the places where you can define a new type compared to what C allows).

~Aaron

>
>
> Repository:
>   rL LLVM
>
> https://reviews.llvm.org/D37089
>
>
>
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-20 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai added a comment.

Thanks for following up, Alberto. I haven't expected such a use case. It is 
possible to achieve the same with `LSA_SIZEOF_SA = sizeof(((len_and_sockaddr 
*)0)->u)` but I don't like it and don't want to force developers using such 
approach.

For solving this problem I think to restrict error only to C++ and to allow 
tags inside enums for C. Alberto, what do you think, will it work for you? And 
from implementation perspective allowing tags in enums for C should be safe 
because things go haywire for C++ while checking access rules and C doesn't 
have access rules.


Repository:
  rL LLVM

https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-20 Thread Alberto Magni via Phabricator via cfe-commits
alberto_magni added a comment.

Hi all,
this change is causing busybox to fail to compile.
The faulty enum is here:
https://git.busybox.net/busybox/tree/include/libbb.h#n639
The nested union is inside a sizeof statement.

Something like this:

  enum {
A = sizeof(union {
  int x;
  int y;
})
  };

I this behavior expected ? Do you suggest to patch busybox ?

Many Thanks


Repository:
  rL LLVM

https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-15 Thread Volodymyr Sapsai via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
vsapsai marked an inline comment as done.
Closed by commit rL313386: [Sema] Error out early for tags defined inside an 
enumeration. (authored by vsapsai).

Changed prior to commit:
  https://reviews.llvm.org/D37089?vs=115333=115466#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D37089

Files:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/test/Sema/enum.c
  cfe/trunk/test/SemaCXX/enum.cpp


Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1335,6 +1335,8 @@
   "%0 cannot be defined in a type alias template">;
 def err_type_defined_in_condition : Error<
   "%0 cannot be defined in a condition">;
+def err_type_defined_in_enum : Error<
+  "%0 cannot be defined in an enumeration">;
 
 def note_pure_virtual_function : Note<
   "unimplemented pure virtual method %0 in %1">;
Index: cfe/trunk/test/Sema/enum.c
===
--- cfe/trunk/test/Sema/enum.c
+++ cfe/trunk/test/Sema/enum.c
@@ -123,3 +123,14 @@
 // PR24610
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag 
type that does not match previous declaration}}
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at 
{{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})0
+  };
+  int makeStructNonEmpty;
+};
Index: cfe/trunk/test/SemaCXX/enum.cpp
===
--- cfe/trunk/test/SemaCXX/enum.cpp
+++ cfe/trunk/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@
 // expected-warning@-2 {{not an integral constant expression}}
 // expected-note@-3 {{value 28958703552 is outside the range of representable 
values}}
 #endif
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at 
{{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };
+};
Index: cfe/trunk/lib/Sema/SemaDecl.cpp
===
--- cfe/trunk/lib/Sema/SemaDecl.cpp
+++ cfe/trunk/lib/Sema/SemaDecl.cpp
@@ -13928,6 +13928,12 @@
 Invalid = true;
   }
 
+  if (!Invalid && TUK == TUK_Definition && DC->getDeclKind() == Decl::Enum) {
+Diag(New->getLocation(), diag::err_type_defined_in_enum)
+  << Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
 if (SS.isSet()) {


Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1335,6 +1335,8 @@
   "%0 cannot be defined in a type alias template">;
 def err_type_defined_in_condition : Error<
   "%0 cannot be defined in a condition">;
+def err_type_defined_in_enum : Error<
+  "%0 cannot be defined in an enumeration">;
 
 def note_pure_virtual_function : Note<
   "unimplemented pure virtual method %0 in %1">;
Index: cfe/trunk/test/Sema/enum.c
===
--- cfe/trunk/test/Sema/enum.c
+++ cfe/trunk/test/Sema/enum.c
@@ -123,3 +123,14 @@
 // PR24610
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at {{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})0
+  };
+  int makeStructNonEmpty;
+};
Index: cfe/trunk/test/SemaCXX/enum.cpp
===
--- cfe/trunk/test/SemaCXX/enum.cpp
+++ cfe/trunk/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@
 // expected-warning@-2 {{not an integral constant expression}}
 // expected-note@-3 {{value 28958703552 is outside the range of representable values}}
 #endif
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at {{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };
+};
Index: cfe/trunk/lib/Sema/SemaDecl.cpp
===
--- cfe/trunk/lib/Sema/SemaDecl.cpp
+++ cfe/trunk/lib/Sema/SemaDecl.cpp
@@ -13928,6 +13928,12 @@
 Invalid = true;
   }
 
+  if (!Invalid && TUK == TUK_Definition && 

[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-14 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai marked an inline comment as done.
vsapsai added inline comments.



Comment at: clang/test/Sema/enum.c:128
+// PR28903
+struct PR28903 { // expected-warning {{empty struct is a GNU extension}}
+  enum {

rnk wrote:
> This is a simpler test case that fixes the extraneous diagnostics:
>   struct PR28903 {
> enum {
>   E1 = (enum {  // expected-error-re {{...}}
>   E2, E3 = E2
> })0
> } e;
>   };
> 
Removed extraneous diagnostics in slightly different way. Keep enum constants 
prefixed with PR28903 because in C struct doesn't create a scope for enum 
constants and I want to avoid polluting test namespace with common names like 
E1, E2, E3.


https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-14 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai updated this revision to Diff 115333.
vsapsai added a comment.

- Remove extraneous diagnostics in test case per Reid Kleckner feedback.


https://reviews.llvm.org/D37089

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/enum.c
  clang/test/SemaCXX/enum.cpp


Index: clang/test/SemaCXX/enum.cpp
===
--- clang/test/SemaCXX/enum.cpp
+++ clang/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@
 // expected-warning@-2 {{not an integral constant expression}}
 // expected-note@-3 {{value 28958703552 is outside the range of representable 
values}}
 #endif
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at 
{{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };
+};
Index: clang/test/Sema/enum.c
===
--- clang/test/Sema/enum.c
+++ clang/test/Sema/enum.c
@@ -123,3 +123,14 @@
 // PR24610
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag 
type that does not match previous declaration}}
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at 
{{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})0
+  };
+  int makeStructNonEmpty;
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13928,6 +13928,12 @@
 Invalid = true;
   }
 
+  if (!Invalid && TUK == TUK_Definition && DC->getDeclKind() == Decl::Enum) {
+Diag(New->getLocation(), diag::err_type_defined_in_enum)
+  << Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
 if (SS.isSet()) {
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1333,6 +1333,8 @@
   "%0 cannot be defined in a type alias template">;
 def err_type_defined_in_condition : Error<
   "%0 cannot be defined in a condition">;
+def err_type_defined_in_enum : Error<
+  "%0 cannot be defined in an enumeration">;
 
 def note_pure_virtual_function : Note<
   "unimplemented pure virtual method %0 in %1">;


Index: clang/test/SemaCXX/enum.cpp
===
--- clang/test/SemaCXX/enum.cpp
+++ clang/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@
 // expected-warning@-2 {{not an integral constant expression}}
 // expected-note@-3 {{value 28958703552 is outside the range of representable values}}
 #endif
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at {{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };
+};
Index: clang/test/Sema/enum.c
===
--- clang/test/Sema/enum.c
+++ clang/test/Sema/enum.c
@@ -123,3 +123,14 @@
 // PR24610
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at {{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})0
+  };
+  int makeStructNonEmpty;
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13928,6 +13928,12 @@
 Invalid = true;
   }
 
+  if (!Invalid && TUK == TUK_Definition && DC->getDeclKind() == Decl::Enum) {
+Diag(New->getLocation(), diag::err_type_defined_in_enum)
+  << Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
 if (SS.isSet()) {
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1333,6 +1333,8 @@
   "%0 cannot be defined in a type alias template">;
 def err_type_defined_in_condition : Error<
   "%0 cannot be defined in a condition">;
+def err_type_defined_in_enum : Error<
+  "%0 cannot be defined in an enumeration">;
 
 def note_pure_virtual_function : Note<
   "unimplemented pure virtual method %0 in %1">;
___
cfe-commits mailing 

[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-14 Thread Doug Gregor via Phabricator via cfe-commits
doug.gregor accepted this revision.
doug.gregor added a comment.
This revision is now accepted and ready to land.

Looks good to me; sorry for the delay.


https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-13 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

I think this looks good, even without fixing the access control crash, this 
seems like a diagnostic improvement.




Comment at: clang/test/Sema/enum.c:128
+// PR28903
+struct PR28903 { // expected-warning {{empty struct is a GNU extension}}
+  enum {

This is a simpler test case that fixes the extraneous diagnostics:
  struct PR28903 {
enum {
  E1 = (enum {  // expected-error-re {{...}}
  E2, E3 = E2
})0
} e;
  };



https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-09-12 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai added a comment.

Ping. If you don't have time to review the change in depth, please say if the 
approach is wrong on high level.


https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-08-28 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai added a comment.

It occurred to me that another approach for fixing the crash can be setting 
`IsTypeSpecifier` to `true` while we ParseCastExpression. According to

  cast-expression:
unary-expression
( type-id ) cast-expression
  type-id:
type-specifier-seq abstract-declarator[opt]

it looks reasonable to require `IsTypeSpecifier` during parsing part of cast 
expression inside parentheses.

What do you think? Is this approach worth pursuing? Does it sound better than 
the one offered initially?


https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-08-23 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai added a comment.

I have also considered adding tests for structs and unions defined inside an 
enumeration but decided it doesn't add much value, given the code is working 
for all TagDecl.

Another option I had in mind is having a note pointing to outer enum. But the 
nesting is done in the same file so the outer enum shouldn't be hard to find. 
So I decided that complexity outweighs the added value.

If anybody thinks the aforementioned changes are valuable, please tell so.


https://reviews.llvm.org/D37089



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37089: [Sema] Error out early for tags defined inside an enumeration.

2017-08-23 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai created this revision.

This fixes PR28903 by avoiding access check for inner enum constant. We
are performing access check because one enum constant references another
and because enum is defined in CXXRecordDecl. But access check doesn't
work because FindDeclaringClass doesn't expect more than one EnumDecl
and because inner enum has access AS_none due to not being an immediate
child of a record.

The change detects an enum is defined in wrong place and allows to skip
parsing its body. Access check is skipped together with body parsing.
There was no crash in C, added test case to cover the new error.

rdar://problem/28530809


https://reviews.llvm.org/D37089

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/enum.c
  clang/test/SemaCXX/enum.cpp


Index: clang/test/SemaCXX/enum.cpp
===
--- clang/test/SemaCXX/enum.cpp
+++ clang/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@
 // expected-warning@-2 {{not an integral constant expression}}
 // expected-note@-3 {{value 28958703552 is outside the range of representable 
values}}
 #endif
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at 
{{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };
+};
Index: clang/test/Sema/enum.c
===
--- clang/test/Sema/enum.c
+++ clang/test/Sema/enum.c
@@ -123,3 +123,13 @@
 // PR24610
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag 
type that does not match previous declaration}}
+
+// PR28903
+struct PR28903 { // expected-warning {{empty struct is a GNU extension}}
+  enum {
+PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at 
{{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };  // expected-error {{expected expression}}
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13929,6 +13929,12 @@
 Invalid = true;
   }
 
+  if (!Invalid && TUK == TUK_Definition && DC->getDeclKind() == Decl::Enum) {
+Diag(New->getLocation(), diag::err_type_defined_in_enum)
+  << Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
 if (SS.isSet()) {
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1329,6 +1329,8 @@
   "%0 cannot be defined in a type alias template">;
 def err_type_defined_in_condition : Error<
   "%0 cannot be defined in a condition">;
+def err_type_defined_in_enum : Error<
+  "%0 cannot be defined in an enumeration">;
 
 def note_pure_virtual_function : Note<
   "unimplemented pure virtual method %0 in %1">;


Index: clang/test/SemaCXX/enum.cpp
===
--- clang/test/SemaCXX/enum.cpp
+++ clang/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@
 // expected-warning@-2 {{not an integral constant expression}}
 // expected-note@-3 {{value 28958703552 is outside the range of representable values}}
 #endif
+
+// PR28903
+struct PR28903 {
+  enum {
+PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at {{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };
+};
Index: clang/test/Sema/enum.c
===
--- clang/test/Sema/enum.c
+++ clang/test/Sema/enum.c
@@ -123,3 +123,13 @@
 // PR24610
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}
+
+// PR28903
+struct PR28903 { // expected-warning {{empty struct is a GNU extension}}
+  enum {
+PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at {{.*}})' cannot be defined in an enumeration}}
+  PR28903_B,
+  PR28903_C = PR28903_B
+})
+  };  // expected-error {{expected expression}}
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13929,6 +13929,12 @@
 Invalid = true;
   }
 
+  if (!Invalid && TUK == TUK_Definition && DC->getDeclKind() == Decl::Enum) {
+Diag(New->getLocation(), diag::err_type_defined_in_enum)
+  << Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
 if (SS.isSet())