On Wed, Jul 2, 2014 at 4:51 PM, Nico Weber <[email protected]> wrote:
> Author: nico > Date: Wed Jul 2 18:51:09 2014 > New Revision: 212238 > > URL: http://llvm.org/viewvc/llvm-project?rev=212238&view=rev > Log: > Enable clang to continue to parse libstdc++4.6 and stlport after r210091. > > r210091 made initialization checking more strict in c++11 mode. LWG2193 is > about changing standard libraries to still be valid under these new rules, > but older libstdc++ (e.g. libstdc++4.6 in -D_GLIBCXX_DEBUG=1 mode, or > stlport) > do not implement that yet. So fall back to the C++03 semantics for > container > classes in system headers below the std namespace. > > Added: > > cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp > Modified: > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/lib/Sema/SemaInit.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=212238&r1=212237&r2=212238&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 2 > 18:51:09 2014 > @@ -2128,6 +2128,10 @@ def err_attribute_dllimport_static_field > def warn_attribute_dllimport_static_field_definition : Warning< > "definition of dllimport static field">, > InGroup<DiagGroup<"dllimport-static-field-def">>; > +def warn_invalid_initializer_from_system_header : Warning< > + "invalid constructor form class in system header, should not be > explicit">, > + InGroup<DiagGroup<"invalid-initializer-from-system-header">>; > +def note_used_in_initialization_here : Note<"used in initialization > here">; > def err_attribute_dll_member_of_dll_class : Error< > "attribute %q0 cannot be applied to member of %q1 class">; > def warn_attribute_dll_instantiated_base_class : Warning< > > Modified: cfe/trunk/lib/Sema/SemaInit.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=212238&r1=212237&r2=212238&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaInit.cpp (original) > +++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Jul 2 18:51:09 2014 > @@ -353,8 +353,9 @@ ExprResult InitListChecker::PerformEmpty > // If there are fewer initializer-clauses in the list than there are > // members in the aggregate, then each member not explicitly > initialized > // ... > - if (SemaRef.getLangOpts().CPlusPlus11 && > - Entity.getType()->getBaseElementTypeUnsafe()->isRecordType()) { > + bool EmptyInitList = SemaRef.getLangOpts().CPlusPlus11 && > + Entity.getType()->getBaseElementTypeUnsafe()->isRecordType(); > + if (EmptyInitList) { > // C++1y / DR1070: > // shall be initialized [...] from an empty initializer list. > // > @@ -376,6 +377,56 @@ ExprResult InitListChecker::PerformEmpty > } > > InitializationSequence InitSeq(SemaRef, Entity, Kind, SubInit); > + // libstdc++4.6 marks the vector default constructor as explicit in > + // _GLIBCXX_DEBUG mode, so recover using the C++03 logic in that case. > + // stlport does so too. Look for std::__debug for libstdc++, and for > + // std:: for stlport. This is effectively a compiler-side > implementation of > + // LWG2193. > + if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() == > + InitializationSequence::FK_ExplicitConstructor) { > + OverloadCandidateSet::iterator Best; > + OverloadingResult O = > + InitSeq.getFailedCandidateSet() > + .BestViableFunction(SemaRef, Kind.getLocation(), Best); > + (void)O; > + assert(O == OR_Success && "Inconsistent overload resolution"); > + CXXConstructorDecl *CtorDecl = > cast<CXXConstructorDecl>(Best->Function); > + CXXRecordDecl *R = CtorDecl->getParent(); > + > + if (CtorDecl->getMinRequiredArguments() == 0 && > + CtorDecl->isExplicit() && R->getDeclName() && > + SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) { > + > + > + bool IsInStd = false; > + for (NamespaceDecl *ND = > dyn_cast<NamespaceDecl>(R->getDeclContext()); > + ND && !IsInStd; > + ND = dyn_cast<NamespaceDecl>(ND->getLexicalParent())) { > 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.) > + if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND)) > + IsInStd = true; > + } > + > + if (IsInStd && llvm::StringSwitch<bool>(R->getName()) > + .Cases("basic_string", "deque", "forward_list", true) > + .Cases("list", "map", "multimap", "multiset", true) > + .Cases("priority_queue", "queue", "set", "stack", true) > + .Cases("unordered_map", "unordered_set", "vector", true) > + .Default(false)) { > + InitSeq.InitializeFrom( > + SemaRef, Entity, > + InitializationKind::CreateValue(Loc, Loc, Loc, true), > + MultiExprArg(), /*TopLevelOfInitList=*/false); > + // Emit a warning for this. System header warnings aren't shown > + // by default, but people working on system headers should see it. > + if (!VerifyOnly) { > + SemaRef.Diag(CtorDecl->getLocation(), > + diag::warn_invalid_initializer_from_system_header); > + SemaRef.Diag(Entity.getDecl()->getLocation(), > + diag::note_used_in_initialization_here); > + } > + } > + } > + } > if (!InitSeq) { > if (!VerifyOnly) { > InitSeq.Diagnose(SemaRef, Entity, Kind, SubInit); > > Added: > cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp?rev=212238&view=auto > > ============================================================================== > --- > cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp > (added) > +++ > cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp > Wed Jul 2 18:51:09 2014 > @@ -0,0 +1,23 @@ > +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wsystem-headers %s > + > +// libstdc++4.6 in debug mode has explicit default constructors. > +// stlport has this for all containers. > +#ifdef BE_THE_HEADER > +#pragma clang system_header > +namespace std { > +namespace __debug { > +template <class T> > +class vector { > +public: > + explicit vector() {} // expected-warning{{should not be explicit}} > +}; > +} > +} > +#else > + > +#define BE_THE_HEADER > +#include __FILE__ > + > +struct { int a, b; std::__debug::vector<int> c; } e[] = { {1, 1} }; // > expected-note{{used in initialization here}} > + > +#endif > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
