<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 15 September 2017 at 12:51, Volodymyr Sapsai via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: vsapsai<br>
Date: Fri Sep 15 12:51:42 2017<br>
New Revision: 313386<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=313386&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=313386&view=rev</a><br>
Log:<br>
[Sema] Error out early for tags defined inside an enumeration.<br>
<br>
This fixes PR28903 by avoiding access check for inner enum constant. We<br>
are performing access check because one enum constant references another<br>
and because enum is defined in CXXRecordDecl. But access check doesn't<br>
work because FindDeclaringClass doesn't expect more than one EnumDecl<br>
and because inner enum has access AS_none due to not being an immediate<br>
child of a record.<br>
<br>
The change detects an enum is defined in wrong place and allows to skip<br>
parsing its body. Access check is skipped together with body parsing.<br>
There was no crash in C, added test case to cover the new error.<br>
<br>
rdar://problem/28530809<br>
<br>
Reviewers: rnk, doug.gregor, rsmith<br>
<br>
Reviewed By: doug.gregor<br>
<br>
Subscribers: cfe-commits<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D37089" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D37089</a><br>
<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
    cfe/trunk/test/Sema/enum.c<br>
    cfe/trunk/test/SemaCXX/enum.<wbr>cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=313386&r1=313385&r2=313386&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/<wbr>DiagnosticSemaKinds.td?rev=<wbr>313386&r1=313385&r2=313386&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Fri Sep 15 12:51:42 2017<br>
@@ -1335,6 +1335,8 @@ def err_type_defined_in_alias_<wbr>template :<br>
   "%0 cannot be defined in a type alias template">;<br>
 def err_type_defined_in_condition : Error<<br>
   "%0 cannot be defined in a condition">;<br>
+def err_type_defined_in_enum : Error<<br>
+  "%0 cannot be defined in an enumeration">;<br>
<br>
 def note_pure_virtual_function : Note<<br>
   "unimplemented pure virtual method %0 in %1">;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=313386&r1=313385&r2=313386&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDecl.cpp?rev=313386&r1=<wbr>313385&r2=313386&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp Fri Sep 15 12:51:42 2017<br>
@@ -13928,6 +13928,12 @@ CreateNewDecl:<br>
     Invalid = true;<br>
   }<br>
<br>
+  if (!Invalid && TUK == TUK_Definition && DC->getDeclKind() == Decl::Enum) {<br>
+    Diag(New->getLocation(), diag::err_type_defined_in_<wbr>enum)<br>
+      << Context.getTagDeclType(New);<br>
+    Invalid = true;<br>
+  }<br></blockquote><div><br></div><div>This looks like the wrong fix. As noted elsewhere, this is wrong in C. And in C++, the relevant context is a type-specifier, which should be rejected due to the check 7 lines above.</div><div><br></div><div>It looks like the actual bug is that we don't consider the type within a C99 compound literal to be a type-specifier. The fact that the context is an enumeration is irrelevant.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
   // Maybe add qualifier info.<br>
   if (SS.isNotEmpty()) {<br>
     if (SS.isSet()) {<br>
<br>
Modified: cfe/trunk/test/Sema/enum.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/enum.c?rev=313386&r1=313385&r2=313386&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Sema/<wbr>enum.c?rev=313386&r1=313385&<wbr>r2=313386&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Sema/enum.c (original)<br>
+++ cfe/trunk/test/Sema/enum.c Fri Sep 15 12:51:42 2017<br>
@@ -123,3 +123,14 @@ int NegativeShortTest[<wbr>NegativeShort == -<br>
 // PR24610<br>
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}<br>
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}<br>
+<br>
+// PR28903<br>
+struct PR28903 {<br>
+  enum {<br>
+    PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at {{.*}})' cannot be defined in an enumeration}}<br>
+      PR28903_B,<br>
+      PR28903_C = PR28903_B<br>
+    })0<br>
+  };<br>
+  int makeStructNonEmpty;<br>
+};<br>
<br>
Modified: cfe/trunk/test/SemaCXX/enum.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/enum.cpp?rev=313386&r1=313385&r2=313386&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/enum.cpp?rev=313386&<wbr>r1=313385&r2=313386&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/enum.<wbr>cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/enum.<wbr>cpp Fri Sep 15 12:51:42 2017<br>
@@ -110,3 +110,13 @@ enum { overflow = 123456 * 234567 };<br>
 // expected-warning@-2 {{not an integral constant expression}}<br>
 // expected-note@-3 {{value 28958703552 is outside the range of representable values}}<br>
 #endif<br>
+<br>
+// PR28903<br>
+struct PR28903 {<br>
+  enum {<br>
+    PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at {{.*}})' cannot be defined in an enumeration}}<br>
+      PR28903_B,<br>
+      PR28903_C = PR28903_B<br>
+    })<br>
+  };<br>
+};<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>