I'd reland with the fix, and with an additional test that catches the problem this introduced. On Apr 28, 2016 8:16 AM, "Vassil Vassilev via cfe-commits" < cfe-commits@lists.llvm.org> wrote:
> Hi Nico, > I have a fix. What is the right way of putting it in? Shall I revert the > "revert" and commit the fix afterwards? > Many thanks > Vassil > On 27/04/16 19:26, Nico Weber via cfe-commits wrote: > >> Author: nico >> Date: Wed Apr 27 12:26:08 2016 >> New Revision: 267744 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=267744&view=rev >> Log: >> Revert r267691, it caused PR27535. >> >> Removed: >> cfe/trunk/test/Modules/Inputs/PR27401/ >> cfe/trunk/test/Modules/pr27401.cpp >> Modified: >> cfe/trunk/include/clang/AST/DeclBase.h >> cfe/trunk/include/clang/Serialization/ASTWriter.h >> cfe/trunk/lib/AST/DeclBase.cpp >> cfe/trunk/lib/Sema/SemaExpr.cpp >> cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >> cfe/trunk/lib/Serialization/ASTWriter.cpp >> cfe/trunk/lib/Serialization/ASTWriterDecl.cpp >> >> Modified: cfe/trunk/include/clang/AST/DeclBase.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=267744&r1=267743&r2=267744&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/AST/DeclBase.h (original) >> +++ cfe/trunk/include/clang/AST/DeclBase.h Wed Apr 27 12:26:08 2016 >> @@ -518,8 +518,8 @@ public: >> bool isImplicit() const { return Implicit; } >> void setImplicit(bool I = true) { Implicit = I; } >> - /// \brief Whether *any* (re-)declaration of the entity was used, >> meaning that >> - /// a definition is required. >> + /// \brief Whether this declaration was used, meaning that a definition >> + /// is required. >> /// >> /// \param CheckUsedAttr When true, also consider the "used" attribute >> /// (in addition to the "used" bit set by \c setUsed()) when >> determining >> @@ -529,8 +529,7 @@ public: >> /// \brief Set whether the declaration is used, in the sense of >> odr-use. >> /// >> /// This should only be used immediately after creating a declaration. >> - /// It intentionally doesn't notify any listeners. >> - void setIsUsed() { getCanonicalDecl()->Used = true; } >> + void setIsUsed() { Used = true; } >> /// \brief Mark the declaration used, in the sense of odr-use. >> /// >> >> Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=267744&r1=267743&r2=267744&view=diff >> >> ============================================================================== >> --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original) >> +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Wed Apr 27 12:26:08 >> 2016 >> @@ -565,17 +565,6 @@ public: >> /// decl. >> const Decl *getFirstLocalDecl(const Decl *D); >> - /// \brief Is this a local declaration (that is, one that will be >> written to >> - /// our AST file)? This is the case for declarations that are neither >> imported >> - /// from another AST file nor predefined. >> - bool IsLocalDecl(const Decl *D) { >> - if (D->isFromASTFile()) >> - return false; >> - auto I = DeclIDs.find(D); >> - return (I == DeclIDs.end() || >> - I->second >= serialization::NUM_PREDEF_DECL_IDS); >> - }; >> - >> /// \brief Emit a reference to a declaration. >> void AddDeclRef(const Decl *D, RecordDataImpl &Record); >> >> Modified: cfe/trunk/lib/AST/DeclBase.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=267744&r1=267743&r2=267744&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/AST/DeclBase.cpp (original) >> +++ cfe/trunk/lib/AST/DeclBase.cpp Wed Apr 27 12:26:08 2016 >> @@ -340,29 +340,25 @@ unsigned Decl::getMaxAlignment() const { >> return Align; >> } >> -bool Decl::isUsed(bool CheckUsedAttr) const { >> - const Decl *CanonD = getCanonicalDecl(); >> - if (CanonD->Used) >> +bool Decl::isUsed(bool CheckUsedAttr) const { >> + if (Used) >> return true; >> - >> + >> // Check for used attribute. >> - // Ask the most recent decl, since attributes accumulate in the redecl >> chain. >> - if (CheckUsedAttr && getMostRecentDecl()->hasAttr<UsedAttr>()) >> + if (CheckUsedAttr && hasAttr<UsedAttr>()) >> return true; >> - // The information may have not been deserialized yet. Force >> deserialization >> - // to complete the needed information. >> - return getMostRecentDecl()->getCanonicalDecl()->Used; >> + return false; >> } >> void Decl::markUsed(ASTContext &C) { >> - if (isUsed()) >> + if (Used) >> return; >> if (C.getASTMutationListener()) >> C.getASTMutationListener()->DeclarationMarkedUsed(this); >> - setIsUsed(); >> + Used = true; >> } >> bool Decl::isReferenced() const { >> >> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=267744&r1=267743&r2=267744&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Apr 27 12:26:08 2016 >> @@ -13011,7 +13011,17 @@ void Sema::MarkFunctionReferenced(Source >> UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), >> Loc)); >> } >> - Func->markUsed(Context); >> + // Normally the most current decl is marked used while processing the >> use and >> + // any subsequent decls are marked used by decl merging. This fails >> with >> + // template instantiation since marking can happen at the end of the >> file >> + // and, because of the two phase lookup, this function is called with >> at >> + // decl in the middle of a decl chain. We loop to maintain the >> invariant >> + // that once a decl is used, all decls after it are also used. >> + for (FunctionDecl *F = Func->getMostRecentDecl();; F = >> F->getPreviousDecl()) { >> + F->markUsed(Context); >> + if (F == Func) >> + break; >> + } >> } >> static void >> >> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=267744&r1=267743&r2=267744&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Apr 27 12:26:08 2016 >> @@ -51,11 +51,6 @@ namespace clang { >> bool HasPendingBody; >> - ///\brief A flag to carry the information for a decl from the >> entity is >> - /// used. We use it to delay the marking of the canonical decl as >> used until >> - /// the entire declaration is deserialized and merged. >> - bool IsDeclMarkedUsed; >> - >> uint64_t GetCurrentCursorOffset(); >> uint64_t ReadLocalOffset(const RecordData &R, unsigned &I) { >> @@ -222,8 +217,7 @@ namespace clang { >> : Reader(Reader), F(*Loc.F), Offset(Loc.Offset), >> ThisDeclID(thisDeclID), >> ThisDeclLoc(ThisDeclLoc), Record(Record), Idx(Idx), >> TypeIDForTypeDecl(0), NamedDeclForTagDecl(0), >> - TypedefNameForLinkage(nullptr), HasPendingBody(false), >> - IsDeclMarkedUsed(false) {} >> + TypedefNameForLinkage(nullptr), HasPendingBody(false) {} >> template <typename DeclT> >> static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D); >> @@ -450,11 +444,6 @@ uint64_t ASTDeclReader::GetCurrentCursor >> void ASTDeclReader::Visit(Decl *D) { >> DeclVisitor<ASTDeclReader, void>::Visit(D); >> - // At this point we have deserialized and merged the decl and it is >> safe to >> - // update its canonical decl to signal that the entire entity is used. >> - D->getCanonicalDecl()->Used |= IsDeclMarkedUsed; >> - IsDeclMarkedUsed = false; >> - >> if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { >> if (DD->DeclInfo) { >> DeclaratorDecl::ExtInfo *Info = >> @@ -535,7 +524,6 @@ void ASTDeclReader::VisitDecl(Decl *D) { >> } >> D->setImplicit(Record[Idx++]); >> D->Used = Record[Idx++]; >> - IsDeclMarkedUsed |= D->Used; >> D->setReferenced(Record[Idx++]); >> D->setTopLevelDeclInObjCContainer(Record[Idx++]); >> D->setAccess((AccessSpecifier)Record[Idx++]); >> @@ -560,7 +548,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { >> if (Owner->NameVisibility != Module::AllVisible) { >> // The owning module is not visible. Mark this declaration as >> hidden. >> D->Hidden = true; >> - >> + >> // Note that this declaration was hidden because its owning >> module is >> // not yet visible. >> Reader.HiddenNamesMap[Owner].push_back(D); >> @@ -2367,8 +2355,6 @@ void ASTDeclReader::mergeRedeclarable(Re >> // appropriate canonical declaration. >> D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon); >> D->First = ExistingCanon; >> - ExistingCanon->Used |= D->Used; >> - D->Used = false; >> // When we merge a namespace, update its pointer to the first >> namespace. >> // We cannot have loaded any redeclarations of this declaration >> yet, so >> @@ -3126,6 +3112,11 @@ void ASTDeclReader::attachPreviousDecl(A >> Previous->IdentifierNamespace & >> (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type); >> + // If the previous declaration is marked as used, then this >> declaration should >> + // be too. >> + if (Previous->Used) >> + D->Used = true; >> + >> // If the declaration declares a template, it may inherit default >> arguments >> // from the previous declaration. >> if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) >> @@ -3874,7 +3865,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, >> // ASTMutationListeners other than an ASTWriter. >> // Maintain AST consistency: any later redeclarations are used >> too. >> - D->setIsUsed(); >> + forAllLaterRedecls(D, [](Decl *D) { D->Used = true; }); >> break; >> } >> >> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=267744&r1=267743&r2=267744&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Apr 27 12:26:08 2016 >> @@ -5784,13 +5784,8 @@ void ASTWriter::AddedObjCCategoryToInter >> void ASTWriter::DeclarationMarkedUsed(const Decl *D) { >> assert(!WritingAST && "Already writing the AST!"); >> - >> - // If there is *any* declaration of the entity that's not from an AST >> file, >> - // we can skip writing the update record. We make sure that isUsed() >> triggers >> - // completion of the redeclaration chain of the entity. >> - for (auto Prev = D->getMostRecentDecl(); Prev; Prev = >> Prev->getPreviousDecl()) >> - if (IsLocalDecl(Prev)) >> - return; >> + if (!D->isFromASTFile()) >> + return; >> DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_USED)); >> } >> >> Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=267744&r1=267743&r2=267744&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Apr 27 12:26:08 2016 >> @@ -1541,6 +1541,16 @@ void ASTDeclWriter::VisitDeclContext(Dec >> } >> const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) { >> + /// \brief Is this a local declaration (that is, one that will be >> written to >> + /// our AST file)? This is the case for declarations that are neither >> imported >> + /// from another AST file nor predefined. >> + auto IsLocalDecl = [&](const Decl *D) -> bool { >> + if (D->isFromASTFile()) >> + return false; >> + auto I = DeclIDs.find(D); >> + return (I == DeclIDs.end() || I->second >= NUM_PREDEF_DECL_IDS); >> + }; >> + >> assert(IsLocalDecl(D) && "expected a local declaration"); >> const Decl *Canon = D->getCanonicalDecl(); >> >> Removed: cfe/trunk/test/Modules/pr27401.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pr27401.cpp?rev=267743&view=auto >> >> ============================================================================== >> --- cfe/trunk/test/Modules/pr27401.cpp (original) >> +++ cfe/trunk/test/Modules/pr27401.cpp (removed) >> @@ -1,38 +0,0 @@ >> -// RUN: rm -rf %t >> -// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27401 -verify %s >> -// RUN: %clang_cc1 -std=c++11 -fmodules >> -fmodule-map-file=%S/Inputs/PR27401/module.modulemap >> -fmodules-cache-path=%t -I%S/Inputs/PR27401 -verify %s >> - >> -#include "a.h" >> -#define _LIBCPP_VECTOR >> -template <class, class _Allocator> >> -class __vector_base { >> -protected: >> - _Allocator __alloc() const; >> - __vector_base(_Allocator); >> -}; >> - >> -template <class _Tp, class _Allocator = allocator> >> -class vector : __vector_base<_Tp, _Allocator> { >> -public: >> - vector() noexcept(is_nothrow_default_constructible<_Allocator>::value); >> - vector(const vector &); >> - vector(vector &&) >> - noexcept(is_nothrow_move_constructible<_Allocator>::value); >> -}; >> - >> -template <class _Tp, class _Allocator> >> -vector<_Tp, _Allocator>::vector(const vector &__x) : __vector_base<_Tp, >> _Allocator>(__x.__alloc()) {} >> - >> - struct CommentOptions { >> - vector<char> ParseAllComments; >> - CommentOptions() {} >> - }; >> - struct PrintingPolicy { >> - PrintingPolicy(CommentOptions LO) : LangOpts(LO) {} >> - CommentOptions LangOpts; >> - }; >> - >> -#include "b.h" >> -CommentOptions fn1() { return fn1(); } >> - >> -// expected-no-diagnostics >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits