Skip to content

Commit 47cf464

Browse files
author
z1_cciauto
authored
merge main into amd-staging (llvm#2647)
2 parents fde89de + 42e336f commit 47cf464

File tree

81 files changed

+1841
-889
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1841
-889
lines changed

bolt/lib/Utils/CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,25 @@ set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc")
66

77
set(generate_vcs_version_script "${LLVM_CMAKE_DIR}/GenerateVersionFromVCS.cmake")
88

9+
if(llvm_vc AND LLVM_APPEND_VC_REV)
10+
set(llvm_source_dir ${LLVM_MAIN_SRC_DIR})
11+
endif()
12+
if(LLVM_VC_REPOSITORY AND LLVM_VC_REVISION)
13+
set(llvm_source_dir ${LLVM_SOURCE_DIR})
14+
set(llvm_vc_repository ${LLVM_VC_REPOSITORY})
15+
set(llvm_vc_revision ${LLVM_VC_REVISION})
16+
endif()
17+
if(bolt_vc AND LLVM_APPEND_VC_REV)
18+
set(bolt_source_dir ${BOLT_SOURCE_DIR})
19+
endif()
20+
921
# Create custom target to generate the VC revision include.
1022
add_custom_command(OUTPUT "${version_inc}"
1123
DEPENDS "${llvm_vc}" "${bolt_vc}" "${generate_vcs_version_script}"
1224
COMMAND ${CMAKE_COMMAND} "-DNAMES=BOLT"
25+
"-DLLVM_SOURCE_DIR=${llvm_source_dir}"
26+
"-DBOLT_SOURCE_DIR=${bolt_source_dir}"
1327
"-DHEADER_FILE=${version_inc}"
14-
"-DBOLT_SOURCE_DIR=${BOLT_SOURCE_DIR}"
1528
"-DLLVM_VC_REPOSITORY=${llvm_vc_repository}"
1629
"-DLLVM_VC_REVISION=${llvm_vc_revision}"
1730
"-DLLVM_FORCE_VC_REVISION=${LLVM_FORCE_VC_REVISION}"

clang/include/clang/AST/ASTContext.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,10 +629,48 @@ class ASTContext : public RefCountedBase<ASTContext> {
629629
void setRelocationInfoForCXXRecord(const CXXRecordDecl *,
630630
CXXRecordDeclRelocationInfo);
631631

632+
/// Examines a given type, and returns whether the type itself
633+
/// is address discriminated, or any transitively embedded types
634+
/// contain data that is address discriminated. This includes
635+
/// implicitly authenticated values like vtable pointers, as well as
636+
/// explicitly qualified fields.
637+
bool containsAddressDiscriminatedPointerAuth(QualType T) {
638+
if (!isPointerAuthenticationAvailable())
639+
return false;
640+
return findPointerAuthContent(T) != PointerAuthContent::None;
641+
}
642+
643+
/// Examines a given type, and returns whether the type itself
644+
/// or any data it transitively contains has a pointer authentication
645+
/// schema that is not safely relocatable. e.g. any data or fields
646+
/// with address discrimination other than any otherwise similar
647+
/// vtable pointers.
648+
bool containsNonRelocatablePointerAuth(QualType T) {
649+
if (!isPointerAuthenticationAvailable())
650+
return false;
651+
return findPointerAuthContent(T) ==
652+
PointerAuthContent::AddressDiscriminatedData;
653+
}
654+
632655
private:
633656
llvm::DenseMap<const CXXRecordDecl *, CXXRecordDeclRelocationInfo>
634657
RelocatableClasses;
635658

659+
// FIXME: store in RecordDeclBitfields in future?
660+
enum class PointerAuthContent : uint8_t {
661+
None,
662+
AddressDiscriminatedVTable,
663+
AddressDiscriminatedData
664+
};
665+
666+
// A simple helper function to short circuit pointer auth checks.
667+
bool isPointerAuthenticationAvailable() const {
668+
return LangOpts.PointerAuthCalls || LangOpts.PointerAuthIntrinsics;
669+
}
670+
PointerAuthContent findPointerAuthContent(QualType T);
671+
llvm::DenseMap<const RecordDecl *, PointerAuthContent>
672+
RecordContainsAddressDiscriminatedPointerAuth;
673+
636674
ImportDecl *FirstLocalImport = nullptr;
637675
ImportDecl *LastLocalImport = nullptr;
638676

@@ -3668,6 +3706,7 @@ OPT_LIST(V)
36683706
/// authentication policy for the specified record.
36693707
const CXXRecordDecl *
36703708
baseForVTableAuthentication(const CXXRecordDecl *ThisClass);
3709+
36713710
bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,
36723711
StringRef MangledName);
36733712

clang/lib/AST/ASTContext.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,73 @@ void ASTContext::setRelocationInfoForCXXRecord(
17051705
RelocatableClasses.insert({D, Info});
17061706
}
17071707

1708+
static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
1709+
ASTContext &Context, const CXXRecordDecl *Class) {
1710+
if (!Class->isPolymorphic())
1711+
return false;
1712+
const CXXRecordDecl *BaseType = Context.baseForVTableAuthentication(Class);
1713+
using AuthAttr = VTablePointerAuthenticationAttr;
1714+
const AuthAttr *ExplicitAuth = BaseType->getAttr<AuthAttr>();
1715+
if (!ExplicitAuth)
1716+
return Context.getLangOpts().PointerAuthVTPtrAddressDiscrimination;
1717+
AuthAttr::AddressDiscriminationMode AddressDiscrimination =
1718+
ExplicitAuth->getAddressDiscrimination();
1719+
if (AddressDiscrimination == AuthAttr::DefaultAddressDiscrimination)
1720+
return Context.getLangOpts().PointerAuthVTPtrAddressDiscrimination;
1721+
return AddressDiscrimination == AuthAttr::AddressDiscrimination;
1722+
}
1723+
1724+
ASTContext::PointerAuthContent ASTContext::findPointerAuthContent(QualType T) {
1725+
assert(isPointerAuthenticationAvailable());
1726+
1727+
T = T.getCanonicalType();
1728+
if (T.hasAddressDiscriminatedPointerAuth())
1729+
return PointerAuthContent::AddressDiscriminatedData;
1730+
const RecordDecl *RD = T->getAsRecordDecl();
1731+
if (!RD)
1732+
return PointerAuthContent::None;
1733+
1734+
if (auto Existing = RecordContainsAddressDiscriminatedPointerAuth.find(RD);
1735+
Existing != RecordContainsAddressDiscriminatedPointerAuth.end())
1736+
return Existing->second;
1737+
1738+
PointerAuthContent Result = PointerAuthContent::None;
1739+
1740+
auto SaveResultAndReturn = [&]() -> PointerAuthContent {
1741+
auto [ResultIter, DidAdd] =
1742+
RecordContainsAddressDiscriminatedPointerAuth.try_emplace(RD, Result);
1743+
(void)ResultIter;
1744+
(void)DidAdd;
1745+
assert(DidAdd);
1746+
return Result;
1747+
};
1748+
auto ShouldContinueAfterUpdate = [&](PointerAuthContent NewResult) {
1749+
static_assert(PointerAuthContent::None <
1750+
PointerAuthContent::AddressDiscriminatedVTable);
1751+
static_assert(PointerAuthContent::AddressDiscriminatedVTable <
1752+
PointerAuthContent::AddressDiscriminatedData);
1753+
if (NewResult > Result)
1754+
Result = NewResult;
1755+
return Result != PointerAuthContent::AddressDiscriminatedData;
1756+
};
1757+
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1758+
if (primaryBaseHaseAddressDiscriminatedVTableAuthentication(*this, CXXRD) &&
1759+
!ShouldContinueAfterUpdate(
1760+
PointerAuthContent::AddressDiscriminatedVTable))
1761+
return SaveResultAndReturn();
1762+
for (auto Base : CXXRD->bases()) {
1763+
if (!ShouldContinueAfterUpdate(findPointerAuthContent(Base.getType())))
1764+
return SaveResultAndReturn();
1765+
}
1766+
}
1767+
for (auto *FieldDecl : RD->fields()) {
1768+
if (!ShouldContinueAfterUpdate(
1769+
findPointerAuthContent(FieldDecl->getType())))
1770+
return SaveResultAndReturn();
1771+
}
1772+
return SaveResultAndReturn();
1773+
}
1774+
17081775
void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
17091776
assert(!Import->getNextLocalImport() &&
17101777
"Import declaration already in the chain");

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,6 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
14231423
// Walk up the call stack to find the appropriate caller and get the
14241424
// element type from it.
14251425
auto [NewCall, ElemType] = S.getStdAllocatorCaller("allocate");
1426-
APSInt Bytes = popToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(0)));
14271426

