Skip to content

Commit a41b546

Browse files
author
z1_cciauto
authored
merge main into amd-staging (llvm#3756)
2 parents 67a92a4 + e00b863 commit a41b546

File tree

147 files changed

+5188
-3048
lines changed

Some content is hidden

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

147 files changed

+5188
-3048
lines changed

.ci/compute_projects.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ def get_env_variables(modified_files: list[str], platform: str) -> Set[str]:
333333
current_platform = platform.system()
334334
if len(sys.argv) == 2:
335335
current_platform = sys.argv[1]
336-
env_variables = get_env_variables(sys.stdin.readlines(), current_platform)
336+
changed_files = [line.strip() for line in sys.stdin.readlines()]
337+
env_variables = get_env_variables(changed_files, current_platform)
337338
for env_variable in env_variables:
338339
print(f"{env_variable}='{env_variables[env_variable]}'")

.github/workflows/premerge.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
# several test suites in a row and discard statistics that we want
6666
# to save in the end.
6767
export SCCACHE_IDLE_TIMEOUT=0
68-
SCCACHE_LOG=info SCCACHE_ERROR_LOG=artifacts/sccache.log sccache --start-server
68+
sccache --start-server
6969
7070
./.ci/monolithic-linux.sh "${projects_to_build}" "${project_check_targets}" "${runtimes_to_build}" "${runtimes_check_targets}" "${runtimes_check_targets_needs_reconfig}" "${enable_cir}"
7171
- name: Upload Artifacts
@@ -117,7 +117,7 @@ jobs:
117117
call C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat -arch=amd64 -host_arch=amd64
118118
# See the comments above in the Linux job for why we define each of
119119
# these environment variables.
120-
bash -c "export SCCACHE_GCS_BUCKET=$CACHE_GCS_BUCKET; export SCCACHE_GCS_RW_MODE=READ_WRITE; export SCCACHE_IDLE_TIMEOUT=0; SCCACHE_LOG=info SCCACHE_ERROR_LOG=artifacts/sccache.log sccache --start-server; .ci/monolithic-windows.sh \"${{ steps.vars.outputs.windows-projects }}\" \"${{ steps.vars.outputs.windows-check-targets }}\""
120+
bash -c "export SCCACHE_GCS_BUCKET=$CACHE_GCS_BUCKET; export SCCACHE_GCS_RW_MODE=READ_WRITE; export SCCACHE_IDLE_TIMEOUT=0; sccache --start-server; .ci/monolithic-windows.sh \"${{ steps.vars.outputs.windows-projects }}\" \"${{ steps.vars.outputs.windows-check-targets }}\""
121121
- name: Upload Artifacts
122122
# In some cases, Github will fail to upload the artifact. We want to
123123
# continue anyways as a failed artifact upload is an infra failure, not

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/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ module Clang_Basic {
3737
umbrella "clang/Basic"
3838

3939
textual header "clang/Basic/AArch64ACLETypes.def"
40+
textual header "clang/Basic/ABIVersions.def"
4041
textual header "clang/Basic/AMDGPUTypes.def"
4142
textual header "clang/Basic/BuiltinHeaders.def"
4243
textual header "clang/Basic/BuiltinsAArch64.def"

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,7 +1713,7 @@ void ASTContext::setRelocationInfoForCXXRecord(
17131713
}
17141714

17151715
static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
1716-
ASTContext &Context, const CXXRecordDecl *Class) {
1716+
const ASTContext &Context, const CXXRecordDecl *Class) {
17171717
if (!Class->isPolymorphic())
17181718
return false;
17191719
const CXXRecordDecl *BaseType = Context.baseForVTableAuthentication(Class);
@@ -1728,7 +1728,8 @@ static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication(
17281728
return AddressDiscrimination == AuthAttr::AddressDiscrimination;
17291729
}
17301730

1731-
ASTContext::PointerAuthContent ASTContext::findPointerAuthContent(QualType T) {
1731+
ASTContext::PointerAuthContent
1732+
ASTContext::findPointerAuthContent(QualType T) const {
17321733
assert(isPointerAuthenticationAvailable());
17331734

17341735
T = T.getCanonicalType();
@@ -3034,7 +3035,7 @@ bool ASTContext::hasUniqueObjectRepresentations(
30343035
return true;
30353036
}
30363037

3037-
// All other pointers (except __ptrauth pointers) are unique.
3038+
// All other pointers are unique.
30383039
if (Ty->isPointerType())
30393040
return !Ty.hasAddressDiscriminatedPointerAuth();
30403041

@@ -15198,7 +15199,7 @@ StringRef ASTContext::getCUIDHash() const {
1519815199
}
1519915200

1520015201
const CXXRecordDecl *
15201-
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) {
15202+
ASTContext::baseForVTableAuthentication(const CXXRecordDecl *ThisClass) const {
1520215203
assert(ThisClass);
1520315204
assert(ThisClass->isPolymorphic());
1520415205
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/CIR/CodeGen/CIRGenClass.cpp

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "CIRGenFunction.h"
1515
#include "CIRGenValue.h"
1616

17+
#include "clang/AST/EvaluatedExprVisitor.h"
1718
#include "clang/AST/ExprCXX.h"
1819
#include "clang/AST/RecordLayout.h"
1920
#include "clang/AST/Type.h"
@@ -124,6 +125,32 @@ static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit) {
124125
return baseClassDecl->isDynamicClass();
125126
}
126127

128+
namespace {
129+
/// A visitor which checks whether an initializer uses 'this' in a
130+
/// way which requires the vtable to be properly set.
131+
struct DynamicThisUseChecker
132+
: ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
133+
using super = ConstEvaluatedExprVisitor<DynamicThisUseChecker>;
134+
135+
bool usesThis = false;
136+
137+
DynamicThisUseChecker(const ASTContext &c) : super(c) {}
138+
139+
// Black-list all explicit and implicit references to 'this'.
140+
//
141+
// Do we need to worry about external references to 'this' derived
142+
// from arbitrary code? If so, then anything which runs arbitrary
143+
// external code might potentially access the vtable.
144+
void VisitCXXThisExpr(const CXXThisExpr *e) { usesThis = true; }
145+
};
146+
} // end anonymous namespace
147+
148+
static bool baseInitializerUsesThis(ASTContext &c, const Expr *init) {
149+
DynamicThisUseChecker checker(c);
150+
checker.Visit(init);
151+
return checker.usesThis;
152+
}
153+
127154
/// Gets the address of a direct base class within a complete object.
128155
/// This should only be used for (1) non-virtual bases or (2) virtual bases
129156
/// when the type is known to be complete (e.g. in complete destructors).
@@ -166,10 +193,8 @@ void CIRGenFunction::emitBaseInitializer(mlir::Location loc,
166193
// If the initializer for the base (other than the constructor
167194
// itself) accesses 'this' in any way, we need to initialize the
168195
// vtables.
169-
if (classDecl->isDynamicClass()) {
170-
cgm.errorNYI(loc, "emitBaseInitializer: dynamic class");
171-
return;
172-
}
196+
if (baseInitializerUsesThis(getContext(), baseInit->getInit()))
197+
initializeVTablePointers(loc, classDecl);
173198

174199
// We can pretend to be a complete class because it only matters for
175200
// virtual bases, and we only do virtual bases for complete ctors.
@@ -260,6 +285,34 @@ void CIRGenFunction::emitCtorPrologue(const CXXConstructorDecl *cd,
260285
}
261286
}
262287

288+
static Address applyNonVirtualAndVirtualOffset(
289+
mlir::Location loc, CIRGenFunction &cgf, Address addr,
290+
CharUnits nonVirtualOffset, mlir::Value virtualOffset,
291+
const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase,
292+
mlir::Type baseValueTy = {}, bool assumeNotNull = true) {
293+
// Assert that we have something to do.
294+
assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);
295+
296+
// Compute the offset from the static and dynamic components.
297+
if (!nonVirtualOffset.isZero()) {
298+
if (virtualOffset) {
299+
cgf.cgm.errorNYI(
300+
loc,
301+
"applyNonVirtualAndVirtualOffset: virtual and non-virtual offset");
302+
return Address::invalid();
303+
} else {
304+
assert(baseValueTy && "expected base type");
305+
// If no virtualOffset is present this is the final stop.
306+
return cgf.getBuilder().createBaseClassAddr(
307+
loc, addr, baseValueTy, nonVirtualOffset.getQuantity(),
308+
assumeNotNull);
309+
}
310+
}
311+
312+
cgf.cgm.errorNYI(loc, "applyNonVirtualAndVirtualOffset: virtual offset");
313+
return Address::invalid();
314+
}
315+
263316
void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
264317
const VPtr &vptr) {
265318
// Compute the address point.
@@ -287,8 +340,9 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
287340
// Apply the offsets.
288341
Address classAddr = loadCXXThisAddress();
289342
if (!nonVirtualOffset.isZero() || virtualOffset) {
290-
cgm.errorNYI(loc,
291-
"initializeVTablePointer: non-virtual and virtual offset");
343+
classAddr = applyNonVirtualAndVirtualOffset(
344+
loc, *this, classAddr, nonVirtualOffset, virtualOffset,
345+
vptr.vtableClass, vptr.nearestVBase, baseValueTy);
292346
}
293347

294348
// Finally, store the address point. Use the same CIR types as the field.
@@ -322,10 +376,11 @@ void CIRGenFunction::initializeVTablePointers(mlir::Location loc,
322376
CIRGenFunction::VPtrsVector
323377
CIRGenFunction::getVTablePointers(const CXXRecordDecl *vtableClass) {
324378
CIRGenFunction::VPtrsVector vptrsResult;
379+
VisitedVirtualBasesSetTy vbases;
325380
getVTablePointers(BaseSubobject(vtableClass, CharUnits::Zero()),
326381
/*NearestVBase=*/nullptr,
327382
/*OffsetFromNearestVBase=*/CharUnits::Zero(),
328-
/*BaseIsNonVirtualPrimaryBase=*/false, vtableClass,
383+
/*BaseIsNonVirtualPrimaryBase=*/false, vtableClass, vbases,
329384
vptrsResult);
330385
return vptrsResult;
331386
}
@@ -335,6 +390,7 @@ void CIRGenFunction::getVTablePointers(BaseSubobject base,
335390
CharUnits offsetFromNearestVBase,
336391
bool baseIsNonVirtualPrimaryBase,
337392
const CXXRecordDecl *vtableClass,
393+
VisitedVirtualBasesSetTy &vbases,
338394
VPtrsVector &vptrs) {
339395
// If this base is a non-virtual primary base the address point has already
340396
// been set.
@@ -346,8 +402,39 @@ void CIRGenFunction::getVTablePointers(BaseSubobject base,
346402

347403
const CXXRecordDecl *rd = base.getBase();
348404

349-
if (rd->getNumBases())
350-
cgm.errorNYI(rd->getSourceRange(), "getVTablePointers: traverse bases");
405+
for (const auto &nextBase : rd->bases()) {
406+
const auto *baseDecl =
407+
cast<CXXRecordDecl>(
408+
nextBase.getType()->castAs<RecordType>()->getOriginalDecl())
409+
->getDefinitionOrSelf();
410+
411+
// Ignore classes without a vtable.
412+
if (!baseDecl->isDynamicClass())
413+
continue;
414+
415+
CharUnits baseOffset;
416+
CharUnits baseOffsetFromNearestVBase;
417+
bool baseDeclIsNonVirtualPrimaryBase;
418+
const CXXRecordDecl *nextBaseDecl;
419+
420+
if (nextBase.isVirtual()) {
421+
cgm.errorNYI(rd->getSourceRange(), "getVTablePointers: virtual base");
422+
return;
423+
} else {
424+
const ASTRecordLayout &layout = getContext().getASTRecordLayout(rd);
425+
426+
nextBaseDecl = baseDecl;
427+
baseOffset = base.getBaseOffset() + layout.getBaseClassOffset(baseDecl);
428+
baseOffsetFromNearestVBase =
429+
offsetFromNearestVBase + layout.getBaseClassOffset(baseDecl);
430+
baseDeclIsNonVirtualPrimaryBase = layout.getPrimaryBase() == baseDecl;
431+
}
432+
433+
getVTablePointers(BaseSubobject(baseDecl, baseOffset), nextBaseDecl,
434+
baseOffsetFromNearestVBase,
435+
baseDeclIsNonVirtualPrimaryBase, vtableClass, vbases,
436+
vptrs);
437+
}
351438
}
352439

353440
Address CIRGenFunction::loadCXXThisAddress() {

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,14 +574,17 @@ class CIRGenFunction : public CIRGenTypeCache {
574574
const clang::CXXRecordDecl *vtableClass;
575575
};
576576

577+
using VisitedVirtualBasesSetTy =
578+
llvm::SmallPtrSet<const clang::CXXRecordDecl *, 4>;
579+
577580
using VPtrsVector = llvm::SmallVector<VPtr, 4>;
578581
VPtrsVector getVTablePointers(const clang::CXXRecordDecl *vtableClass);
579582
void getVTablePointers(clang::BaseSubobject base,
580583
const clang::CXXRecordDecl *nearestVBase,
581584
clang::CharUnits offsetFromNearestVBase,
582585
bool baseIsNonVirtualPrimaryBase,
583586
const clang::CXXRecordDecl *vtableClass,
584-
VPtrsVector &vptrs);
587+
VisitedVirtualBasesSetTy &vbases, VPtrsVector &vptrs);
585588
/// Return the Value of the vtable pointer member pointed to by thisAddr.
586589
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr,
587590
const clang::CXXRecordDecl *vtableClass);

clang/lib/Sema/SemaDecl.cpp

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

0 commit comments

Comments
 (0)