diff options
author | Vladislav Belov <vladislav.belov@syntacore.com> | 2024-12-09 12:28:26 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-09 10:28:26 +0100 |
commit | 01710aa345f2fb26e2312dd1c62bd0044fc75bed (patch) | |
tree | 2946f0731bdf1441253ec17b1bdad4c36ba623f8 /clang/lib/AST/CXXInheritance.cpp | |
parent | 98b694b66032b8b66b800a9ff44089245b3786dd (diff) | |
download | llvm-01710aa345f2fb26e2312dd1c62bd0044fc75bed.zip llvm-01710aa345f2fb26e2312dd1c62bd0044fc75bed.tar.gz llvm-01710aa345f2fb26e2312dd1c62bd0044fc75bed.tar.bz2 |
[clang] Fix cast for injected types in case name lookup for dependent bases (#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
Diffstat (limited to 'clang/lib/AST/CXXInheritance.cpp')
-rw-r--r-- | clang/lib/AST/CXXInheritance.cpp | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp index 10b8d52..ee57758 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. |