Skip to content

Commit 986cca3

Browse files
authored
Merge branch 'main' into x86-widen-build-vector
2 parents 07cb6a2 + 20034ba commit 986cca3

File tree

104 files changed

+2449
-809
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+2449
-809
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ Potentially Breaking Changes
8282
- Downstream projects that previously linked only against ``clangDriver`` may
8383
now (also) need to link against the new ``clangOptions`` library, since
8484
options-related code has been moved out of the Driver into a separate library.
85+
- Clang now supports MSVC vector deleting destructors when targeting Windows.
86+
This means that vtables of classes with virtual destructors will contain a
87+
pointer to vector deleting destructor (instead of scalar deleting destructor)
88+
which in fact is a different symbol with different name and linkage. This
89+
may cause runtime failures if two binaries using the same class defining a
90+
virtual destructor are compiled with different versions of clang.
8591

8692
C/C++ Language Potentially Breaking Changes
8793
-------------------------------------------
@@ -588,6 +594,8 @@ Android Support
588594
Windows Support
589595
^^^^^^^^^^^^^^^
590596

597+
- Clang now supports MSVC vector deleting destructors (GH19772).
598+
591599
LoongArch Support
592600
^^^^^^^^^^^^^^^^^
593601
- Enable linker relaxation by default for loongarch64.

clang/include/clang/AST/ASTContext.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,18 @@ class ASTContext : public RefCountedBase<ASTContext> {
370370
mutable llvm::DenseSet<const FunctionDecl *> DestroyingOperatorDeletes;
371371
mutable llvm::DenseSet<const FunctionDecl *> TypeAwareOperatorNewAndDeletes;
372372

373+
/// Global and array operators delete are only required for MSVC deleting
374+
/// destructors support. Store them here to avoid keeping 4 pointers that are
375+
/// not always used in each redeclaration of the destructor.
376+
mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
377+
OperatorDeletesForVirtualDtor;
378+
mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
379+
GlobalOperatorDeletesForVirtualDtor;
380+
mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
381+
ArrayOperatorDeletesForVirtualDtor;
382+
mutable llvm::DenseMap<const CXXDestructorDecl *, FunctionDecl *>
383+
GlobalArrayOperatorDeletesForVirtualDtor;
384+
373385
/// The next string literal "version" to allocate during constant evaluation.
374386
/// This is used to distinguish between repeated evaluations of the same
375387
/// string literal.
@@ -3473,6 +3485,16 @@ class ASTContext : public RefCountedBase<ASTContext> {
34733485
bool IsTypeAware);
34743486
bool isTypeAwareOperatorNewOrDelete(const FunctionDecl *FD) const;
34753487

3488+
enum OperatorDeleteKind { Regular, GlobalRegular, Array, ArrayGlobal };
3489+
3490+
void addOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
3491+
FunctionDecl *OperatorDelete,
3492+
OperatorDeleteKind K) const;
3493+
FunctionDecl *getOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
3494+
OperatorDeleteKind K) const;
3495+
bool dtorHasOperatorDelete(const CXXDestructorDecl *Dtor,
3496+
OperatorDeleteKind K) const;
3497+
34763498
/// Retrieve the context for computing mangling numbers in the given
34773499
/// DeclContext.
34783500
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);

clang/include/clang/AST/ASTMutationListener.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ class ASTMutationListener {
9090
virtual void ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
9191
const FunctionDecl *GlobDelete) {}
9292

93+
/// A virtual destructor's operator array delete has been resolved.
94+
virtual void ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
95+
const FunctionDecl *ArrayDelete) {}
96+
97+
/// A virtual destructor's operator global array delete has been resolved.
98+
virtual void
99+
ResolvedOperatorGlobArrayDelete(const CXXDestructorDecl *DD,
100+
const FunctionDecl *GlobArrayDelete) {}
101+
93102
/// An implicit member got a definition.
94103
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
95104