14281427
if (ElemType.isNull()) {
14291428
S.FFDiag(Call, S.getLangOpts().CPlusPlus20
@@ -1439,6 +1438,25 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
14391438
return false;
14401439
}
14411440

1441+
// We only care about the first parameter (the size), so discard all the
1442+
// others.
1443+
{
1444+
unsigned NumArgs = Call->getNumArgs();
1445+
assert(NumArgs >= 1);
1446+
1447+
// The std::nothrow_t arg never gets put on the stack.
1448+
if (Call->getArg(NumArgs - 1)->getType()->isNothrowT())
1449+
--NumArgs;
1450+
auto Args = llvm::ArrayRef(Call->getArgs(), Call->getNumArgs());
1451+
// First arg is needed.
1452+
Args = Args.drop_front();
1453+
1454+
// Discard the rest.
1455+
for (const Expr *Arg : Args)
1456+
discard(S.Stk, *S.getContext().classify(Arg));
1457+
}
1458+
1459+
APSInt Bytes = popToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(0)));
14421460
CharUnits ElemSize = S.getASTContext().getTypeSizeInChars(ElemType);
14431461
assert(!ElemSize.isZero());
14441462
// Divide the number of bytes by sizeof(ElemType), so we get the number of

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4603,6 +4603,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
46034603
Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
46044604
else if (Major <= 19)
46054605
Opts.setClangABICompat(LangOptions::ClangABI::Ver19);
4606+
else if (Major <= 20)
4607+
Opts.setClangABICompat(LangOptions::ClangABI::Ver20);
46064608
} else if (Ver != "latest") {
46074609
Diags.Report(diag::err_drv_invalid_value)
46084610
<< A->getAsString(Args) << A->getValue();

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ static bool IsEligibleForTrivialRelocation(Sema &SemaRef,
188188
return false;
189189
}
190190

191+
bool IsUnion = D->isUnion();
191192
for (const FieldDecl *Field : D->fields()) {
192193
if (Field->getType()->isDependentType())
193194
continue;
@@ -197,6 +198,12 @@ static bool IsEligibleForTrivialRelocation(Sema &SemaRef,
197198
// of a trivially relocatable type
198199
if (!SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
199200
return false;
201+
202+
// A union contains values with address discriminated pointer auth
203+
// cannot be relocated.
204+
if (IsUnion && SemaRef.Context.containsAddressDiscriminatedPointerAuth(
205+
Field->getType()))
206+
return false;
200207
}
201208
return !D->hasDeletedDestructor();
202209
}
@@ -313,7 +320,6 @@ bool Sema::IsCXXTriviallyRelocatableType(const CXXRecordDecl &RD) {
313320
}
314321

315322
bool Sema::IsCXXTriviallyRelocatableType(QualType Type) {
316-
317323
QualType BaseElementType = getASTContext().getBaseElementType(Type);
318324

319325
if (Type->isVariableArrayType())
@@ -322,10 +328,10 @@ bool Sema::IsCXXTriviallyRelocatableType(QualType Type) {
322328
if (BaseElementType.hasNonTrivialObjCLifetime())
323329
return false;
324330

325-
if (BaseElementType.hasAddressDiscriminatedPointerAuth())
331+
if (BaseElementType->isIncompleteType())
326332
return false;
327333

328-
if (BaseElementType->isIncompleteType())
334+
if (Context.containsNonRelocatablePointerAuth(Type))
329335
return false;
330336

331337
if (BaseElementType->isScalarType() || BaseElementType->isVectorType())
@@ -670,7 +676,10 @@ static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
670676
if (!BaseElementType->isObjectType())
671677
return false;
672678

673-
if (T.hasAddressDiscriminatedPointerAuth())
679+
// The deprecated __builtin_is_trivially_relocatable does not have
680+
// an equivalent to __builtin_trivially_relocate, so there is no
681+
// safe way to use it if there are any address discriminated values.
682+
if (SemaRef.getASTContext().containsAddressDiscriminatedPointerAuth(T))
674683
return false;
675684

676685
if (const auto *RD = BaseElementType->getAsCXXRecordDecl();

clang/test/AST/ByteCode/new-delete.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2-
// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s
3-
// RUN: %clang_cc1 -triple=i686-linux-gnu -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s
4-
// RUN: %clang_cc1 -verify=ref,both %s
5-
// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
6-
// RUN: %clang_cc1 -triple=i686-linux-gnu -std=c++20 -verify=ref,both %s
1+
// RUN: %clang_cc1 -verify=expected,both -fexperimental-new-constant-interpreter %s
2+
// RUN: %clang_cc1 -std=c++20 -verify=expected,both -fexperimental-new-constant-interpreter %s
3+
// RUN: %clang_cc1 -std=c++20 -verify=expected,both -triple=i686-linux-gnu -fexperimental-new-constant-interpreter %s
4+
// RUN: %clang_cc1 -verify=ref,both %s
5+
// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
6+
// RUN: %clang_cc1 -std=c++20 -verify=ref,both -triple=i686-linux-gnu %s
77

88
#if __cplusplus >= 202002L
99

@@ -1012,6 +1012,16 @@ constexpr int no_deallocate_nonalloc = (std::allocator<int>().deallocate((int*)&
10121012
// both-note {{in call}} \
10131013
// both-note {{declared here}}
10141014

1015+
namespace OpNewNothrow {
1016+
constexpr int f() {
1017+
int *v = (int*)operator new(sizeof(int), std::align_val_t(2), std::nothrow); // both-note {{cannot allocate untyped memory in a constant expression; use 'std::allocator<T>::allocate' to allocate memory of type 'T'}}
1018+
operator delete(v, std::align_val_t(2), std::nothrow);
1019+
return 1;
1020+
}
1021+
static_assert(f()); // both-error {{not an integral constant expression}} \
1022+
// both-note {{in call to}}
1023+
}
1024+
10151025
#else
10161026
/// Make sure we reject this prior to C++20
10171027
constexpr int a() { // both-error {{never produces a constant expression}}

clang/test/CodeGen/X86/avx-cxx-record.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -O2 -target-cpu x86-64-v3 -o - | FileCheck %s
2+
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -O2 -target-cpu x86-64-v3 -fclang-abi-compat=20 -o - | FileCheck --check-prefix CLANG-20 %s
23

34
using UInt64x2 = unsigned long long __attribute__((__vector_size__(16), may_alias));
45

@@ -11,6 +12,7 @@ struct XMM2 : XMM1<0>, XMM1<1> {
1112
};
1213

1314
// CHECK: define{{.*}} @_Z3foov({{.*}} [[ARG:%.*]]){{.*}}
15+
// CLANG-20: define{{.*}} <4 x double> @_Z3foov()
1416
// CHECK: entry:
1517
// CHECK-NEXT: store {{.*}}, ptr [[ARG]]{{.*}}
1618
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr {{.*}}, ptr [[ARG]]{{.*}}

clang/test/SemaCXX/cxx2c-trivially-relocatable.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 -std=c++2c -verify %s
2+
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-intrinsics -fptrauth-calls -std=c++2c -verify %s
23

34
class Trivial {};
45
static_assert(__builtin_is_cpp_trivially_relocatable(Trivial));

clang/test/SemaCXX/ptrauth-triviality.cpp

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++20 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
2-
// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++20 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
1+
// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++26 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
2+
// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++26 -fptrauth-calls -fptrauth-intrinsics -verify -fsyntax-only %s
33

44
#define AQ __ptrauth(1,1,50)
55
#define IQ __ptrauth(1,0,50)
@@ -83,7 +83,7 @@ static_assert(!__is_trivially_constructible(Holder<S3>, const Holder<S3>&));
8383
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>));
86-
static_assert(__is_trivially_relocatable(Holder<S3>)); // expected-warning{{deprecated}}
86+
static_assert(!__is_trivially_relocatable(Holder<S3>)); // expected-warning{{deprecated}}
8787
static_assert(__builtin_is_cpp_trivially_relocatable(Holder<S3>));
8888
static_assert(!__is_trivially_equality_comparable(Holder<S3>));
8989

@@ -99,7 +99,6 @@ static_assert(!__is_trivially_assignable(S4, const S4&));
9999
static_assert(__is_trivially_destructible(S4));
100100
static_assert(!__is_trivially_copyable(S4));
101101
static_assert(!__is_trivially_relocatable(S4)); // expected-warning{{deprecated}}
102-
//FIXME
103102
static_assert(__builtin_is_cpp_trivially_relocatable(S4));
104103
static_assert(!__is_trivially_equality_comparable(S4));
105104

@@ -124,7 +123,6 @@ static_assert(!__is_trivially_assignable(S5, const S5&));
124123
static_assert(__is_trivially_destructible(S5));
125124
static_assert(!__is_trivially_copyable(S5));
126125
static_assert(!__is_trivially_relocatable(S5)); // expected-warning{{deprecated}}
127-
//FIXME
128126
static_assert(__builtin_is_cpp_trivially_relocatable(S5));
129127
static_assert(!__is_trivially_equality_comparable(S5));
130128

@@ -182,3 +180,39 @@ static_assert(__is_trivially_copyable(Holder<S7>));
182180
static_assert(__is_trivially_relocatable(Holder<S7>)); // expected-warning{{deprecated}}
183181
static_assert(__builtin_is_cpp_trivially_relocatable(Holder<S7>));
184182
static_assert(__is_trivially_equality_comparable(Holder<S7>));
183+
184+
template <class... Bases> struct MultipleInheriter : Bases... {
185+
};
186+
187+
template <class T> static const bool test_is_trivially_relocatable_v = __builtin_is_cpp_trivially_relocatable(T);
188+
template <class... Types> static const bool multiple_inheritance_is_relocatable = test_is_trivially_relocatable_v<MultipleInheriter<Types...>>;
189+
template <class... Types> static const bool inheritance_relocatability_matches_bases_v =
190+
(test_is_trivially_relocatable_v<Types> && ...) == multiple_inheritance_is_relocatable<Types...>;
191+
192+
static_assert(multiple_inheritance_is_relocatable<S4, S5> == multiple_inheritance_is_relocatable<S5, S4>);
193+
static_assert(inheritance_relocatability_matches_bases_v<S4, S5>);
194+
static_assert(inheritance_relocatability_matches_bases_v<S5, S4>);
195+
196+
struct AA AddressDiscriminatedPolymorphicBase trivially_relocatable_if_eligible {
197+
virtual void foo();
198+
};
199+
200+
struct IA NoAddressDiscriminatedPolymorphicBase trivially_relocatable_if_eligible {
201+
virtual void bar();
202+
};
203+
204+
template <class T> struct UnionWrapper trivially_relocatable_if_eligible {
205+
union U {
206+
T field1;
207+
} u;
208+
};
209+
210+
static_assert(test_is_trivially_relocatable_v<AddressDiscriminatedPolymorphicBase>);
211+
static_assert(test_is_trivially_relocatable_v<NoAddressDiscriminatedPolymorphicBase>);
212+
static_assert(inheritance_relocatability_matches_bases_v<AddressDiscriminatedPolymorphicBase, NoAddressDiscriminatedPolymorphicBase>);
213+
static_assert(inheritance_relocatability_matches_bases_v<NoAddressDiscriminatedPolymorphicBase, AddressDiscriminatedPolymorphicBase>);
214+
215+
static_assert(!test_is_trivially_relocatable_v<UnionWrapper<AddressDiscriminatedPolymorphicBase>>);
216+
static_assert(test_is_trivially_relocatable_v<UnionWrapper<NoAddressDiscriminatedPolymorphicBase>>);
217+
static_assert(!test_is_trivially_relocatable_v<UnionWrapper<MultipleInheriter<NoAddressDiscriminatedPolymorphicBase, AddressDiscriminatedPolymorphicBase>>>);
218+
static_assert(!test_is_trivially_relocatable_v<UnionWrapper<MultipleInheriter<AddressDiscriminatedPolymorphicBase, NoAddressDiscriminatedPolymorphicBase>>>);

0 commit comments

Comments
 (0)