<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>