Hi Alp,<div><br></div><div>This change doesn't look correct.<br><br><div>On Fri Jan 17 2014 at 5:04:31 AM, Alp Toker <<a href="mailto:alp@nuanti.com">alp@nuanti.com</a>> wrote:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: alp<br>
Date: Fri Jan 17 06:57:21 2014<br>
New Revision: 199490<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=199490&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=199490&view=rev</a><br>
Log:<br>
Permit redeclaration of tags introduced by using decls<br>
<br>
This valid construct appears in MSVC headers where it's used to provide a<br>
definition for the '::type_info' compiler builtin type.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Sema/SemaDecl.<u></u>cpp<br>
    cfe/trunk/test/SemaCXX/using-<u></u>decl-1.cpp<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.<u></u>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=199490&r1=199489&r2=199490&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/lib/Sema/<u></u>SemaDecl.cpp?rev=199490&r1=<u></u>199489&r2=199490&view=diff</a><br>

==============================<u></u>==============================<u></u>==================<br>
--- cfe/trunk/lib/Sema/SemaDecl.<u></u>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.<u></u>cpp Fri Jan 17 06:57:21 2014<br>
@@ -10681,7 +10681,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned<br>
   }<br>
<br>
   if (!Previous.empty()) {<br>
-    NamedDecl *PrevDecl = (*Previous.begin())-><u></u>getUnderlyingDecl();<br>
+    NamedDecl *DirectPrevDecl = *Previous.begin();<br>
+    NamedDecl *PrevDecl = DirectPrevDecl-><u></u>getUnderlyingDecl();<br>
<br>
     // It's okay to have a tag decl in the same scope as a typedef<br>
     // which hides a tag decl in the same scope.  Finding this<br>
@@ -10713,7 +10714,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned<br>
       // in the same scope (so that the definition/declaration completes or<br>
       // rementions the tag), reuse the decl.<br>
       if (TUK == TUK_Reference || TUK == TUK_Friend ||<br>
-          isDeclInScope(PrevDecl, SearchDC, S,<br>
+          isDeclInScope(DirectPrevDecl, SearchDC, S,<br>
                         SS.isNotEmpty() || isExplicitSpecialization)) {<br>
         // Make sure that this wasn't declared as an enum and now used as a<br>
         // struct or something similar.<br>
<br>
Modified: cfe/trunk/test/SemaCXX/using-<u></u>decl-1.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-decl-1.cpp?rev=199490&r1=199489&r2=199490&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/test/<u></u>SemaCXX/using-decl-1.cpp?rev=<u></u>199490&r1=199489&r2=199490&<u></u>view=diff</a><br>

==============================<u></u>==============================<u></u>==================<br>
--- cfe/trunk/test/SemaCXX/using-<u></u>decl-1.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/using-<u></u>decl-1.cpp Fri Jan 17 06:57:21 2014<br>
@@ -119,6 +119,27 @@ namespace foo<br>
   };<br>
 }<br>
<br>
+namespace using_tag_redeclaration<br>
+{<br>
+  struct S;<br>
+  namespace N {<br>
+    using ::using_tag_redeclaration::S;<br>
+    struct S {}; // expected-note {{previous definition is here}}<br></blockquote><div><br></div><div>This is ill-formed, by 3.3.1/4. It appears that your change makes the second declaration into a redeclaration of ::using_tag_redeclaration::S; that's incorrect. (Our previous handling of this case was also incorrect, albeit in a different way, since we didn't enforce the 3.3.1/4 rule here.)</div>
<div><br></div><div>If we need to handle something of this form for MSVC compatibility, we'll need to put it behind MSVCCompat.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+  }<br>
+  void f() {<br>
+    N::S s1;</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    S s2;<br>
+  }<br>
+  void g() {<br>
+    struct S; // expected-note {{forward declaration of 'S'}}<br>
+    S s3; // expected-error {{variable has incomplete type 'S'}}<br>
+  }<br>
+  void h() {<br>
+    using ::using_tag_redeclaration::S;<br>
+    struct S {}; // expected-error {{redefinition of 'S'}}<br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+  }<br>
+}<br>
+<br>
 // Don't suggest non-typenames for positions requiring typenames.<br>
 namespace using_suggestion_tyname_val {<br>
 namespace N { void FFF() {} }<br>
<br>
<br>
______________________________<u></u>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-commits</a><br>
</blockquote></div>