r212238 - Enable clang to continue to parse libstdc++4.6 and stlport after r210091.

Nico Weber thakis at chromium.org
Wed Jul 2 17:46:56 PDT 2014


r212243.


On Wed, Jul 2, 2014 at 5:09 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> On Wed, Jul 2, 2014 at 4:51 PM, Nico Weber <nicolasweber at gmx.de> 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
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140702/4a0dacfe/attachment.html>


More information about the cfe-commits mailing list