Skip to content

Commit 161328c

Browse files
ojhuntllvmbot
authored andcommitted
[clang][PAC] Fix builtins that claim address discriminated types are bitwise compatible (#154490)
A number of builtins report some variation of "this type is compatibile with some bitwise equivalent operation", but this is not true for address discriminated values. We had address a number of cases, but not all of them. This PR corrects the remaining builtins. Fixes #154394 (cherry picked from commit d66b537)
1 parent 3623fe6 commit 161328c

File tree

9 files changed

+448
-16
lines changed

9 files changed

+448
-16
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
634634
/// contain data that is address discriminated. This includes
635635
/// implicitly authenticated values like vtable pointers, as well as
636636
/// explicitly qualified fields.
637-
bool containsAddressDiscriminatedPointerAuth(QualType T) {
637+
bool containsAddressDiscriminatedPointerAuth(QualType T) const {
638638
if (!isPointerAuthenticationAvailable())
639639
return false;
640640
return findPointerAuthContent(T) != PointerAuthContent::None;
@@ -648,8 +648,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
648648
bool containsNonRelocatablePointerAuth(QualType T) {
649649
if (!isPointerAuthenticationAvailable())
650650
return false;
651-
return findPointerAuthContent(T) ==
652-
PointerAuthContent::AddressDiscriminatedData;
651+
return findPointerAuthContent(T) != PointerAuthContent::None;
653652
}
654653

655654
private:
@@ -667,8 +666,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
667666
bool isPointerAuthenticationAvailable() const {
668667
return LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;
669668
}
670-
PointerAuthContent findPointerAuthContent(QualType T);
671-
llvm::DenseMap<const RecordDecl *, PointerAuthContent>
669+
PointerAuthContent findPointerAuthContent(QualType T) const;
670+
mutable llvm::DenseMap<const RecordDecl *, PointerAuthContent>
672671
RecordContainsAddressDiscriminatedPointerAuth;
673672

674673
ImportDecl *FirstLocalImport = nullptr;
@@ -3698,7 +3697,7 @@ OPT_LIST(V)
36983697
/// Resolve the root record to be used to derive the vtable pointer
36993698
/// authentication policy for the specified record.
37003699
const CXXRecordDecl *
3701-
baseForVTableAuthentication(const CXXRecordDecl *ThisClass);
3700+
baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const;
37023701

37033702
bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,
37043703
StringRef MangledName);

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,7 @@ void ASTContext::setRelocationInfoForCXXRecord(
17061706
}
17071707

17081708
static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
1709-
ASTContext &Context, const CXXRecordDecl *Class) {
1709+
const ASTContext &Context, const CXXRecordDecl *Class) {
17101710
if (!Class->isPolymorphic())
17111711
return false;
17121712
const CXXRecordDecl *BaseType = Context.baseForVTableAuthentication(Class);
@@ -1721,7 +1721,8 @@ static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
17211721
return AddressDiscrimination == AuthAttr::AddressDiscrimination;
17221722
}
17231723

1724-
ASTContext::PointerAuthContent ASTContext::findPointerAuthContent(QualType T) {
1724+
ASTContext::PointerAuthContent
1725+
ASTContext::findPointerAuthContent(QualType T) const {
17251726
assert(isPointerAuthenticationAvailable());
17261727

17271728
T = T.getCanonicalType();
@@ -3032,7 +3033,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
30323033
return true;
30333034
}
30343035

3035-
// All other pointers (except __ptrauth pointers) are unique.
3036+
// All other pointers are unique.
30363037
if (Ty->isPointerType())
30373038
return !Ty.hasAddressDiscriminatedPointerAuth();
30383039

@@ -15106,7 +15107,7 @@ StringRef ASTContext::getCUIDHash() const {
1510615107
}
1510715108

1510815109
const CXXRecordDecl *
15109-
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) {
15110+
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const {
1511015111
assert(ThisClass);
1511115112
assert(ThisClass->isPolymorphic());
1511215113
const CXXRecordDecl *PrimaryBase = ThisClass;

clang/lib/AST/DeclCXX.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
14481448
data().StructuralIfLiteral = false;
14491449
}
14501450

1451+
// If this type contains any address discriminated values we should
1452+
// have already indicated that the only special member functions that
1453+
// can possibly be trivial are the default constructor and destructor.
1454+
if (T.hasAddressDiscriminatedPointerAuth())
1455+
data().HasTrivialSpecialMembers &=
1456+
SMF_DefaultConstructor | SMF_Destructor;
1457+
14511458
// C++14 [meta.unary.prop]p4:
14521459
// T is a class type [...] with [...] no non-static data members other
14531460
// than subobjects of zero size

clang/lib/AST/Type.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2715,6 +2715,11 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
27152715
return false;
27162716

27172717
QualType CanonicalType = getTypePtr()->CanonicalType;
2718+
2719+
// Any type that is, or contains, address discriminated data is never POD.
2720+
if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
2721+
return false;
2722+
27182723
switch (CanonicalType->getTypeClass()) {
27192724
// Everything not explicitly mentioned is not POD.
27202725
default:
@@ -2773,6 +2778,11 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
27732778
if (CanonicalType->isDependentType())
27742779
return false;
27752780

2781+
// Any type that is, or contains, address discriminated data is never a
2782+
// trivial type.
2783+
if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
2784+
return false;
2785+
27762786
// C++0x [basic.types]p9:
27772787
// Scalar types, trivial class types, arrays of such types, and
27782788
// cv-qualified versions of these types are collectively called trivial
@@ -2870,6 +2880,12 @@ bool QualType::isBitwiseCloneableType(const ASTContext &Context) const {
28702880

28712881
if (CanonicalType->isIncompleteType())
28722882
return false;
2883+
2884+
// Any type that is, or contains, address discriminated data is never
2885+
// bitwise clonable.
2886+
if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
2887+
return false;
2888+
28732889
const auto *RD = CanonicalType->getAsRecordDecl(); // struct/union/class
28742890
if (!RD)
28752891
return true;
@@ -3115,6 +3131,10 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const {
31153131
if (BaseTy->isIncompleteType())
31163132
return false;
31173133

3134+
// Any type that is, or contains, address discriminated data is non-POD.
3135+
if (Context.containsAddressDiscriminatedPointerAuth(*this))
3136+
return false;
3137+
31183138
// As an extension, Clang treats vector types as Scalar types.
31193139
if (BaseTy->isScalarType() || BaseTy->isVectorType())
31203140
return true;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19651,6 +19651,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1965119651
Q && Q.isAddressDiscriminated()) {
1965219652
Record->setArgPassingRestrictions(
1965319653
RecordArgPassingKind::CanNeverPassInRegs);
19654+
Record->setNonTrivialToPrimitiveCopy(true);
1965419655
}
1965519656
}
1965619657

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,10 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
17681768
// Objective-C lifetime, this is a non-trivial assignment.
17691769
if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
17701770
return false;
1771-
1771+
const ASTContext &Context = Self.getASTContext();
1772+
if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1773+
Context.containsAddressDiscriminatedPointerAuth(RhsT))
1774+
return false;
17721775
return !Result.get()->hasNonTrivialCall(Self.Context);
17731776
}
17741777

clang/test/SemaCXX/ptrauth-triviality.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static_assert(__is_trivially_destructible(S3));
7474
static_assert(!__is_trivially_copyable(S3));
7575
static_assert(!__is_trivially_relocatable(S3)); // expected-warning{{deprecated}}
7676
//FIXME
77-
static_assert(__builtin_is_cpp_trivially_relocatable(S3));
77+
static_assert(!__builtin_is_cpp_trivially_relocatable(S3));
7878
static_assert(!__is_trivially_equality_comparable(S3));
7979

8080

@@ -84,7 +84,7 @@ static_assert(!__is_trivially_assignable(Holder<S3>, const Holder<S3>&));
8484
static_assert(__is_trivially_destructible(Holder<S3>));
8585
static_assert(!__is_trivially_copyable(Holder<S3>));
8686
static_assert(!__is_trivially_relocatable(Holder<S3>)); // expected-warning{{deprecated}}
87-
static_assert(__builtin_is_cpp_trivially_relocatable(Holder<S3>));
87+
static_assert(!__builtin_is_cpp_trivially_relocatable(Holder<S3>));
8888
static_assert(!__is_trivially_equality_comparable(Holder<S3>));
8989

9090
struct IA S4 {
@@ -207,7 +207,7 @@ template <class T> struct UnionWrapper trivially_relocatable_if_eligible {
207207
} u;
208208
};
209209

210-
static_assert(test_is_trivially_relocatable_v<AddressDiscriminatedPolymorphicBase>);
210+
static_assert(!test_is_trivially_relocatable_v<AddressDiscriminatedPolymorphicBase>);
211211
static_assert(test_is_trivially_relocatable_v<NoAddressDiscriminatedPolymorphicBase>);
212212
static_assert(inheritance_relocatability_matches_bases_v<AddressDiscriminatedPolymorphicBase, NoAddressDiscriminatedPolymorphicBase>);
213213
static_assert(inheritance_relocatability_matches_bases_v<NoAddressDiscriminatedPolymorphicBase, AddressDiscriminatedPolymorphicBase>);

0 commit comments

Comments
 (0)