llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vladislav Belov (vbe-sc)

<details>
<summary>Changes</summary>

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

```c++
template &lt;typename, typename, bool&gt; struct MozPromise {
  class Private;

private:
  int mMagic4 = 42;
};

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

Output:
```
clang: llvm-project/llvm/include/llvm/Support/Casting.h:566: decltype(auto) 
llvm::cast(const From&amp;) [with To = clang::RecordType; From = 
clang::QualType]: Assertion `isa&lt;To&gt;(Val) &amp;&amp; "cast&lt;Ty&gt;() 
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-&gt;getType()-&gt;castAs&lt;RecordType&gt;()-&gt;getDecl()-&gt;getCanonicalDecl()
 == BaseRecord;
```

It loses injected types for template class names. 

This patch provides fix for such cases

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


1 Files Affected:

- (modified) clang/lib/AST/CXXInheritance.cpp (+6-6) 


``````````diff
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.

``````````

</details>


https://github.com/llvm/llvm-project/pull/119024
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to