[c++17] Fix assertion on synthesizing deduction guides after a fatal error.
authorVolodymyr Sapsai <vsapsai@apple.com>
Mon, 14 May 2018 22:49:44 +0000 (22:49 +0000)
committerVolodymyr Sapsai <vsapsai@apple.com>
Mon, 14 May 2018 22:49:44 +0000 (22:49 +0000)
After a fatal error Sema::InstantiatingTemplate doesn't allow further
instantiation and doesn't push a CodeSynthesisContext. When we tried to
synthesize implicit deduction guides from constructors we hit the
assertion

> Assertion failed: (!CodeSynthesisContexts.empty() && "Cannot perform an instantiation without some context on the " "instantiation stack"), function SubstType, file clang/lib/Sema/SemaTemplateInstantiate.cpp, line 1580.

Fix by avoiding deduction guide synthesis if InstantiatingTemplate is invalid.

rdar://problem/39051732

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D46446

llvm-svn: 332307

clang/lib/Sema/SemaTemplate.cpp
clang/test/SemaTemplate/instantiate-after-fatal-cxx17.cpp [new file with mode: 0644]

index 530fc668f2fdf5ff7cfb2968b1a464a0cc0c995f..a5f6b3f026f1543bc56c48763dcdc70b8c57abe9 100644 (file)
@@ -1976,6 +1976,8 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   // FIXME: Add a kind for this to give more meaningful diagnostics. But can
   // this substitution process actually fail?
   InstantiatingTemplate BuildingDeductionGuides(*this, Loc, Template);
+  if (BuildingDeductionGuides.isInvalid())
+    return;
 
   // Convert declared constructors into deduction guide templates.
   // FIXME: Skip constructors for which deduction must necessarily fail (those
diff --git a/clang/test/SemaTemplate/instantiate-after-fatal-cxx17.cpp b/clang/test/SemaTemplate/instantiate-after-fatal-cxx17.cpp
new file mode 100644 (file)
index 0000000..3e0ddf1
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: not %clang_cc1 -std=c++17 -fsyntax-only -ferror-limit 1 %s 2>&1 | FileCheck %s
+
+#error Error 1
+#error Error 2
+// CHECK: fatal error: too many errors emitted, stopping now
+
+namespace rdar39051732 {
+
+  template<class T> struct A {
+    template <class U> A(T&, ...);
+  };
+  // Deduction guide triggers constructor instantiation.
+  template<class T> A(const T&, const T&) -> A<T&>;
+
+}
+