-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang] Avoid triggering vtable instantiation for C++23 constexpr dtor #102605
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -7042,11 +7042,38 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { | |||
} | ||||
} | ||||
|
||||
bool EffectivelyConstexprDestructor = true; | ||||
// Avoid triggering vtable instantiation due to a dtor that is not | ||||
// "effectively constexpr" for better compatibility. | ||||
// See https://github.com/llvm/llvm-project/issues/102293 for more info. | ||||
if (isa<CXXDestructorDecl>(M)) { | ||||
auto Check = [](QualType T, auto &&Check) -> bool { | ||||
const CXXRecordDecl *RD = | ||||
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl(); | ||||
if (!RD || !RD->isCompleteDefinition()) | ||||
return true; | ||||
|
||||
if (!RD->hasConstexprDestructor()) | ||||
return false; | ||||
|
||||
for (const CXXBaseSpecifier &B : RD->bases()) | ||||
if (!Check(B.getType(), Check)) | ||||
return false; | ||||
for (const FieldDecl *FD : RD->fields()) | ||||
if (!Check(FD->getType(), Check)) | ||||
return false; | ||||
return true; | ||||
}; | ||||
EffectivelyConstexprDestructor = | ||||
Check(QualType(Record->getTypeForDecl(), 0), Check); | ||||
} | ||||
|
||||
Comment on lines
+7049
to
+7070
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think Could you try? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, unfortunately There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, because it's not effectively constexpr :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, woops, I meant it returns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Due to this llvm-project/clang/lib/AST/DeclCXX.cpp Line 1342 in 52126dc
I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh. That's unfortunate. Oh well, good enough! |
||||
// Define defaulted constexpr virtual functions that override a base class | ||||
// function right away. | ||||
// FIXME: We can defer doing this until the vtable is marked as used. | ||||
if (CSM != CXXSpecialMemberKind::Invalid && !M->isDeleted() && | ||||
M->isDefaulted() && M->isConstexpr() && M->size_overridden_methods()) | ||||
M->isDefaulted() && M->isConstexpr() && M->size_overridden_methods() && | ||||
EffectivelyConstexprDestructor) | ||||
DefineDefaultedFunction(*this, M, M->getLocation()); | ||||
|
||||
if (!Incomplete) | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s | ||
// expected-no-diagnostics | ||
|
||
template <typename T> static void destroy() { | ||
T t; | ||
++t; | ||
} | ||
|
||
struct Incomplete; | ||
|
||
template <typename = int> struct HasD { | ||
~HasD() { destroy<Incomplete*>(); } | ||
}; | ||
|
||
struct HasVT { | ||
virtual ~HasVT(); | ||
}; | ||
|
||
struct S : HasVT { | ||
HasD<> v; | ||
}; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happen if you do
(and do we care that it's probably going to complain about the destructor not being defined?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It complains
I suppose expectedly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think there NO tests checking that complain? |
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.
I think we want more comment here (and/or a reference to the issue)