[clang] [Clang][Sema] Don't treat error-recovery dependence as genuine templa… (PR #221440)

via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 5 05:29:08 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Anirudh Mathur (AnirudhMathur12)

<details>
<summary>Changes</summary>

…te dependence in ActOnTag

When a template argument fails to resolve (e.g. a namespace name used where a value is expected), Sema substitutes a RecoveryExpr with a dependent type so downstream code can recover gracefully. This error-induced dependence was being conflated with genuine template parameter dependence in ActOnTag's handling of TagUseKind::Reference/ Friend, causing computeDeclContext to report failure the same way it would for an actually-dependent nested-name-specifier. This tripped an assert in ActOnExplicitInstantiation that assumes dependent names can't reach explicit instantiation, when in fact the diagnostic had already been emitted at the point the RecoveryExpr was created.

Fixes #<!-- -->220525

---
Full diff: https://github.com/llvm/llvm-project/pull/221440.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+9-1) 
- (added) clang/test/SemaCXX/GH220525.cpp (+7) 


``````````diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d6114ccbae7fe..7f22701376770 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -18356,7 +18356,15 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
     if (TUK == TagUseKind::Friend || TUK == TagUseKind::Reference) {
       DC = computeDeclContext(SS, false);
       if (!DC) {
-        IsDependent = true;
+        if (SS.getScopeRep().getAsType() &&
+            !SS.getScopeRep().getAsType()->containsErrors()) {
+          // This is a genuinely dependent nested-name-specifier (e.g. it
+          // depends on an uninstantiated template parameter), not one that
+          // merely appears dependent because of an embedded error-recovery
+          // placeholder. Only in that genuine case should we defer/treat this
+          // as a dependent name for the caller to handle.
+          IsDependent = true;
+        }
         return true;
       }
     } else {
diff --git a/clang/test/SemaCXX/GH220525.cpp b/clang/test/SemaCXX/GH220525.cpp
new file mode 100644
index 0000000000000..5f34e67d70886
--- /dev/null
+++ b/clang/test/SemaCXX/GH220525.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+
+namespace foo {
+  template<typename T> struct S {}; // expected-note {{template parameter is declared here}}
+}
+template struct foo::S<foo>::bar; // expected-error {{template argument for template type parameter must be a type}} \
+                                  // expected-error {{unexpected namespace name 'foo': expected expression}}

``````````

</details>


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


More information about the cfe-commits mailing list