[clang] [Clang] Fix ICE in constraint normalization when substituting concept template parameters (PR #184406)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 4 09:12:44 PST 2026


================
@@ -4481,11 +4482,40 @@ ExprResult Sema::SubstConceptTemplateArguments(
 
     ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
                                              bool IsAddressOfOperand = false) {
-      if (E->isConceptReference()) {
-        ExprResult Res = SemaRef.SubstExpr(E, MLTAL);
-        return Res;
-      }
-      return E;
+      if (!E->isConceptReference())
+        return E;
+
+      assert(std::next(E->decls_begin()) == E->decls_end() &&
+             "ConceptReference must have single declaration");
+      NamedDecl *D = *E->decls_begin();
+      ConceptDecl *ResolvedConcept = nullptr;
+
+      if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
+        unsigned Depth = TTP->getDepth();
+        unsigned Pos = TTP->getPosition();
+        assert(Depth < MLTAL.getNumLevels() &&
+               MLTAL.hasTemplateArgument(Depth, Pos));
----------------
zyn0217 wrote:

Maybe we can't assert on this if the transformed expression needs to remain dependent.

I think what we want is, if provided with some template arguments (i.e. MLTAL _contains_ argument at `(Level, Depth)`), then they should be of `TemplateArgument::Template` type. If it doesn't have template arguments (at that level), then the transform should at least keep the expression dependent.

The assertion at 4499 is to catch mismatched template arguments, which are always bugs.

But I don't have a test case for dependent transform in mind, all the above are following our common instantiator implementation.

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


More information about the cfe-commits mailing list