clang/include/clang/AST/DeclCXX.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2872,8 +2872,6 @@ class CXXDestructorDecl : public CXXMethodDecl {
28722872

28732873
// FIXME: Don't allocate storage for these except in the first declaration
28742874
// of a virtual destructor.
2875-
FunctionDecl *OperatorDelete = nullptr;
2876-
FunctionDecl *OperatorGlobalDelete = nullptr;
28772875
Expr *OperatorDeleteThisArg = nullptr;
28782876

28792877
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
@@ -2900,14 +2898,12 @@ class CXXDestructorDecl : public CXXMethodDecl {
29002898

29012899
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
29022900
void setOperatorGlobalDelete(FunctionDecl *OD);
2903-
2904-
const FunctionDecl *getOperatorDelete() const {
2905-
return getCanonicalDecl()->OperatorDelete;
2906-
}
2907-
2908-
const FunctionDecl *getOperatorGlobalDelete() const {
2909-
return getCanonicalDecl()->OperatorGlobalDelete;
2910-
}
2901+
void setOperatorArrayDelete(FunctionDecl *OD);
2902+
void setGlobalOperatorArrayDelete(FunctionDecl *OD);
2903+
const FunctionDecl *getOperatorDelete() const;
2904+
const FunctionDecl *getOperatorGlobalDelete() const;
2905+
const FunctionDecl *getArrayOperatorDelete() const;
2906+
const FunctionDecl *getGlobalArrayOperatorDelete() const;
29112907

29122908
Expr *getOperatorDeleteThisArg() const {
29132909
return getCanonicalDecl()->OperatorDeleteThisArg;

clang/include/clang/AST/VTableBuilder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class VTableComponent {
150150

151151
bool isRTTIKind() const { return isRTTIKind(getKind()); }
152152

153-
GlobalDecl getGlobalDecl() const {
153+
GlobalDecl getGlobalDecl(bool HasVectorDeletingDtors) const {
154154
assert(isUsedFunctionPointerKind() &&
155155
"GlobalDecl can be created only from virtual function");
156156

@@ -161,7 +161,9 @@ class VTableComponent {
161161
case CK_CompleteDtorPointer:
162162
return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Complete);
163163
case CK_DeletingDtorPointer:
164-
return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Deleting);
164+
return GlobalDecl(DtorDecl, (HasVectorDeletingDtors)
165+
? CXXDtorType::Dtor_VectorDeleting
166+
: CXXDtorType::Dtor_Deleting);
165167
case CK_VCallOffset:
166168
case CK_VBaseOffset:
167169
case CK_OffsetToTop:

clang/include/clang/Basic/ABI.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ enum CXXCtorType {
3232

3333
/// C++ destructor types.
3434
enum CXXDtorType {
35-
Dtor_Deleting, ///< Deleting dtor
36-
Dtor_Complete, ///< Complete object dtor
37-
Dtor_Base, ///< Base object dtor
38-
Dtor_Comdat, ///< The COMDAT used for dtors
39-
Dtor_Unified, ///< GCC-style unified dtor
35+
Dtor_Deleting, ///< Deleting dtor
36+
Dtor_Complete, ///< Complete object dtor
37+
Dtor_Base, ///< Base object dtor
38+
Dtor_Comdat, ///< The COMDAT used for dtors
39+
Dtor_Unified, ///< GCC-style unified dtor
40+
Dtor_VectorDeleting, ///< Vector deleting dtor
4041
};
4142

4243
} // end namespace clang

clang/include/clang/Basic/TargetInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,11 @@ class TargetInfo : public TransferrableTargetInfo,
17961796
/// destructor body.
17971797
virtual bool callGlobalDeleteInDeletingDtor(const LangOptions &) const;
17981798

1799+
/// Controls whether to emit MSVC vector deleting destructors. The support for
1800+
/// vector deleting affects vtable layout and therefore is an ABI breaking
1801+
/// change. The support was only implemented at Clang 22 timeframe.
1802+
virtual bool emitVectorDeletingDtors(const LangOptions &) const;
1803+
17991804
/// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
18001805
/// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
18011806
virtual bool hasSjLjLowering() const {

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8570,7 +8570,8 @@ class Sema final : public SemaBase {
85708570
FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc,
85718571
CXXRecordDecl *RD,
85728572
bool Diagnose,
8573-
bool LookForGlobal);
8573+
bool LookForGlobal,
8574+
DeclarationName Name);
85748575

85758576
/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
85768577
/// @code ::delete ptr; @endcode

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,10 @@ class ASTWriter : public ASTDeserializationListener,
955955
Expr *ThisArg) override;
956956
void ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
957957
const FunctionDecl *Delete) override;
958+
void ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
959+
const FunctionDecl *Delete) override;
960+
void ResolvedOperatorGlobArrayDelete(const CXXDestructorDecl *DD,
961+
const FunctionDecl *Delete) override;
958962
void CompletedImplicitDefinition(const FunctionDecl *D) override;
959963
void InstantiationRequested(const ValueDecl *D) override;
960964
void VariableDefinitionInstantiated(const VarDecl *D) override;

clang/lib/AST/ASTContext.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13333,6 +13333,71 @@ bool ASTContext::isTypeAwareOperatorNewOrDelete(const FunctionDecl *FD) const {
1333313333
return TypeAwareOperatorNewAndDeletes.contains(FD->getCanonicalDecl());
1333413334
}
1333513335

13336+
void ASTContext::addOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
13337+
FunctionDecl *OperatorDelete,
13338+
OperatorDeleteKind K) const {
13339+
switch (K) {
13340+
case OperatorDeleteKind::Regular:
13341+
OperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] = OperatorDelete;
13342+
break;
13343+
case OperatorDeleteKind::GlobalRegular:
13344+
GlobalOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] =
13345+
OperatorDelete;
13346+
break;
13347+
case OperatorDeleteKind::Array:
13348+
ArrayOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] =
13349+
OperatorDelete;
13350+
break;
13351+
case OperatorDeleteKind::ArrayGlobal:
13352+
GlobalArrayOperatorDeletesForVirtualDtor[Dtor->getCanonicalDecl()] =
13353+
OperatorDelete;
13354+
break;
13355+
}
13356+
}
13357+
13358+
bool ASTContext::dtorHasOperatorDelete(const CXXDestructorDecl *Dtor,
13359+
OperatorDeleteKind K) const {
13360+
switch (K) {
13361+
case OperatorDeleteKind::Regular:
13362+
return OperatorDeletesForVirtualDtor.contains(Dtor->getCanonicalDecl());
13363+
case OperatorDeleteKind::GlobalRegular:
13364+
return GlobalOperatorDeletesForVirtualDtor.contains(
13365+
Dtor->getCanonicalDecl());
13366+
case OperatorDeleteKind::Array:
13367+
return ArrayOperatorDeletesForVirtualDtor.contains(
13368+
Dtor->getCanonicalDecl());
13369+
case OperatorDeleteKind::ArrayGlobal:
13370+
return GlobalArrayOperatorDeletesForVirtualDtor.contains(
13371+
Dtor->getCanonicalDecl());
13372+
}
13373+
return false;
13374+
}
13375+
13376+
FunctionDecl *
13377+
ASTContext::getOperatorDeleteForVDtor(const CXXDestructorDecl *Dtor,
13378+
OperatorDeleteKind K) const {
13379+
const CXXDestructorDecl *Canon = Dtor->getCanonicalDecl();
13380+
switch (K) {
13381+
case OperatorDeleteKind::Regular:
13382+
if (OperatorDeletesForVirtualDtor.contains(Canon))
13383+
return OperatorDeletesForVirtualDtor[Canon];
13384+
return nullptr;
13385+
case OperatorDeleteKind::GlobalRegular:
13386+
if (GlobalOperatorDeletesForVirtualDtor.contains(Canon))
13387+
return GlobalOperatorDeletesForVirtualDtor[Canon];
13388+
return nullptr;
13389+
case OperatorDeleteKind::Array:
13390+
if (ArrayOperatorDeletesForVirtualDtor.contains(Canon))
13391+
return ArrayOperatorDeletesForVirtualDtor[Canon];
13392+
return nullptr;
13393+
case OperatorDeleteKind::ArrayGlobal:
13394+
if (GlobalArrayOperatorDeletesForVirtualDtor.contains(Canon))
13395+
return GlobalArrayOperatorDeletesForVirtualDtor[Canon];
13396+
return nullptr;
13397+
}
13398+
return nullptr;
13399+
}
13400+
1333613401
MangleNumberingContext &
1333713402
ASTContext::getManglingNumberContext(const DeclContext *DC) {
1333813403
assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.

0 commit comments

Comments
 (0)