https://github.com/vbe-sc created 
https://github.com/llvm/llvm-project/pull/119024

An assertion failure occurs in Clang when attempting to compile such an example:

```c++
template <typename, typename, bool> struct MozPromise {
  class Private;

private:
  int mMagic4 = 42;
};

template <typename ResolveValueT, typename RejectValueT, bool IsExclusive>
struct MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private : 
MozPromise {
  void SetTaskPriority() { mMagic4 ; }
};
```

Output:
```
clang: llvm-project/llvm/include/llvm/Support/Casting.h:566: decltype(auto) 
llvm::cast(const From&) [with To = clang::RecordType; From = clang::QualType]: 
Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
```

The reason is in the incorrect way of casting types when searching for names in 
base classes

```c++
return 
Specifier->getType()->castAs<RecordType>()->getDecl()->getCanonicalDecl() == 
BaseRecord;
```

It loses injected types for template class names. 

This patch provides fix for such cases

>From 9c501fc54a9673e9755fdef2a55d040a6fcceea5 Mon Sep 17 00:00:00 2001
From: vb-sc <vladislav.be...@syntacore.com>
Date: Fri, 6 Dec 2024 23:06:01 +0300
Subject: [PATCH] [clang][NFC] Fix cast for injected types in case name lookup
 for dependent bases

---
 clang/lib/AST/CXXInheritance.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index 10b8d524ff8978..74848696963e99 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -368,8 +368,8 @@ bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier 
*Specifier,
                                   const CXXRecordDecl *BaseRecord) {
   assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
          "User data for FindBaseClass is not canonical!");
-  return Specifier->getType()->castAs<RecordType>()->getDecl()
-            ->getCanonicalDecl() == BaseRecord;
+  return (cast<CXXRecordDecl>(Specifier->getType()->getAsRecordDecl())
+              ->getCanonicalDecl()) == BaseRecord;
 }
 
 bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
@@ -378,8 +378,8 @@ bool CXXRecordDecl::FindVirtualBaseClass(const 
CXXBaseSpecifier *Specifier,
   assert(BaseRecord->getCanonicalDecl() == BaseRecord &&
          "User data for FindBaseClass is not canonical!");
   return Specifier->isVirtual() &&
-         Specifier->getType()->castAs<RecordType>()->getDecl()
-            ->getCanonicalDecl() == BaseRecord;
+         (cast<CXXRecordDecl>(Specifier->getType()->getAsRecordDecl())
+              ->getCanonicalDecl()) == BaseRecord;
 }
 
 static bool isOrdinaryMember(const NamedDecl *ND) {
@@ -692,7 +692,7 @@ AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext 
&Context,
            "Cannot get indirect primary bases for class with dependent 
bases.");
 
     const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+        cast<CXXRecordDecl>(I.getType()->getAsRecordDecl());
 
     // Only bases with virtual bases participate in computing the
     // indirect primary virtual base classes.
@@ -714,7 +714,7 @@ 
CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const {
            "Cannot get indirect primary bases for class with dependent 
bases.");
 
     const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+        cast<CXXRecordDecl>(I.getType()->getAsRecordDecl());
 
     // Only bases with virtual bases participate in computing the
     // indirect primary virtual base classes.

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to