Author: rsmith Date: Fri Mar 25 16:49:43 2016 New Revision: 264466 URL: http://llvm.org/viewvc/llvm-project?rev=264466&view=rev Log: Store list of undefined-but-used objects in a deterministic order to fix non-deterministic diagnostics (and non-deterministic PCH files). Check these when building a module rather than serializing it; it's not reasonable for a module's use to be satisfied by a definition in the user of the module.
Modified: cfe/trunk/include/clang/Sema/ExternalSemaSource.h cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/include/clang/Serialization/ASTReader.h cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp cfe/trunk/lib/Sema/Sema.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/test/SemaCXX/diagnostic-order.cpp Modified: cfe/trunk/include/clang/Sema/ExternalSemaSource.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ExternalSemaSource.h?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/ExternalSemaSource.h (original) +++ cfe/trunk/include/clang/Sema/ExternalSemaSource.h Fri Mar 25 16:49:43 2016 @@ -77,8 +77,8 @@ public: /// \brief Load the set of used but not defined functions or variables with /// internal linkage, or used but not defined internal functions. - virtual void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined); + virtual void + ReadUndefinedButUsed(llvm::MapVector<NamedDecl *, SourceLocation> &Undefined); virtual void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &); Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original) +++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Fri Mar 25 16:49:43 2016 @@ -211,7 +211,7 @@ public: /// \brief Load the set of used but not defined functions or variables with /// internal linkage, or used but not defined inline functions. void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override; + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) override; void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Fri Mar 25 16:49:43 2016 @@ -941,7 +941,7 @@ public: /// UndefinedInternals - all the used, undefined objects which require a /// definition in this translation unit. - llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed; + llvm::MapVector<NamedDecl *, SourceLocation> UndefinedButUsed; /// Obtain a sorted list of functions that are undefined but ODR-used. void getUndefinedButUsed( Modified: cfe/trunk/include/clang/Serialization/ASTReader.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) +++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Mar 25 16:49:43 2016 @@ -1807,7 +1807,7 @@ public: SmallVectorImpl<NamespaceDecl *> &Namespaces) override; void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override; + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) override; void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original) +++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Fri Mar 25 16:49:43 2016 @@ -204,7 +204,7 @@ void MultiplexExternalSemaSource::ReadKn } void MultiplexExternalSemaSource::ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined){ + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) { for(size_t i = 0; i < Sources.size(); ++i) Sources[i]->ReadUndefinedButUsed(Undefined); } Modified: cfe/trunk/lib/Sema/Sema.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.cpp (original) +++ cfe/trunk/lib/Sema/Sema.cpp Fri Mar 25 16:49:43 2016 @@ -478,10 +478,8 @@ static bool ShouldRemoveFromUnused(Sema /// Obtains a sorted list of functions that are undefined but ODR-used. void Sema::getUndefinedButUsed( SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined) { - for (llvm::DenseMap<NamedDecl *, SourceLocation>::iterator - I = UndefinedButUsed.begin(), E = UndefinedButUsed.end(); - I != E; ++I) { - NamedDecl *ND = I->first; + for (const auto &UndefinedUse : UndefinedButUsed) { + NamedDecl *ND = UndefinedUse.first; // Ignore attributes that have become invalid. if (ND->isInvalidDecl()) continue; @@ -502,24 +500,8 @@ void Sema::getUndefinedButUsed( continue; } - Undefined.push_back(std::make_pair(ND, I->second)); + Undefined.push_back(std::make_pair(ND, UndefinedUse.second)); } - - // Sort (in order of use site) so that we're not dependent on the iteration - // order through an llvm::DenseMap. - SourceManager &SM = Context.getSourceManager(); - std::sort(Undefined.begin(), Undefined.end(), - [&SM](const std::pair<NamedDecl *, SourceLocation> &l, - const std::pair<NamedDecl *, SourceLocation> &r) { - if (l.second.isValid() && !r.second.isValid()) - return true; - if (!l.second.isValid() && r.second.isValid()) - return false; - if (l.second != r.second) - return SM.isBeforeInTranslationUnit(l.second, r.second); - return SM.isBeforeInTranslationUnit(l.first->getLocation(), - r.first->getLocation()); - }); } /// checkUndefinedButUsed - Check for undefined objects with internal linkage @@ -554,6 +536,8 @@ static void checkUndefinedButUsed(Sema & if (I->second.isValid()) S.Diag(I->second, diag::note_used_here); } + + S.UndefinedButUsed.clear(); } void Sema::LoadExternalWeakUndeclaredIdentifiers() { @@ -749,6 +733,12 @@ void Sema::ActOnEndOfTranslationUnit() { !Diags.isIgnored(diag::warn_delegating_ctor_cycle, SourceLocation())) CheckDelegatingCtorCycles(); + if (!Diags.hasErrorOccurred()) { + if (ExternalSource) + ExternalSource->ReadUndefinedButUsed(UndefinedButUsed); + checkUndefinedButUsed(*this); + } + if (TUKind == TU_Module) { // If we are building a module, resolve all of the exported declarations // now. @@ -882,10 +872,6 @@ void Sema::ActOnEndOfTranslationUnit() { } } - if (ExternalSource) - ExternalSource->ReadUndefinedButUsed(UndefinedButUsed); - checkUndefinedButUsed(*this); - emitAndClearUnusedLocalTypedefWarnings(); } @@ -1271,8 +1257,7 @@ void ExternalSemaSource::ReadKnownNamesp } void ExternalSemaSource::ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) { -} + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {} void ExternalSemaSource::ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &) {} Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Mar 25 16:49:43 2016 @@ -7254,7 +7254,7 @@ void ASTReader::ReadKnownNamespaces( } void ASTReader::ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) { + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) { for (unsigned Idx = 0, N = UndefinedButUsed.size(); Idx != N;) { NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedButUsed[Idx++])); SourceLocation Loc = Modified: cfe/trunk/test/SemaCXX/diagnostic-order.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/diagnostic-order.cpp?rev=264466&r1=264465&r2=264466&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/diagnostic-order.cpp (original) +++ cfe/trunk/test/SemaCXX/diagnostic-order.cpp Fri Mar 25 16:49:43 2016 @@ -1,4 +1,7 @@ -// RUN: not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -std=c++11 %s -fsyntax-only 2>&1 | FileCheck %s +// RUN: %clang_cc1 -std=c++11 %s -fsyntax-only -DWARN 2>&1 | FileCheck %s --check-prefix=CHECK-WARN + +#ifndef WARN // Ensure that the diagnostics we produce for this situation appear in a // deterministic order. This requires ADL to provide lookup results in a @@ -55,3 +58,16 @@ int *p = Oper() + 0; // CHECK: in instantiation of template class 'Error<Oper, X *>' // CHECK: no type named 'error' in 'Oper' // CHECK: in instantiation of template class 'Error<Oper, Y *>' + +#endif + +template<typename T> struct UndefButUsed { + static inline int f(); + static int g() { return f(); } +}; +int undef_but_used = UndefButUsed<int>::g() + UndefButUsed<float>::g() + UndefButUsed<char>::g() + UndefButUsed<void>::g(); + +// CHECK-WARN: inline function 'UndefButUsed<int>::f' is not defined +// CHECK-WARN: inline function 'UndefButUsed<float>::f' is not defined +// CHECK-WARN: inline function 'UndefButUsed<char>::f' is not defined +// CHECK-WARN: inline function 'UndefButUsed<void>::f' is not defined _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits