Skip to content

Commit d66b537

Browse files
authored
[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
1 parent 77bc236 commit d66b537

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
@@ -642,7 +642,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
642642
/// contain data that is address discriminated. This includes
643643
/// implicitly authenticated values like vtable pointers, as well as
644644
/// explicitly qualified fields.
645-
bool containsAddressDiscriminatedPointerAuth(QualType T) {
645+
bool containsAddressDiscriminatedPointerAuth(QualType T) const {
646646
if (!isPointerAuthenticationAvailable())
647647
return false;
648648
return findPointerAuthContent(T) != PointerAuthContent::None;
@@ -656,8 +656,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
656656
bool containsNonRelocatablePointerAuth(QualType T) {
657657
if (!isPointerAuthenticationAvailable())
658658
return false;
659-
return findPointerAuthContent(T) ==
660-
PointerAuthContent::AddressDiscriminatedData;
659+
return findPointerAuthContent(T) != PointerAuthContent::None;
661660
}
662661

663662
private:
@@ -675,8 +674,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
675674
bool isPointerAuthenticationAvailable() const {
676675
return LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;
677676
}
678-
PointerAuthContent findPointerAuthContent(QualType T);
679-
llvm::DenseMap<const RecordDecl *, PointerAuthContent>
677+
PointerAuthContent findPointerAuthContent(QualType T) const;
678+
mutable llvm::DenseMap<const RecordDecl *, PointerAuthContent>
680679
RecordContainsAddressDiscriminatedPointerAuth;
681680

682681
ImportDecl *FirstLocalImport = nullptr;
@@ -3723,7 +3722,7 @@ OPT_LIST(V)
37233722
/// Resolve the root record to be used to derive the vtable pointer
37243723
/// authentication policy for the specified record.
37253724
const CXXRecordDecl *
3726-
baseForVTableAuthentication(const CXXRecordDecl *ThisClass);
3725+
baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const;
37273726

37283727
bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,
37293728
StringRef MangledName);

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,7 +1708,7 @@ void ASTContext::setRelocationInfoForCXXRecord(
17081708
}
17091709

17101710
static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
1711-
ASTContext &Context, const CXXRecordDecl *Class) {
1711+
const ASTContext &Context, const CXXRecordDecl *Class) {
17121712
if (!Class->isPolymorphic())
17131713
return false;
17141714
const CXXRecordDecl *BaseType = Context.baseForVTableAuthentication(Class);
@@ -1723,7 +1723,8 @@ static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
17231723
return AddressDiscrimination == AuthAttr::AddressDiscrimination;
17241724
}
17251725

1726-
ASTContext::PointerAuthContent ASTContext::findPointerAuthContent(QualType T) {
1726+
ASTContext::PointerAuthContent
1727+
ASTContext::findPointerAuthContent(QualType T) const {
17271728
assert(isPointerAuthenticationAvailable());
17281729

17291730
T = T.getCanonicalType();
@@ -3029,7 +3030,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
30293030
return true;
30303031
}
30313032

3032-
// All other pointers (except __ptrauth pointers) are unique.
3033+
// All other pointers are unique.
30333034
if (Ty->isPointerType())
30343035
return !Ty.hasAddressDiscriminatedPointerAuth();
30353036

@@ -15189,7 +15190,7 @@ StringRef ASTContext::getCUIDHash() const {
1518915190
}
1519015191

1519115192
const CXXRecordDecl *
15192-
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) {
15193+
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const {
1519315194
assert(ThisClass);
1519415195
assert(ThisClass->isPolymorphic());
1519515196
const CXXRecordDecl *PrimaryBase = ThisClass;

clang/lib/AST/DeclCXX.cpp

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

1438+
// If this type contains any address discriminated values we should
1439+
// have already indicated that the only special member functions that
1440+
// can possibly be trivial are the default constructor and destructor.
1441+
if (T.hasAddressDiscriminatedPointerAuth())
1442+
data().HasTrivialSpecialMembers &=
1443+
SMF_DefaultConstructor | SMF_Destructor;
1444+
14381445
// C++14 [meta.unary.prop]p4:
14391446
// T is a class type [...] with [...] no non-static data members other
14401447
// than subobjects of zero size

clang/lib/AST/Type.cpp

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

27742774
QualType CanonicalType = getTypePtr()->CanonicalType;
2775+
2776+
// Any type that is, or contains, address discriminated data is never POD.
2777+
if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
2778+
return false;
2779+
27752780
switch (CanonicalType->getTypeClass()) {
27762781
// Everything not explicitly mentioned is not POD.
27772782
default:
@@ -2830,6 +2835,11 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
28302835
if (CanonicalType->isDependentType())
28312836
return false;
28322837

2838+
// Any type that is, or contains, address discriminated data is never a
2839+
// trivial type.
2840+
if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
2841+
return false;
2842+
28332843
// C++0x [basic.types]p9:
28342844
// Scalar types, trivial class types, arrays of such types, and
28352845
// cv-qualified versions of these types are collectively called trivial
@@ -2925,6 +2935,12 @@ bool QualType::isBitwiseCloneableType(const ASTContext &Context) const {
29252935

29262936
if (CanonicalType->isIncompleteType())
29272937
return false;
2938+
2939+
// Any type that is, or contains, address discriminated data is never
2940+
// bitwise clonable.
2941+
if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
2942+
return false;
2943+
29282944
const auto *RD = CanonicalType->getAsRecordDecl(); // struct/union/class
29292945
if (!RD)
29302946
return true;
@@ -3170,6 +3186,10 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const {
31703186
if (BaseTy->isIncompleteType())
31713187
return false;
31723188

3189+
// Any type that is, or contains, address discriminated data is non-POD.
3190+
if (Context.containsAddressDiscriminatedPointerAuth(*this))
3191+
return false;
3192+
31733193
// As an extension, Clang treats vector types as Scalar types.
31743194
if (BaseTy->isScalarType() || BaseTy->isVectorType())
31753195
return true;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19751,6 +19751,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1975119751
Q && Q.isAddressDiscriminated()) {
1975219752
Record->setArgPassingRestrictions(
1975319753
RecordArgPassingKind::CanNeverPassInRegs);
19754+
Record->setNonTrivialToPrimitiveCopy(true);
1975419755
}
1975519756
}
1975619757

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1764,7 +1764,10 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
17641764
// Objective-C lifetime, this is a non-trivial assignment.
17651765
if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
17661766
return false;
1767-
1767+
const ASTContext &Context = Self.getASTContext();
1768+
if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1769+
Context.containsAddressDiscriminatedPointerAuth(RhsT))
1770+
return false;
17681771
return !Result.get()->hasNonTrivialCall(Self.Context);
17691772
}
17701773

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)