Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// For performance, track whether any function effects are in use.
mutable bool AnyFunctionEffects = false;

bool ExternalCopyConstructorsForExceptionObjectsLoaded = false;

const TargetInfo *Target = nullptr;
const TargetInfo *AuxTarget = nullptr;
clang::PrintingPolicy PrintingPolicy;
Expand Down Expand Up @@ -3362,6 +3364,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
const FunctionDecl *FD,
llvm::function_ref<void(FunctionDecl *)> Pred) const;

llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> *
getRecordToCopyCtor();

const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl *RD);

Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/ExternalASTSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ASTConsumer;
class ASTContext;
class ASTSourceDescriptor;
class CXXBaseSpecifier;
class CXXConstructorDecl;
class CXXCtorInitializer;
class CXXRecordDecl;
class DeclarationName;
Expand Down Expand Up @@ -175,6 +176,9 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs);

virtual void LoadExternalExceptionCopyingConstructors(
llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> &RecordToCtor);

/// Ensures that the table of all visible declarations inside this
/// context is up to date.
///
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/MultiplexExternalSemaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

void LoadExternalExceptionCopyingConstructors(
llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> &RecordToCtor)
override;

/// Ensures that the table of all visible declarations inside this
/// context is up to date.
void completeVisibleDeclsMap(const DeclContext *DC) override;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,8 @@ enum ASTRecordTypes {
UPDATE_MODULE_LOCAL_VISIBLE = 76,

UPDATE_TU_LOCAL_VISIBLE = 77,

MSCXXABI_EXCEPTION_COPYING_CONSTRUCTORS = 78,
};

/// Record types used within a source manager block.
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,12 @@ class ASTReader
/// The IDs of all decls with function effects to be checked.
SmallVector<GlobalDeclID> DeclsWithEffectsToVerify;

struct RecordAndCopyingCtor {
GlobalDeclID RecordID;
GlobalDeclID CtorID;
};
SmallVector<RecordAndCopyingCtor> RecordToCopyingCtor;

private:
struct ImportedSubmodule {
serialization::SubmoduleID ID;
Expand Down Expand Up @@ -2177,6 +2183,10 @@ class ASTReader
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

void LoadExternalExceptionCopyingConstructors(
llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> &RecordToCtor)
override;

/// Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13333,8 +13333,25 @@ ASTContext::createMangleNumberingContext() const {
return ABI->createMangleNumberingContext();
}

llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> *
ASTContext::getRecordToCopyCtor() {
if (ABI) { // TODO Why can this be null?
return ABI->getRecordToCopyCtor();
}
return nullptr;
}

const CXXConstructorDecl *
ASTContext::getCopyConstructorForExceptionObject(CXXRecordDecl *RD) {
if (!getTargetInfo().getCXXABI().isMicrosoft()) {
return nullptr;
}
if (ExternalSource && !ExternalCopyConstructorsForExceptionObjectsLoaded) {
auto *Map = ABI->getRecordToCopyCtor();
assert(Map);
ExternalSource->LoadExternalExceptionCopyingConstructors(*Map);
ExternalCopyConstructorsForExceptionObjectsLoaded = true;
}
return ABI->getCopyConstructorForExceptionObject(
cast<CXXRecordDecl>(RD->getFirstDecl()));
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/CXXABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class CXXABI {
virtual void addCopyConstructorForExceptionObject(CXXRecordDecl *,
CXXConstructorDecl *) = 0;

virtual llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> *
getRecordToCopyCtor() = 0;

/// Retrieves the mapping from class to copy constructor for this C++ ABI.
virtual const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl *) = 0;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/ExternalASTSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ bool ExternalASTSource::LoadExternalSpecializations(
return false;
}

void ExternalASTSource::LoadExternalExceptionCopyingConstructors(
llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> &) {}

void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {}

void ExternalASTSource::FindExternalLexicalDecls(
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ class ItaniumCXXABI : public CXXABI {
return Layout.getNonVirtualSize() == PointerSize;
}

llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> *
getRecordToCopyCtor() override {
return nullptr;
}

const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
return nullptr;
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/MicrosoftCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ class MicrosoftCXXABI : public CXXABI {
llvm_unreachable("unapplicable to the MS ABI");
}

llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> *
getRecordToCopyCtor() override {
return &RecordToCopyCtor;
}

const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
return RecordToCopyCtor[RD];
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/MultiplexExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ bool MultiplexExternalSemaSource::LoadExternalSpecializations(
return AnyNewSpecsLoaded;
}

void MultiplexExternalSemaSource::LoadExternalExceptionCopyingConstructors(
llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> &RecordToCtor) {
for (size_t i = 0; i < Sources.size(); ++i)
Sources[i]->LoadExternalExceptionCopyingConstructors(RecordToCtor);
}

void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
for(size_t i = 0; i < Sources.size(); ++i)
Sources[i]->completeVisibleDeclsMap(DC);
Expand Down
20 changes: 20 additions & 0 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4358,6 +4358,16 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
DeclsToCheckForDeferredDiags.insert(ReadDeclID(F, Record, I));
break;

case MSCXXABI_EXCEPTION_COPYING_CONSTRUCTORS:
if (Record.size() % 2 != 0)
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"Invalid MSCXXABI_EXCEPTION_COPYING_CONSTRUCTORS record");
for (unsigned I = 0, N = Record.size(); I < N; /* in loop */)
RecordToCopyingCtor.push_back(
{ReadDeclID(F, Record, I), ReadDeclID(F, Record, I)});
break;
}
}
}
Expand Down Expand Up @@ -8418,6 +8428,16 @@ bool ASTReader::LoadExternalSpecializations(
return NewDeclsFound;
}

