-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[clang] Fix cast for injected types in case name lookup for dependent bases #119024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Fix cast for injected types in case name lookup for dependent bases #119024
Conversation
@llvm/pr-subscribers-clang Author: Vladislav Belov (vbe-sc) ChangesAn assertion failure occurs in Clang when attempting to compile such an example: 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:
The reason is in the incorrect way of casting types when searching for names in base classes return Specifier->getType()->castAs<RecordType>()->getDecl()->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:
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.
|
9c501fc
to
e3fd6b1
Compare
@erichkeane, @cor3ntin, could you, please, take a look at this fix? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm this is a fix for #118003 ?
In which case we do not need changelog entry
clang/lib/AST/CXXInheritance.cpp
Outdated
return (cast<CXXRecordDecl>(Specifier->getType()->getAsRecordDecl()) | ||
->getCanonicalDecl()) == BaseRecord; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You do not need the outer parentheses here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
e3fd6b1
to
ce758d5
Compare
Yes, you are right |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@glandium, this is the fix for your example. Please, feel free to contact if you have any more troubles with this patch |
@@ -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()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this instead of:
Specifier->getType()->getAsCXXRecordDecl()
??
Same question throughout this patch.
An assertion failure occurs in Clang when attempting to compile such an example:
Output:
The reason is in the incorrect way of casting types when searching for names in base classes
It loses injected types for template class names.
This patch provides fix for such cases