Skip to content

Commit ab3d7e8

Browse files
committed
Separating the cache for the existence of address discrimination
Codegen needs to be able to test this, so we need to be able to rely on queries to the ASTContext.
1 parent fed1625 commit ab3d7e8

File tree

5 files changed

+103
-108
lines changed

5 files changed

+103
-108
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 13 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -620,61 +620,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
620620
ParameterIndexTable ParamIndices;
621621

622622
public:
623-
struct TypeRelocationInfo {
624-
static TypeRelocationInfo invalid() {
625-
TypeRelocationInfo Result;
626-
Result.IsRelocatable = false;
627-
Result.IsReplaceable = false;
628-
return Result;
623+
struct CXXRecordDeclRelocationInfo {
624+
static CXXRecordDeclRelocationInfo NonRelocatable() {
625+
return {false, false};
629626
}
630627

631-
TypeRelocationInfo() {}
632-
TypeRelocationInfo(bool IsRelocatable, bool IsReplaceable,
633-
bool HasAddressDiscriminatedValues)
634-
: IsUnion(false), IsRelocatable(IsRelocatable),
635-
IsReplaceable(IsReplaceable),
636-
HasAddressDiscriminatedValues(HasAddressDiscriminatedValues) {}
637-
638-
void setIsUnion(bool Union) {
639-
IsUnion = Union;
640-
normalizeState();
641-
}
642-
void updateRelocatable(bool Relocatable) { IsRelocatable &= Relocatable; }
643-
void updateReplaceable(bool Replaceable) { IsReplaceable &= Replaceable; }
644-
void
645-
updateContainsAddressDiscriminatedValues(bool AddressDiscriminatedValues) {
646-
HasAddressDiscriminatedValues |= AddressDiscriminatedValues;
647-
normalizeState();
648-
}
649-
void mergeWithSiblingMember(bool IsUnion, const TypeRelocationInfo &Other) {
650-
updateRelocatable(Other.IsRelocatable);
651-
updateReplaceable(Other.IsReplaceable);
652-
normalizeState();
653-
}
654-
bool isRelocatable() const { return IsRelocatable; }
655-
bool isReplaceable() const { return IsReplaceable; }
656-
bool hasAddressDiscriminatedPointerAuth() const {
657-
return HasAddressDiscriminatedValues;
658-
}
659-
660-
private:
661-
void normalizeState() {
662-
if (!IsUnion || !HasAddressDiscriminatedValues)
663-
return;
664-
IsRelocatable = false;
665-
IsReplaceable = false;
666-
}
667-
bool IsUnion = false;
668-
bool IsRelocatable = true;
669-
bool IsReplaceable = true;
670-
bool HasAddressDiscriminatedValues = false;
628+
unsigned IsRelocatable;
629+
unsigned IsReplaceable;
671630
};
672-
std::optional<TypeRelocationInfo>
631+
std::optional<CXXRecordDeclRelocationInfo>
673632
getRelocationInfoForCXXRecord(const CXXRecordDecl *) const;
674-
void setRelocationInfoForCXXRecord(const CXXRecordDecl *, TypeRelocationInfo);
633+
void setRelocationInfoForCXXRecord(const CXXRecordDecl *,
634+
const CXXRecordDeclRelocationInfo &);
635+
bool containsAddressDiscriminatedPointerAuth(QualType T);
675636

676637
private:
677-
llvm::DenseMap<const CXXRecordDecl *, TypeRelocationInfo> RelocationInfo;
638+
llvm::DenseMap<const CXXRecordDecl *, CXXRecordDeclRelocationInfo>
639+
RelocatableClasses;
640+
llvm::DenseMap<const RecordDecl *, bool>
641+
RecordContainsAddressDiscriminatedPointerAuth;
678642

679643
ImportDecl *FirstLocalImport = nullptr;
680644
ImportDecl *LastLocalImport = nullptr;

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4343,10 +4343,10 @@ class Sema final : public SemaBase {
43434343
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl,
43444344
SourceRange BraceRange);
43454345

4346-
ASTContext::TypeRelocationInfo
4347-
GetCXX2CTypeRelocationInfo(const clang::CXXRecordDecl *D);
4348-
4349-
ASTContext::TypeRelocationInfo GetCXX2CTypeRelocationInfo(QualType T);
4346+
using CXXRecordDeclRelocationInfo = ASTContext::CXXRecordDeclRelocationInfo;
4347+
CXXRecordDeclRelocationInfo
4348+
CheckCXX2CRelocatableAndReplaceable(const clang::CXXRecordDecl *D);
4349+
CXXRecordDeclRelocationInfo CheckCXX2CRelocatableAndReplaceable(QualType T);
43504350

43514351
void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context);
43524352

clang/lib/AST/ASTContext.cpp

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,22 +1687,56 @@ void ASTContext::getOverriddenMethods(
16871687
Overridden.append(OverDecls.begin(), OverDecls.end());
16881688
}
16891689

1690-
std::optional<ASTContext::TypeRelocationInfo>
1690+
std::optional<ASTContext::CXXRecordDeclRelocationInfo>
16911691
ASTContext::getRelocationInfoForCXXRecord(const CXXRecordDecl *RD) const {
16921692
assert(RD);
16931693
CXXRecordDecl *D = RD->getDefinition();
1694-
auto it = RelocationInfo.find(D);
1695-
if (it != RelocationInfo.end())
1694+
auto it = RelocatableClasses.find(D);
1695+
if (it != RelocatableClasses.end())
16961696
return it->getSecond();
16971697
return std::nullopt;
16981698
}
16991699

1700-
void ASTContext::setRelocationInfoForCXXRecord(const CXXRecordDecl *RD,
1701-
TypeRelocationInfo Info) {
1700+
void ASTContext::setRelocationInfoForCXXRecord(
1701+
const CXXRecordDecl *RD, const CXXRecordDeclRelocationInfo &Info) {
17021702
assert(RD);
17031703
CXXRecordDecl *D = RD->getDefinition();
1704-
assert(RelocationInfo.find(D) == RelocationInfo.end());
1705-
RelocationInfo.insert({D, Info});
1704+
assert(RelocatableClasses.find(D) == RelocatableClasses.end());
1705+
RelocatableClasses.insert({D, Info});
1706+
}
1707+
1708+
bool ASTContext::containsAddressDiscriminatedPointerAuth(QualType T) {
1709+
if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthIntrinsics)
1710+
return false;
1711+
1712+
T = T.getCanonicalType();
1713+
if (T.hasAddressDiscriminatedPointerAuth())
1714+
return true;
1715+
const RecordDecl *RD = T->getAsRecordDecl();
1716+
if (!RD)
1717+
return false;
1718+
1719+
auto SaveReturn = [this, RD](bool Result) {
1720+
RecordContainsAddressDiscriminatedPointerAuth.insert({RD, Result});
1721+
return Result;
1722+
};
1723+
if (auto Existing = RecordContainsAddressDiscriminatedPointerAuth.find(RD);
1724+
Existing != RecordContainsAddressDiscriminatedPointerAuth.end())
1725+
return Existing->second;
1726+
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1727+
if (CXXRD->isPolymorphic() &&
1728+
hasAddressDiscriminatedVTableAuthentication(CXXRD))
1729+
return SaveReturn(true);
1730+
for (auto Base : CXXRD->bases()) {
1731+
if (containsAddressDiscriminatedPointerAuth(Base.getType()))
1732+
return SaveReturn(true);
1733+
}
1734+
}
1735+
for (auto *FieldDecl : RD->fields()) {
1736+
if (containsAddressDiscriminatedPointerAuth(FieldDecl->getType()))
1737+
return SaveReturn(true);
1738+
}
1739+
return SaveReturn(false);
17061740
}
17071741

