[clang] [clang] Substitute alias templates from correct context (PR #75069)

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 11 10:55:23 PST 2023


Fznamznon wrote:

> Can you point out the diff from the previous patch?

To fix the following case:
```
// Test case that regressed with the first iteration of the fix
template <typename T> class SP {
    T* data;
};

template <typename T> class A {
    static SP<A> foo();
};

template<typename T> using TRet = SP<A<T>>;

template<typename T> TRet<T> A<T>::foo() { return TRet<T>{};}; // failed with error bc TRet and SP<A>
                                                                                      // had different canonical types due to my change.
```
I had to disable `Sema::CurContext` switch when the type is rebuilt by `Sema::RebuildTypeInCurrentInstantiation` routine since its whole point is to rebuild the type looking at it from different context. There is comment above definition of `Sema::RebuildTypeInCurrentInstantiation` explaining what it does. 

The concrete important diff is:
```
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8738,7 +8738,7 @@ public:
                              SourceLocation IILoc,
                              bool DeducedTSTContext = true);

-
+  bool RebuildingTypesInCurrentInstantiation = false;
   TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
                                                     SourceLocation Loc,
                                                     DeclarationName Name);

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3157700607e0..810a93f37d74 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -39,6 +39,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/SaveAndRestore.h"

 #include <iterator>
 #include <optional>
@@ -3990,12 +3991,12 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
     if (Inst.isInvalid())
       return QualType();

-    {
-      bool ForLambdaCallOperator = false;
-      if (const auto *Rec = dyn_cast<CXXRecordDecl>(Pattern->getDeclContext()))
-        ForLambdaCallOperator = Rec->isLambda();
-      Sema::ContextRAII SavedContext(*this, Pattern->getDeclContext(),
-                                     !ForLambdaCallOperator);
+    if (!RebuildingTypesInCurrentInstantiation) {
+      Sema::ContextRAII SavedContext(*this, Pattern->getDeclContext());
+      CanonType =
+          SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
+                    AliasTemplate->getLocation(), AliasTemplate->getDeclName());
+    } else {
       CanonType =
           SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
                     AliasTemplate->getLocation(), AliasTemplate->getDeclName());
@@ -11399,6 +11400,8 @@ TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
   if (!T || !T->getType()->isInstantiationDependentType())
     return T;

+  llvm::SaveAndRestore DisableContextSwitchForTypeAliases(
+      RebuildingTypesInCurrentInstantiation, true);
   CurrentInstantiationRebuilder Rebuilder(*this, Loc, Name);
   return Rebuilder.TransformType(T);
 }

```

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


More information about the cfe-commits mailing list