[clang] [clang][Parse] Fix DeclContext reentry to use the template's lexical TU, not the current fragment's TU (PR #218571)

via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 24 18:54:42 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: anondeveg

<details>
<summary>Changes</summary>

Problem:
when  `-fdelayed-template-parsing` is enabled Instantiating a late-parsed function template defined in an earlier TU caused an assertion failure in `clang::Sema::PushDeclContext`:

``DC->getLexicalParent() == CurContext && "The next DeclContext should be lexically contained in the current one."'`

Fix:
- 1 in `Parser::ParseLateTemplatedFuncDef` obtained the enclosing `TranslationUnitDecl` called it `LexicalTU` 
- 2 changed `GlobalSavedContext` with the `LexicalTU` instead of using `Actions.Context.getTranslationUnitDecl()` 
- in the case that no `LexicalTU` was found fellback to `Actions.Context.getTranslationUnitDecl()`
 
Fixes 217073

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


1 Files Affected:

- (modified) clang/lib/Parse/ParseTemplate.cpp (+14-6) 


``````````diff
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 735a9bd1f9f1c..cba4a29888516 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1451,17 +1451,25 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
   // Track template parameter depth.
   TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
 
-  // To restore the context after late parsing.
-  Sema::ContextRAII GlobalSavedContext(
-      Actions, Actions.Context.getTranslationUnitDecl());
-
   MultiParseScope Scopes(*this);
 
   // Get the list of DeclContexts to reenter.
   SmallVector<DeclContext*, 4> DeclContextsToReenter;
-  for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit();
-       DC = DC->getLexicalParent())
+  DeclContext *LexicalTU = nullptr;
+  for (DeclContext *DC = FunD; DC; DC = DC->getLexicalParent()) {
+    if (DC->isTranslationUnit()) {
+      LexicalTU = DC;
+      break;
+    }
     DeclContextsToReenter.push_back(DC);
+  }
+
+  if (!LexicalTU) {
+    LexicalTU = Actions.Context.getTranslationUnitDecl();
+  }
+
+  // To restore the context after late parsing.
+  Sema::ContextRAII GlobalSavedContext(Actions, LexicalTU);
 
   // Reenter scopes from outermost to innermost.
   for (DeclContext *DC : reverse(DeclContextsToReenter)) {

``````````

</details>


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


More information about the cfe-commits mailing list