[clang] [Clang] [Sema] Fix crash instantiating a member variable template partial specialization when the enclosing class template is deserialized (PR #202958)

Rex Technology via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 3 09:23:49 PDT 2026


================
@@ -2697,6 +2697,14 @@ void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl(
 
   RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
 
+  // A partial specialization whose primary template is invalid cannot be
+  // instantiated. Mark it invalid too so InstantiateClass skips it, the same
+  // way it already skips the invalid primary, instead of later looking for an
+  // instantiated primary that was never created.
+  if (VarTemplateDecl *Primary = D->getSpecializedTemplate();
+      Primary && Primary->isInvalidDecl())
+    D->setInvalidDecl();
----------------
RexTechnology1 wrote:

	Researched. The asymmetry is created at parse time, not by serialization. Declaring the primary cons_from substitutes its default arg type_identity_t<T>; since the unresolved include already raised a fatal error, that substitution bails via the hasFatalErrorOccurred() && hasUncompilableErrorOccurred() guard, so the primary is marked invalid. The partial spec has no such default arg, so nothing substitutes and it stays valid.
	It doesn't crash without a PCH because that same fatal error suppresses instantiation of wrapper<int,int> entirely (same guard in InstantiatingTemplate). Through a PCH the invalid-primary/valid-partial-spec state is serialized, and the consuming TU has no fatal error, so it instantiates the class: InstantiateClass skips the invalid primary but still instantiates the valid partial spec, which looks up the never-created primary and crashes.
	So the fix should keep the primary invalid (the fatal-error guard is doing its job) and invalidate the partial specs alongside it, so the AST stays consistent and the asserts hold. Invalidating the partial spec at the point the primary is invalidated seems cleanest. I'll go that route unless you'd prefer it handled elsewhere.

https://github.com/llvm/llvm-project/pull/202958


More information about the cfe-commits mailing list