17081742
void ASTContext::addedLocalImportDecl(ImportDecl *Import) {

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10615,7 +10615,7 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) {
1061510615
}
1061610616
}
1061710617

10618-
if (GetCXX2CTypeRelocationInfo(&RD).isRelocatable())
10618+
if (CheckCXX2CRelocatableAndReplaceable(&RD).IsRelocatable)
1061910619
return;
1062010620

1062110621
// Ill-formed if the copy and move constructors are deleted.

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,13 @@ static bool IsEligibleForReplacement(Sema &SemaRef, const CXXRecordDecl *D) {
226226
return !D->hasDeletedDestructor();
227227
}
228228

229-
ASTContext::TypeRelocationInfo
230-
Sema::GetCXX2CTypeRelocationInfo(const CXXRecordDecl *D) {
229+
ASTContext::CXXRecordDeclRelocationInfo
230+
Sema::CheckCXX2CRelocatableAndReplaceable(const CXXRecordDecl *D) {
231231
if (auto ExistingInfo = Context.getRelocationInfoForCXXRecord(D))
232232
return *ExistingInfo;
233233

234234
if (!getLangOpts().CPlusPlus || D->isInvalidDecl())
235-
return ASTContext::TypeRelocationInfo::invalid();
235+
return CXXRecordDeclRelocationInfo::NonRelocatable();
236236

237237
assert(D->hasDefinition());
238238

@@ -260,9 +260,8 @@ Sema::GetCXX2CTypeRelocationInfo(const CXXRecordDecl *D) {
260260
return *Is;
261261
};
262262

263-
ASTContext::TypeRelocationInfo Info;
264-
265-
Info.updateRelocatable([&] {
263+
ASTContext::CXXRecordDeclRelocationInfo Info;
264+
Info.IsRelocatable = [&] {
266265
if (D->isDependentType())
267266
return false;
268267

@@ -280,9 +279,9 @@ Sema::GetCXX2CTypeRelocationInfo(const CXXRecordDecl *D) {
280279

281280
// is default-movable.
282281
return IsDefaultMovable();
283-
}());
282+
}();
284283

285-
Info.updateReplaceable([&] {
284+
Info.IsReplaceable = [&] {
286285
if (D->isDependentType())
287286
return false;
288287

@@ -300,42 +299,45 @@ Sema::GetCXX2CTypeRelocationInfo(const CXXRecordDecl *D) {
300299

301300
// is default-movable.
302301
return IsDefaultMovable();
303-
}());
304-
305-
Info.setIsUnion(D->isUnion());
302+
}();
306303

307304
bool PtrauthMatters = LangOpts.PointerAuthIntrinsics ||
308305
LangOpts.PointerAuthVTPtrAddressDiscrimination;
309306
if (PtrauthMatters) {
310-
auto IsBottomRelocationInfo =
311-
[](const ASTContext::TypeRelocationInfo &Info) {
312-
return !Info.isReplaceable() && !Info.isRelocatable() &&
313-
Info.hasAddressDiscriminatedPointerAuth();
314-
};
307+
bool IsUnion = D->isUnion();
308+
auto RecordPointerAuth = [&](bool HasAddressDiscrimination) {
309+
if (HasAddressDiscrimination && IsUnion) {
310+
Info.IsRelocatable = false;
311+
Info.IsReplaceable = false;
312+
}
313+
};
314+
auto IsBottomRelocationInfo = [](const CXXRecordDeclRelocationInfo &Info) {
315+
return !Info.IsReplaceable && !Info.IsRelocatable;
316+
};
315317

316318
if (D->isPolymorphic())
317-
Info.updateContainsAddressDiscriminatedValues(
318-
Context.hasAddressDiscriminatedVTableAuthentication(D));
319+
RecordPointerAuth(Context.hasAddressDiscriminatedVTableAuthentication(D));
319320
for (auto Base : D->bases()) {
320321
if (IsBottomRelocationInfo(Info))
321322
break;
322-
bool BaseHasPtrauth = GetCXX2CTypeRelocationInfo(Base.getType())
323-
.hasAddressDiscriminatedPointerAuth();
324-
Info.updateContainsAddressDiscriminatedValues(BaseHasPtrauth);
323+
bool BaseHasPtrauth =
324+
Context.containsAddressDiscriminatedPointerAuth(Base.getType());
325+
RecordPointerAuth(BaseHasPtrauth);
325326
}
326327
for (auto *FieldDecl : D->fields()) {
327328
if (IsBottomRelocationInfo(Info))
328329
break;
329-
bool FieldHasPtrauth = GetCXX2CTypeRelocationInfo(FieldDecl->getType())
330-
.hasAddressDiscriminatedPointerAuth();
331-
Info.updateContainsAddressDiscriminatedValues(FieldHasPtrauth);
330+
bool FieldHasPtrauth =
331+
Context.containsAddressDiscriminatedPointerAuth(FieldDecl->getType());
332+
RecordPointerAuth(FieldHasPtrauth);
332333
}
333334
}
334335
Context.setRelocationInfoForCXXRecord(D, Info);
335336
return Info;
336337
}
337338

338-
ASTContext::TypeRelocationInfo Sema::GetCXX2CTypeRelocationInfo(QualType T) {
339+
ASTContext::CXXRecordDeclRelocationInfo
340+
Sema::CheckCXX2CRelocatableAndReplaceable(QualType T) {
339341
T = T.getCanonicalType();
340342
enum class DirectRelocationInformation { Yes, No, Unknown };
341343
DirectRelocationInformation Relocatable =
@@ -356,10 +358,8 @@ ASTContext::TypeRelocationInfo Sema::GetCXX2CTypeRelocationInfo(QualType T) {
356358
Replaceable = DRI;
357359
};
358360
auto UpdateAddressDiscrimination = [&](DirectRelocationInformation DRI) {
359-
if (ContainsAddressDiscriminatedValues ==
360-
DirectRelocationInformation::Unknown ||
361-
ContainsAddressDiscriminatedValues == DirectRelocationInformation::No)
362-
ContainsAddressDiscriminatedValues = DRI;
361+
if (ContainsAddressDiscriminatedValues == DirectRelocationInformation::Yes)
362+
Replaceable = DirectRelocationInformation::No;
363363
};
364364

365365
if (T->isVariableArrayType()) {
@@ -393,12 +393,9 @@ ASTContext::TypeRelocationInfo Sema::GetCXX2CTypeRelocationInfo(QualType T) {
393393
if (BaseElementType->isVectorType())
394394
UpdateRelocatable(DirectRelocationInformation::Yes);
395395

396-
auto CreateInfo = [=]() -> ASTContext::TypeRelocationInfo {
397-
ASTContext::TypeRelocationInfo Result;
396+
auto CreateInfo = [=]() -> CXXRecordDeclRelocationInfo {
398397
return {Relocatable == DirectRelocationInformation::Yes,
399-
Replaceable == DirectRelocationInformation::Yes,
400-
ContainsAddressDiscriminatedValues ==
401-
DirectRelocationInformation::Yes};
398+
Replaceable == DirectRelocationInformation::Yes};
402399
};
403400

404401
if (BaseElementType->isIncompleteType())
@@ -408,20 +405,18 @@ ASTContext::TypeRelocationInfo Sema::GetCXX2CTypeRelocationInfo(QualType T) {
408405
if (!RD)
409406
return CreateInfo();
410407

411-
ASTContext::TypeRelocationInfo Info = GetCXX2CTypeRelocationInfo(RD);
412-
Info.updateRelocatable(Relocatable != DirectRelocationInformation::No);
413-
Info.updateReplaceable(Replaceable != DirectRelocationInformation::No);
414-
Info.updateContainsAddressDiscriminatedValues(
415-
ContainsAddressDiscriminatedValues == DirectRelocationInformation::Yes);
408+
CXXRecordDeclRelocationInfo Info = CheckCXX2CRelocatableAndReplaceable(RD);
409+
Info.IsRelocatable &= Relocatable != DirectRelocationInformation::No;
410+
Info.IsReplaceable &= Replaceable != DirectRelocationInformation::No;
416411
return Info;
417412
}
418413

419414
bool Sema::IsCXXTriviallyRelocatableType(QualType Type) {
420-
return GetCXX2CTypeRelocationInfo(Type).isRelocatable();
415+
return CheckCXX2CRelocatableAndReplaceable(Type).IsRelocatable;
421416
}
422417

423418
bool Sema::IsCXXReplaceableType(QualType Type) {
424-
return GetCXX2CTypeRelocationInfo(Type).isReplaceable();
419+
return CheckCXX2CRelocatableAndReplaceable(Type).IsReplaceable;
425420
}
426421

427422
/// Checks that type T is not a VLA.
@@ -722,7 +717,8 @@ static bool isTriviallyEqualityComparableType(Sema &S, QualType Type,
722717
}
723718

724719
static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
725-
QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);
720+
ASTContext &Ctx = SemaRef.getASTContext();
721+
QualType BaseElementType = Ctx.getBaseElementType(T);
726722

727723
if (BaseElementType->isIncompleteType())
728724
return false;
@@ -732,13 +728,14 @@ static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
732728
if (T.hasAddressDiscriminatedPointerAuth())
733729
return false;
734730

731+
if (Ctx.containsAddressDiscriminatedPointerAuth(BaseElementType))
732+
return false;
733+
735734
if (const auto *RD = BaseElementType->getAsCXXRecordDecl();
736735
RD && !RD->isPolymorphic()) {
737-
ASTContext::TypeRelocationInfo Info =
738-
SemaRef.GetCXX2CTypeRelocationInfo(RD);
739-
if (Info.hasAddressDiscriminatedPointerAuth())
740-
return false;
741-
if (Info.isRelocatable())
736+
ASTContext::CXXRecordDeclRelocationInfo Info =
737+
SemaRef.CheckCXX2CRelocatableAndReplaceable(RD);
738+
if (Info.IsRelocatable)
742739
return true;
743740
}
744741

0 commit comments

Comments
 (0)