Skip to content

Commit 689d70c

Browse files
committed
[clang][PAC] Fix builtins that claim Address discriminated types are copyable
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 b69fd34 commit 689d70c

File tree

9 files changed

+445
-16
lines changed

9 files changed

+445
-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();
@@ -3040,7 +3041,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
30403041
return true;
30413042
}
30423043

3043-
// All other pointers (except __ptrauth pointers) are unique.
3044+
// All other pointers are unique.
30443045
if (Ty->isPointerType())
30453046
return !Ty.hasAddressDiscriminatedPointerAuth();
30463047

@@ -15203,7 +15204,7 @@ StringRef ASTContext::getCUIDHash() const {
1520315204
}
1520415205

1520515206
const CXXRecordDecl *
15206-
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) {
15207+
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const {
1520715208
assert(ThisClass);
1520815209
assert(ThisClass->isPolymorphic());
1520915210
const CXXRecordDecl *PrimaryBase = ThisClass;

clang/lib/AST/DeclCXX.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
14381438
data().StructuralIfLiteral = false;
14391439
}
14401440

1441+
if (!data().HasTrivialSpecialMembers &&
1442+
T.hasAddressDiscriminatedPointerAuth())
1443+
data().HasTrivialSpecialMembers = true;
1444+
14411445
// C++14 [meta.unary.prop]p4:
14421446
// T is a class type [...] with [...] no non-static data members other
14431447
// than subobjects of zero size

clang/lib/AST/Type.cpp

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

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

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

29312941
if (CanonicalType->isIncompleteType())
29322942
return false;
2943+
2944+
// Any type that is, or contains, address discriminated data is never
2945+
// bitwise clonable.
2946+
if (Context.containsAddressDiscriminatedPointerAuth(CanonicalType))
2947+
return false;
2948+
29332949
const auto *RD = CanonicalType->getAsRecordDecl(); // struct/union/class
29342950
if (!RD)
29352951
return true;
@@ -3179,6 +3195,10 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const {
31793195
if (BaseTy->isIncompleteType())
31803196
return false;
31813197

3198+
// Any type that is, or contains, address discriminated data is non-POD
3199+
if (Context.containsAddressDiscriminatedPointerAuth(*this))
3200+
return false;
3201+
31823202
// As an extension, Clang treats vector types as Scalar types.
31833203
if (BaseTy->isScalarType() || BaseTy->isVectorType())
31843204
return true;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19779,6 +19779,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1977919779
Q && Q.isAddressDiscriminated()) {
1978019780
Record->setArgPassingRestrictions(
1978119781
RecordArgPassingKind::CanNeverPassInRegs);
19782+
Record->setNonTrivialToPrimitiveCopy(true);
1978219783
}
1978319784
}
1978419785

clang/lib/Sema/SemaTypeTraits.cpp

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

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)