Author: rsmith Date: Wed Feb 22 20:09:03 2017 New Revision: 295921 URL: http://llvm.org/viewvc/llvm-project?rev=295921&view=rev Log: Fix tracking of whether the previous template instantiation stack matches the current one.
Rather than attempting to compare whether the previous and current top of context stack are "equal" (which fails for a number of reasons, such as the context stack entries containing pointers to objects on the stack, or reaching the same "top of stack" entry through two different paths), track the depth of context stack at which we last emitted a note and invalidate it when we pop the context stack to less than that depth. This causes us to emit some missing "in instantiation of" notes and to stop emitting redundant "in instantiation of" stacks matching the previous stack in rare cases. Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp cfe/trunk/test/CXX/drs/dr4xx.cpp cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp cfe/trunk/test/SemaCXX/libstdcxx_pair_swap_hack.cpp cfe/trunk/test/SemaCXX/make_integer_seq.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=295921&r1=295920&r2=295921&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Wed Feb 22 20:09:03 2017 @@ -6922,39 +6922,6 @@ public: /// \brief Determines whether this template is an actual instantiation /// that should be counted toward the maximum instantiation depth. bool isInstantiationRecord() const; - - friend bool operator==(const CodeSynthesisContext &X, - const CodeSynthesisContext &Y) { - if (X.Kind != Y.Kind) - return false; - - if (X.Entity != Y.Entity) - return false; - - switch (X.Kind) { - case TemplateInstantiation: - case ExceptionSpecInstantiation: - return true; - - case PriorTemplateArgumentSubstitution: - case DefaultTemplateArgumentChecking: - return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs; - - case DefaultTemplateArgumentInstantiation: - case ExplicitTemplateArgumentSubstitution: - case DeducedTemplateArgumentSubstitution: - case DefaultFunctionArgumentInstantiation: - return X.TemplateArgs == Y.TemplateArgs; - - } - - llvm_unreachable("Invalid InstantiationKind!"); - } - - friend bool operator!=(const CodeSynthesisContext &X, - const CodeSynthesisContext &Y) { - return !(X == Y); - } }; /// \brief List of active code synthesis contexts. @@ -7004,14 +6971,13 @@ public: // FIXME: Should we have a similar limit for other forms of synthesis? unsigned NonInstantiationEntries; - /// \brief The last template from which a template instantiation + /// \brief The depth of the context stack at the point when the most recent /// error or warning was produced. /// - /// This value is used to suppress printing of redundant template - /// instantiation backtraces when there are multiple errors in the - /// same instantiation. FIXME: Does this belong in Sema? It's tough - /// to implement it anywhere else. - CodeSynthesisContext LastTemplateInstantiationErrorContext; + /// This value is used to suppress printing of redundant context stacks + /// when there are multiple errors or warnings in the same instantiation. + // FIXME: Does this belong in Sema? It's tough to implement it anywhere else. + unsigned LastEmittedCodeSynthesisContextDepth = 0; /// \brief The current index into pack expansion arguments that will be /// used for substitution of parameter packs. @@ -7192,11 +7158,9 @@ public: void PrintContextStack() { if (!CodeSynthesisContexts.empty() && - CodeSynthesisContexts.back() != - LastTemplateInstantiationErrorContext) { + CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) { PrintInstantiationStack(); - LastTemplateInstantiationErrorContext = - CodeSynthesisContexts.back(); + LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size(); } } void PrintInstantiationStack(); Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=295921&r1=295920&r2=295921&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Feb 22 20:09:03 2017 @@ -11774,9 +11774,6 @@ static void RebuildLambdaScopeInfo(CXXMe Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, SkipBodyInfo *SkipBody) { - // Clear the last template instantiation error context. - LastTemplateInstantiationErrorContext = CodeSynthesisContext(); - if (!D) return D; FunctionDecl *FD = nullptr; Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=295921&r1=295920&r2=295921&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Feb 22 20:09:03 2017 @@ -369,6 +369,12 @@ void Sema::InstantiatingTemplate::Clear( SemaRef.CodeSynthesisContextLookupModules.pop_back(); } + // If we've left the code synthesis context for the current context stack, + // stop remembering that we've emitted that stack. + if (SemaRef.CodeSynthesisContexts.size() == + SemaRef.LastEmittedCodeSynthesisContextDepth) + SemaRef.LastEmittedCodeSynthesisContextDepth = 0; + if (!AlreadyInstantiating) SemaRef.InstantiatingSpecializations.erase( std::make_pair(Active.Entity, Active.Kind)); Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=295921&r1=295920&r2=295921&view=diff ============================================================================== --- cfe/trunk/test/CXX/drs/dr4xx.cpp (original) +++ cfe/trunk/test/CXX/drs/dr4xx.cpp Wed Feb 22 20:09:03 2017 @@ -35,9 +35,7 @@ namespace dr401 { // dr401: yes }; A<B> *b; // expected-note {{default argument}} - // FIXME: We're missing the "in instantiation of" note for the default - // argument here. - A<D> *d; + A<D> *d; // expected-note {{in instantiation of default argument}} struct E { template<class T, class U = typename T::type> class A : public T {}; Modified: cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp?rev=295921&r1=295920&r2=295921&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp Wed Feb 22 20:09:03 2017 @@ -912,7 +912,7 @@ struct X1 { template<class T> template<class U> int X1::X2<T>::fooG3(T (*fp)(U)) { return 0; } -X1::X2<int> x2; //expected-note 3{{in instantiation of}} +X1::X2<int> x2; //expected-note {{in instantiation of}} int run1 = x2.fooG2(); int run2 = x2.fooG3(); } // end ns Modified: cfe/trunk/test/SemaCXX/libstdcxx_pair_swap_hack.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/libstdcxx_pair_swap_hack.cpp?rev=295921&r1=295920&r2=295921&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/libstdcxx_pair_swap_hack.cpp (original) +++ cfe/trunk/test/SemaCXX/libstdcxx_pair_swap_hack.cpp Wed Feb 22 20:09:03 2017 @@ -88,7 +88,7 @@ namespace sad { CLASS<int, int> pi; - static_assert(!noexcept(pi.swap(pi)), ""); // expected-note {{in instantiation of}} + static_assert(!noexcept(pi.swap(pi)), ""); // expected-note 2{{in instantiation of exception specification for 'swap'}} } #endif Modified: cfe/trunk/test/SemaCXX/make_integer_seq.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/make_integer_seq.cpp?rev=295921&r1=295920&r2=295921&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/make_integer_seq.cpp (original) +++ cfe/trunk/test/SemaCXX/make_integer_seq.cpp Wed Feb 22 20:09:03 2017 @@ -43,7 +43,7 @@ enum Color : int { Red, Blue }; using illformed1 = ErrorSeq<Color, Blue>; // expected-note{{in instantiation}} -using illformed2 = ErrorSeq<int, -5>; +using illformed2 = ErrorSeq<int, -5>; // expected-note{{in instantiation}} template <typename T, T N> void f() {} __make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits