[clang] Do not crash on template specialization following a fatal error
authorAdam Czachorowski <adamcz@google.com>
Thu, 15 Apr 2021 20:33:05 +0000 (22:33 +0200)
committerAdam Czachorowski <adamcz@google.com>
Fri, 23 Apr 2021 11:34:05 +0000 (13:34 +0200)
There was a missing isInvalid() check leading to an attempt to
instantiate template with an empty instantiation stack.

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

clang/lib/Sema/SemaTemplateDeduction.cpp
clang/test/SemaCXX/template-specialization-fatal.cpp [new file with mode: 0644]

index d755696..7d548e4 100644 (file)
@@ -5466,6 +5466,9 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2,
                                                Deduced.end());
   Sema::InstantiatingTemplate Inst(S, Info.getLocation(), P2, DeducedArgs,
                                    Info);
+  if (Inst.isInvalid())
+    return false;
+
   auto *TST1 = T1->castAs<TemplateSpecializationType>();
   bool AtLeastAsSpecialized;
   S.runWithSufficientStackSpace(Info.getLocation(), [&] {
diff --git a/clang/test/SemaCXX/template-specialization-fatal.cpp b/clang/test/SemaCXX/template-specialization-fatal.cpp
new file mode 100644 (file)
index 0000000..2191e54
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// Verify clang doesn't assert()-fail on template specialization happening after
+// fatal error.
+
+#include "not_found.h" // expected-error {{'not_found.h' file not found}}
+
+template <class A, class B, class = void>
+struct foo {};
+
+template <class A, class B>
+struct foo<A, B, decltype(static_cast<void (*)(B)>(0)(static_cast<A (*)()>(0)()))> {};