r295921 - Fix tracking of whether the previous template instantiation stack matches the current one.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 22 18:09:04 PST 2017


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}}




More information about the cfe-commits mailing list