Skip to content

Commit

Permalink
Merge commit 'd469794d0cdf' from llvm.org/main into next
Browse files Browse the repository at this point in the history
  • Loading branch information
git apple-llvm automerger committed Aug 12, 2024
2 parents daf74be + d469794 commit ae2ff5a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
29 changes: 28 additions & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

// 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)
Expand Down
22 changes: 22 additions & 0 deletions clang/test/SemaCXX/gh102293.cpp
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;
};

0 comments on commit ae2ff5a

Please sign in to comment.