void ASTReader::LoadExternalExceptionCopyingConstructors(
llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> &RecordToCtor) {
for (const auto &[RecordID, CtorID] : RecordToCopyingCtor) {
auto *RD = cast<CXXRecordDecl>(GetDecl(RecordID));
auto *CD = cast<CXXConstructorDecl>(GetDecl(CtorID));
RecordToCtor.insert({RD, CD});
}
RecordToCopyingCtor.clear();
}

void ASTReader::FindExternalLexicalDecls(
const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Decls) {
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5857,6 +5857,20 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {

if (!VTablesToEmit.empty())
Stream.EmitRecord(VTABLES_TO_EMIT, VTablesToEmit);

if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
const auto *RecordToCopyCtor = Context.getRecordToCopyCtor();
if (RecordToCopyCtor) {
RecordData ExceptionCopyingConstructors;
for (const auto &[RD, CD] : *RecordToCopyCtor) {
AddDeclRef(RD, ExceptionCopyingConstructors);
AddDeclRef(CD, ExceptionCopyingConstructors);
}
if (!ExceptionCopyingConstructors.empty())
Stream.EmitRecord(MSCXXABI_EXCEPTION_COPYING_CONSTRUCTORS,
ExceptionCopyingConstructors);
}
}
}

ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
Expand Down
13 changes: 13 additions & 0 deletions clang/test/CodeGenCXX/microsoft-abi-throw-pch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Regression test for https://github.com/llvm/llvm-project/issues/53486

// RUN: %clang_cc1 -x c++ -std=c++11 -fcxx-exceptions -fexceptions -triple=x86_64-pc-windows-msvc -emit-pch -building-pch-with-obj -fmodules-codegen -o %t.pch %S/microsoft-abi-throw-pch.h
// RUN: %clang_cc1 -x c++ -std=c++11 -fcxx-exceptions -fexceptions -triple=x86_64-pc-windows-msvc -include-pch %t.pch -emit-llvm -building-pch-with-obj -fmodules-codegen -o - %s | FileCheck %s

// CHECK-DAG: @"_CT??_R0?AUTrivial@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"??_R0?AUTrivial@@@8" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 1, i32 0 }, section ".xdata", comdat
// CHECK-DAG: @"_CTA1?AUTrivial@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"_CT??_R0?AUTrivial@@@81" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32)] }, section ".xdata", comdat

// CHECK-DAG: @"_CT??_R0?AUNonTrivial@@@8??0NonTrivial@@QEAA@AEBU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"??_R0?AUNonTrivial@@@8" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"??0NonTrivial@@QEAA@AEBU0@@Z" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32) }, section ".xdata", comdat
// CHECK-DAG: @"_CTA1?AUNonTrivial@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"_CT??_R0?AUNonTrivial@@@8??0NonTrivial@@QEAA@AEBU0@@Z1" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32)] }, section ".xdata", comdat

// CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QEAAXAEAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"??_R0?AUTemplateWithDefault@@@8" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"??$?_OH@TemplateWithDefault@@QEAAXAEAU0@@Z" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32) }, section ".xdata", comdat
// CHECK-DAG: @"_CTA1?AUTemplateWithDefault@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (ptr @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QEAAXAEAU0@@Z1" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32)] }, section ".xdata", comdat
30 changes: 30 additions & 0 deletions clang/test/CodeGenCXX/microsoft-abi-throw-pch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Header for PCH test microsoft-abi-throw-pch.cpp

struct Trivial {};

struct NonTrivial {
NonTrivial() = default;
NonTrivial(const NonTrivial &) noexcept {}
NonTrivial(NonTrivial &&) noexcept {}
};

struct TemplateWithDefault {
template <typename T>
static int f() {
return 0;
}
template <typename T = int>
TemplateWithDefault(TemplateWithDefault &, T = f<T>());
};

inline void throw_trivial() {
throw Trivial();
}

inline void throw_non_trivial() {
throw NonTrivial();
}

inline void throw_template(TemplateWithDefault &e) {
throw e;
}
Loading