Skip to content

Commit a87dee3

Browse files
author
z1.cciauto
committed
merge main into amd-staging
2 parents 51a3114 + d7c7c46 commit a87dee3

File tree

241 files changed

+4958
-2216
lines changed

Some content is hidden

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

241 files changed

+4958
-2216
lines changed

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,7 @@ std::error_code DataAggregator::parseAggregatedLBREntry() {
12201220
// Storage for parsed fields.
12211221
StringRef EventName;
12221222
std::optional<Location> Addr[3];
1223-
int64_t Counters[2];
1223+
int64_t Counters[2] = {0};
12241224

12251225
while (Type == INVALID || Type == EVENT_NAME) {
12261226
while (checkAndConsumeFS()) {

bolt/test/X86/entry-point-fallthru.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
# RUN: link_fdata %s %t %t.preagg PREAGG
77
# RUN: perf2bolt %t -p %t.preagg --pa -o %t.fdata | FileCheck %s
88
# CHECK: traces mismatching disassembled function contents: 0
9+
# RUN: FileCheck %s --check-prefix=CHECK-FDATA --input-file %t.fdata
10+
# CHECK-FDATA: 1 main 0 1 main 6 0 1
11+
# CHECK-FDATA-NEXT: 1 main e 1 main 11 0 1
12+
# CHECK-FDATA-NEXT: 1 main 11 1 main 0 0 1
913

1014
.globl main
1115
main:

clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,6 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
170170

171171
const auto PointerToStructType =
172172
hasUnqualifiedDesugaredType(pointerType(pointee(recordType())));
173-
const auto PointerToStructTypeWithBinding =
174-
type(PointerToStructType).bind("struct-type");
175173
const auto PointerToStructExpr =
176174
expr(hasType(hasCanonicalType(PointerToStructType)));
177175

@@ -188,12 +186,10 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
188186
ignoringParenImpCasts(unaryOperator(hasOperatorName("*")));
189187

190188
Finder->addMatcher(
191-
expr(sizeOfExpr(anyOf(has(ignoringParenImpCasts(
192-
expr(PointerToDetectedExpr, unless(DerefExpr),
193-
unless(SubscriptExprWithZeroIndex),
194-
unless(VarWithConstStrLiteralDecl),
195-
unless(cxxThisExpr())))),
196-
has(PointerToStructTypeWithBinding))))
189+
expr(sizeOfExpr(has(ignoringParenImpCasts(expr(
190+
PointerToDetectedExpr, unless(DerefExpr),
191+
unless(SubscriptExprWithZeroIndex),
192+
unless(VarWithConstStrLiteralDecl), unless(cxxThisExpr()))))))
197193
.bind("sizeof-pointer"),
198194
this);
199195
}
@@ -354,16 +350,9 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
354350
"suspicious usage of 'sizeof(char*)'; do you mean 'strlen'?")
355351
<< E->getSourceRange();
356352
} else if (const auto *E = Result.Nodes.getNodeAs<Expr>("sizeof-pointer")) {
357-
if (Result.Nodes.getNodeAs<Type>("struct-type")) {
358-
diag(E->getBeginLoc(),
359-
"suspicious usage of 'sizeof(A*)' on pointer-to-aggregate type; did "
360-
"you mean 'sizeof(A)'?")
361-
<< E->getSourceRange();
362-
} else {
363-
diag(E->getBeginLoc(), "suspicious usage of 'sizeof()' on an expression "
364-
"of pointer type")
365-
<< E->getSourceRange();
366-
}
353+
diag(E->getBeginLoc(), "suspicious usage of 'sizeof()' on an expression "
354+
"of pointer type")
355+
<< E->getSourceRange();
367356
} else if (const auto *E = Result.Nodes.getNodeAs<BinaryOperator>(
368357
"sizeof-compare-constant")) {
369358
diag(E->getOperatorLoc(),

clang/docs/LanguageExtensions.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3074,6 +3074,41 @@ following way:
30743074
30753075
Query for this feature with ``__has_builtin(__builtin_offsetof)``.
30763076
3077+
``__builtin_get_vtable_pointer``
3078+
--------------------------------
3079+
3080+
``__builtin_get_vtable_pointer`` loads and authenticates the primary vtable
3081+
pointer from an instance of a polymorphic C++ class. This builtin is needed
3082+
for directly loading the vtable pointer when on platforms using
3083+
:doc:`PointerAuthentication`.
3084+
3085+
**Syntax**:
3086+
3087+
.. code-block:: c++
3088+
3089+
__builtin_get_vtable_pointer(PolymorphicClass*)
3090+
3091+
**Example of Use**:
3092+
3093+
.. code-block:: c++
3094+
3095+
struct PolymorphicClass {
3096+
virtual ~PolymorphicClass();
3097+
};
3098+
3099+
PolymorphicClass anInstance;
3100+
const void* vtablePointer = __builtin_get_vtable_pointer(&anInstance);
3101+
3102+
**Description**:
3103+
3104+
The ``__builtin_get_vtable_pointer`` builtin loads the primary vtable
3105+
pointer from a polymorphic C++ type. If the target platform authenticates
3106+
vtable pointers, this builtin will perform the authentication and produce
3107+
the underlying raw pointer. The object being queried must be polymorphic,
3108+
and so must also be a complete type.
3109+
3110+
Query for this feature with ``__has_builtin(__builtin_get_vtable_pointer)``.
3111+
30773112
``__builtin_call_with_static_chain``
30783113
------------------------------------
30793114

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ Non-comprehensive list of changes in this release
317317
``sizeof`` or ``typeof`` expression. (#GH138444)
318318
- Deprecation warning is emitted for the deprecated ``__reference_binds_to_temporary`` intrinsic.
319319
``__reference_constructs_from_temporary`` should be used instead. (#GH44056)
320+
- Added `__builtin_get_vtable_pointer` to directly load the primary vtable pointer from a
321+
polymorphic object.
320322

321323
New Compiler Flags
322324
------------------

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,12 @@ def IsWithinLifetime : LangBuiltin<"CXX_LANG"> {
970970
let Prototype = "bool(void*)";
971971
}
972972

973+
def GetVtablePointer : LangBuiltin<"CXX_LANG"> {
974+
let Spellings = ["__builtin_get_vtable_pointer"];
975+
let Attributes = [CustomTypeChecking, NoThrow, Const];
976+
let Prototype = "void*(void*)";
977+
}
978+
973979
// GCC exception builtins
974980
def EHReturn : Builtin {
975981
let Spellings = ["__builtin_eh_return"];

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12807,6 +12807,14 @@ def err_bit_cast_non_trivially_copyable : Error<
1280712807
def err_bit_cast_type_size_mismatch : Error<
1280812808
"size of '__builtin_bit_cast' source type %0 does not match destination type %1 (%2 vs %3 bytes)">;
1280912809

12810+
def err_get_vtable_pointer_incorrect_type
12811+
: Error<"__builtin_get_vtable_pointer requires an argument of%select{| "
12812+
"polymorphic}0 class pointer type"
12813+
", but %1 %select{was provided|has no virtual methods}0">;
12814+
def err_get_vtable_pointer_requires_complete_type
12815+
: Error<"__builtin_get_vtable_pointer requires an argument with a complete "
12816+
"type, but %0 is incomplete">;
12817+
1281012818
// SYCL-specific diagnostics
1281112819
def warn_sycl_kernel_num_of_template_params : Warning<
1281212820
"'sycl_kernel' attribute only applies to a function template with at least"

clang/lib/AST/ByteCode/Context.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ using namespace clang;
2222
using namespace clang::interp;
2323

2424
Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {
25+
this->ShortWidth = Ctx.getTargetInfo().getShortWidth();
2526
this->IntWidth = Ctx.getTargetInfo().getIntWidth();
2627
this->LongWidth = Ctx.getTargetInfo().getLongWidth();
28+
this->LongLongWidth = Ctx.getTargetInfo().getLongLongWidth();
2729
assert(Ctx.getTargetInfo().getCharWidth() == 8 &&
2830
"We're assuming 8 bit chars");
2931
}
@@ -265,6 +267,11 @@ std::optional<PrimType> Context::classify(QualType T) const {
265267
return PT_MemberPtr;
266268

267269
// Just trying to avoid the ASTContext::getIntWidth call below.
270+
if (Kind == BuiltinType::Short)
271+
return integralTypeToPrimTypeS(this->ShortWidth);
272+
if (Kind == BuiltinType::UShort)
273+
return integralTypeToPrimTypeU(this->ShortWidth);
274+
268275
if (Kind == BuiltinType::Int)
269276
return integralTypeToPrimTypeS(this->IntWidth);
270277
if (Kind == BuiltinType::UInt)
@@ -273,6 +280,11 @@ std::optional<PrimType> Context::classify(QualType T) const {
273280
return integralTypeToPrimTypeS(this->LongWidth);
274281
if (Kind == BuiltinType::ULong)
275282
return integralTypeToPrimTypeU(this->LongWidth);
283+
if (Kind == BuiltinType::LongLong)
284+
return integralTypeToPrimTypeS(this->LongLongWidth);
285+
if (Kind == BuiltinType::ULongLong)
286+
return integralTypeToPrimTypeU(this->LongLongWidth);
287+
276288
if (Kind == BuiltinType::SChar || Kind == BuiltinType::Char_S)
277289
return integralTypeToPrimTypeS(8);
278290
if (Kind == BuiltinType::UChar || Kind == BuiltinType::Char_U ||

clang/lib/AST/ByteCode/Context.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,10 @@ class Context final {
138138
/// ID identifying an evaluation.
139139
unsigned EvalID = 0;
140140
/// Cached widths (in bits) of common types, for a faster classify().
141+
unsigned ShortWidth;
141142
unsigned IntWidth;
142143
unsigned LongWidth;
144+
unsigned LongLongWidth;
143145
};
144146

145147
} // namespace interp

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
104104
return builder.createBoolToInt(value, dstTy);
105105
if (mlir::isa<cir::BoolType>(dstTy))
106106
return value;
107+
llvm_unreachable("Can only promote integer or boolean types");
107108
}
108109

109110
//===--------------------------------------------------------------------===//
@@ -1857,9 +1858,6 @@ mlir::Value ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *e) {
18571858

18581859
// ZExt result to the expr type.
18591860
return maybePromoteBoolResult(boolVal, cgf.convertType(e->getType()));
1860-
1861-
cgf.cgm.errorNYI("destination type for logical-not unary operator is NYI");
1862-
return {};
18631861
}
18641862

18651863
/// Return the size or alignment of the type of argument of the sizeof

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "CGDebugInfo.h"
1818
#include "CGObjCRuntime.h"
1919
#include "CGOpenCLRuntime.h"
20+
#include "CGPointerAuthInfo.h"
2021
#include "CGRecordLayout.h"
2122
#include "CGValue.h"
2223
#include "CodeGenFunction.h"
@@ -5621,6 +5622,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
56215622
return RValue::get(Result);
56225623
}
56235624

5625+
case Builtin::BI__builtin_get_vtable_pointer: {
5626+
const Expr *Target = E->getArg(0);
5627+
QualType TargetType = Target->getType();
5628+
const CXXRecordDecl *Decl = TargetType->getPointeeCXXRecordDecl();
5629+
assert(Decl);
5630+
auto ThisAddress = EmitPointerWithAlignment(Target);
5631+
assert(ThisAddress.isValid());
5632+
llvm::Value *VTablePointer =
5633+
GetVTablePtr(ThisAddress, Int8PtrTy, Decl, VTableAuthMode::MustTrap);
5634+
return RValue::get(VTablePointer);
5635+
}
5636+
56245637
case Builtin::BI__exception_code:
56255638
case Builtin::BI_exception_code:
56265639
return RValue::get(EmitSEHExceptionCode());

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2747,7 +2747,14 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
27472747
if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)
27482748
BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
27492749
BoolCondVal, Stmt::getLikelihood(S.getBody()));
2750-
Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
2750+
auto *I = Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
2751+
// Key Instructions: Emit the condition and branch as separate atoms to
2752+
// match existing loop stepping behaviour. FIXME: We could have the branch as
2753+
// the backup location for the condition, which would probably be a better
2754+
// experience.
2755+
if (auto *CondI = dyn_cast<llvm::Instruction>(BoolCondVal))
2756+
addInstToNewSourceAtom(CondI, nullptr);
2757+
addInstToNewSourceAtom(I, nullptr);
27512758

27522759
if (ExitBlock != LoopExit.getBlock()) {
27532760
EmitBlock(ExitBlock);
@@ -2772,6 +2779,9 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
27722779
EmitStmt(S.getLoopVarStmt());
27732780
EmitStmt(S.getBody());
27742781
}
2782+
// The last block in the loop's body (which unconditionally branches to the
2783+
// `inc` block if there is one).
2784+
auto *FinalBodyBB = Builder.GetInsertBlock();
27752785

27762786
EmitStopPoint(&S);
27772787
// If there is an increment, emit it next.
@@ -2796,6 +2806,12 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
27962806

27972807
if (CGM.shouldEmitConvergenceTokens())
27982808
ConvergenceTokenStack.pop_back();
2809+
2810+
if (FinalBodyBB) {
2811+
// We want the for closing brace to be step-able on to match existing
2812+
// behaviour.
2813+
addInstToNewSourceAtom(FinalBodyBB->getTerminator(), nullptr);
2814+
}
27992815
}
28002816

28012817
void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {

clang/lib/Sema/SemaChecking.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,6 +1829,40 @@ static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call) {
18291829
return Call;
18301830
}
18311831

1832+
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call) {
1833+
if (S.checkArgCount(Call, 1))
1834+
return ExprError();
1835+
Expr *FirstArg = Call->getArg(0);
1836+
ExprResult FirstValue = S.DefaultFunctionArrayLvalueConversion(FirstArg);
1837+
if (FirstValue.isInvalid())
1838+
return ExprError();
1839+
Call->setArg(0, FirstValue.get());
1840+
QualType FirstArgType = FirstArg->getType();
1841+
if (FirstArgType->canDecayToPointerType() && FirstArgType->isArrayType())
1842+
FirstArgType = S.Context.getDecayedType(FirstArgType);
1843+
1844+
const CXXRecordDecl *FirstArgRecord = FirstArgType->getPointeeCXXRecordDecl();
1845+
if (!FirstArgRecord) {
1846+
S.Diag(FirstArg->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1847+
<< /*isPolymorphic=*/0 << FirstArgType;
1848+
return ExprError();
1849+
}
1850+
if (S.RequireCompleteType(
1851+
FirstArg->getBeginLoc(), FirstArgType->getPointeeType(),
1852+
diag::err_get_vtable_pointer_requires_complete_type)) {
1853+
return ExprError();
1854+
}
1855+
1856+
if (!FirstArgRecord->isPolymorphic()) {
1857+
S.Diag(FirstArg->getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1858+
<< /*isPolymorphic=*/1 << FirstArgRecord;
1859+
return ExprError();
1860+
}
1861+
QualType ReturnType = S.Context.getPointerType(S.Context.VoidTy.withConst());
1862+
Call->setType(ReturnType);
1863+
return Call;
1864+
}
1865+
18321866
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall) {
18331867
if (S.checkArgCount(TheCall, 1))
18341868
return ExprError();
@@ -2727,6 +2761,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
27272761
return PointerAuthAuthAndResign(*this, TheCall);
27282762
case Builtin::BI__builtin_ptrauth_string_discriminator:
27292763
return PointerAuthStringDiscriminator(*this, TheCall);
2764+
2765+
case Builtin::BI__builtin_get_vtable_pointer:
2766+
return GetVTablePointer(*this, TheCall);
2767+
27302768
// OpenCL v2.0, s6.13.16 - Pipe functions
27312769
case Builtin::BIread_pipe:
27322770
case Builtin::BIwrite_pipe:

0 commit comments

Comments
 (0)