<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jul 2, 2014 at 4:51 PM, Nico Weber <span dir="ltr"><<a href="mailto:nicolasweber@gmx.de" target="_blank">nicolasweber@gmx.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: nico<br>
Date: Wed Jul  2 18:51:09 2014<br>
New Revision: 212238<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=212238&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=212238&view=rev</a><br>
Log:<br>
Enable clang to continue to parse libstdc++4.6 and stlport after r210091.<br>
<br>
r210091 made initialization checking more strict in c++11 mode. LWG2193 is<br>
about changing standard libraries to still be valid under these new rules,<br>
but older libstdc++ (e.g. libstdc++4.6 in -D_GLIBCXX_DEBUG=1 mode, or stlport)<br>
do not implement that yet.  So fall back to the C++03 semantics for container<br>
classes in system headers below the std namespace.<br>
<br>
Added:<br>
    cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/SemaInit.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=212238&r1=212237&r2=212238&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=212238&r1=212237&r2=212238&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul  2 18:51:09 2014<br>
@@ -2128,6 +2128,10 @@ def err_attribute_dllimport_static_field<br>
 def warn_attribute_dllimport_static_field_definition : Warning<<br>
   "definition of dllimport static field">,<br>
   InGroup<DiagGroup<"dllimport-static-field-def">>;<br>
+def warn_invalid_initializer_from_system_header : Warning<<br>
+  "invalid constructor form class in system header, should not be explicit">,<br>
+  InGroup<DiagGroup<"invalid-initializer-from-system-header">>;<br>
+def note_used_in_initialization_here : Note<"used in initialization here">;<br>
 def err_attribute_dll_member_of_dll_class : Error<<br>
   "attribute %q0 cannot be applied to member of %q1 class">;<br>
 def warn_attribute_dll_instantiated_base_class : Warning<<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=212238&r1=212237&r2=212238&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=212238&r1=212237&r2=212238&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Jul  2 18:51:09 2014<br>
@@ -353,8 +353,9 @@ ExprResult InitListChecker::PerformEmpty<br>
   //   If there are fewer initializer-clauses in the list than there are<br>
   //   members in the aggregate, then each member not explicitly initialized<br>
   //   ...<br>
-  if (SemaRef.getLangOpts().CPlusPlus11 &&<br>
-      Entity.getType()->getBaseElementTypeUnsafe()->isRecordType()) {<br>
+  bool EmptyInitList = SemaRef.getLangOpts().CPlusPlus11 &&<br>
+      Entity.getType()->getBaseElementTypeUnsafe()->isRecordType();<br>
+  if (EmptyInitList) {<br>
     // C++1y / DR1070:<br>
     //   shall be initialized [...] from an empty initializer list.<br>
     //<br>
@@ -376,6 +377,56 @@ ExprResult InitListChecker::PerformEmpty<br>
   }<br>
<br>
   InitializationSequence InitSeq(SemaRef, Entity, Kind, SubInit);<br>
+  // libstdc++4.6 marks the vector default constructor as explicit in<br>
+  // _GLIBCXX_DEBUG mode, so recover using the C++03 logic in that case.<br>
+  // stlport does so too. Look for std::__debug for libstdc++, and for<br>
+  // std:: for stlport.  This is effectively a compiler-side implementation of<br>
+  // LWG2193.<br>
+  if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() ==<br>
+          InitializationSequence::FK_ExplicitConstructor) {<br>
+    OverloadCandidateSet::iterator Best;<br>
+    OverloadingResult O =<br>
+        InitSeq.getFailedCandidateSet()<br>
+            .BestViableFunction(SemaRef, Kind.getLocation(), Best);<br>
+    (void)O;<br>
+    assert(O == OR_Success && "Inconsistent overload resolution");<br>
+    CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);<br>
+    CXXRecordDecl *R = CtorDecl->getParent();<br>
+<br>
+    if (CtorDecl->getMinRequiredArguments() == 0 &&<br>
+        CtorDecl->isExplicit() && R->getDeclName() &&<br>
+        SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) {<br>
+<br>
+<br>
+      bool IsInStd = false;<br>
+      for (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(R->getDeclContext());<br>
+           ND && !IsInStd;<br>
+          ND = dyn_cast<NamespaceDecl>(ND->getLexicalParent())) {<br></blockquote><div><br></div><div>Minor nit: use getParent() not getLexicalParent() here. (This doesn't matter today, but EWG are considering allowing 'namespace A::B', and that would make this matter.)</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND))<br>
+          IsInStd = true;<br>
+      }<br>
+<br>
+      if (IsInStd && llvm::StringSwitch<bool>(R->getName())<br>
+              .Cases("basic_string", "deque", "forward_list", true)<br>
+              .Cases("list", "map", "multimap", "multiset", true)<br>
+              .Cases("priority_queue", "queue", "set", "stack", true)<br>
+              .Cases("unordered_map", "unordered_set", "vector", true)<br>
+              .Default(false)) {<br>
+        InitSeq.InitializeFrom(<br>
+            SemaRef, Entity,<br>
+            InitializationKind::CreateValue(Loc, Loc, Loc, true),<br>
+            MultiExprArg(), /*TopLevelOfInitList=*/false);<br>
+        // Emit a warning for this.  System header warnings aren't shown<br>
+        // by default, but people working on system headers should see it.<br>
+        if (!VerifyOnly) {<br>
+          SemaRef.Diag(CtorDecl->getLocation(),<br>
+                       diag::warn_invalid_initializer_from_system_header);<br>
+          SemaRef.Diag(Entity.getDecl()->getLocation(),<br>
+                       diag::note_used_in_initialization_here);<br>
+        }<br>
+      }<br>
+    }<br>
+  }<br>
   if (!InitSeq) {<br>
     if (!VerifyOnly) {<br>
       InitSeq.Diagnose(SemaRef, Entity, Kind, SubInit);<br>
<br>
Added: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp?rev=212238&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp?rev=212238&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp (added)<br>
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp Wed Jul  2 18:51:09 2014<br>
@@ -0,0 +1,23 @@<br>
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wsystem-headers %s<br>
+<br>
+// libstdc++4.6 in debug mode has explicit default constructors.<br>
+// stlport has this for all containers.<br>
+#ifdef BE_THE_HEADER<br>
+#pragma clang system_header<br>
+namespace std {<br>
+namespace __debug {<br>
+template <class T><br>
+class vector {<br>
+public:<br>
+  explicit vector() {} // expected-warning{{should not be explicit}}<br>
+};<br>
+}<br>
+}<br>
+#else<br>
+<br>
+#define BE_THE_HEADER<br>
+#include __FILE__<br>
+<br>
+struct { int a, b; std::__debug::vector<int> c; } e[] = { {1, 1} }; // expected-note{{used in initialization here}}<br>
+<br>
+#endif<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">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/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>