Skip to content

Commit 1c6208a

Browse files
committed
merge main into amd-staging
2 parents b24b984 + 2443fe5 commit 1c6208a

File tree

157 files changed

+7894
-2266
lines changed

Some content is hidden

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

157 files changed

+7894
-2266
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ Improvements to Clang's diagnostics
251251
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
252252
except for the case where the operand is an unsigned integer
253253
and throws warning if they are compared with unsigned integers (##18878).
254+
- The ``-Wunnecessary-virtual-specifier`` warning has been added to warn about
255+
methods which are marked as virtual inside a ``final`` class, and hence can
256+
never be overridden.
254257

255258
- Improve the diagnostics for chained comparisons to report actual expressions and operators (#GH129069).
256259

clang/include/clang/Basic/Attr.td

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4812,33 +4812,6 @@ def HLSLShader : InheritableAttr {
48124812
}];
48134813
}
48144814

4815-
def HLSLResource : InheritableAttr {
4816-
let Spellings = [];
4817-
let Subjects = SubjectList<[Struct]>;
4818-
let LangOpts = [HLSL];
4819-
let Args = [
4820-
EnumArgument<
4821-
"ResourceKind", "llvm::hlsl::ResourceKind",
4822-
/*is_string=*/0,
4823-
[
4824-
"Texture1D", "Texture2D", "Texture2DMS", "Texture3D", "TextureCube",
4825-
"Texture1DArray", "Texture2DArray", "Texture2DMSArray",
4826-
"TextureCubeArray", "TypedBuffer", "RawBuffer", "StructuredBuffer",
4827-
"CBuffer", "Sampler", "TBuffer", "RTAccelerationStructure",
4828-
"FeedbackTexture2D", "FeedbackTexture2DArray"
4829-
],
4830-
[
4831-
"Texture1D", "Texture2D", "Texture2DMS", "Texture3D", "TextureCube",
4832-
"Texture1DArray", "Texture2DArray", "Texture2DMSArray",
4833-
"TextureCubeArray", "TypedBuffer", "RawBuffer", "StructuredBuffer",
4834-
"CBuffer", "Sampler", "TBuffer", "RTAccelerationStructure",
4835-
"FeedbackTexture2D", "FeedbackTexture2DArray"
4836-
],
4837-
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1, /*isCovered=*/0>
4838-
];
4839-
let Documentation = [InternalOnly];
4840-
}
4841-
48424815
def HLSLROV : TypeAttr {
48434816
let Spellings = [CXX11<"hlsl", "is_rov">];
48444817
let LangOpts = [HLSL];

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,19 @@ def CXX11WarnInconsistentOverrideMethod :
372372
def CXX11WarnSuggestOverrideDestructor : DiagGroup<"suggest-destructor-override">;
373373
def CXX11WarnSuggestOverride : DiagGroup<"suggest-override">;
374374

375+
def WarnUnnecessaryVirtualSpecifier : DiagGroup<"unnecessary-virtual-specifier"> {
376+
code Documentation = [{
377+
Warns when a ``final`` class contains a virtual method (including virtual
378+
destructors). Since ``final`` classes cannot be subclassed, their methods
379+
cannot be overridden, and hence the ``virtual`` specifier is useless.
380+
381+
The warning also detects virtual methods in classes whose destructor is
382+
``final``, for the same reason.
383+
384+
The warning does not fire on virtual methods which are also marked ``override``.
385+
}];
386+
}
387+
375388
// Original name of this warning in Clang
376389
def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;
377390

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,9 @@ def warn_final_dtor_non_final_class : Warning<
27062706
InGroup<FinalDtorNonFinalClass>;
27072707
def note_final_dtor_non_final_class_silence : Note<
27082708
"mark %0 as '%select{final|sealed}1' to silence this warning">;
2709+
def warn_unnecessary_virtual_specifier : Warning<
2710+
"virtual method %0 is inside a 'final' class and can never be overridden">,
2711+
InGroup<WarnUnnecessaryVirtualSpecifier>, DefaultIgnore;
27092712

27102713
// C++11 attributes
27112714
def err_repeat_attribute : Error<"%0 attribute cannot be repeated">;
@@ -6214,7 +6217,7 @@ def warn_possible_object_duplication_mutable : Warning<
62146217
"it is mutable, has hidden visibility, and external linkage">,
62156218
InGroup<UniqueObjectDuplication>, DefaultIgnore;
62166219
def warn_possible_object_duplication_init : Warning<
6217-
"initializeation of %0 may run twice when built into a shared library: "
6220+
"initialization of %0 may run twice when built into a shared library: "
62186221
"it has hidden visibility and external linkage">,
62196222
InGroup<UniqueObjectDuplication>, DefaultIgnore;
62206223

clang/lib/AST/ByteCode/ByteCodeEmitter.cpp

Lines changed: 36 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -20,149 +20,64 @@
2020
using namespace clang;
2121
using namespace clang::interp;
2222

23-
Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
23+
void ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl,
24+
Function *Func) {
25+
assert(FuncDecl);
26+
assert(Func);
2427

2528
// Manually created functions that haven't been assigned proper
2629
// parameters yet.
2730
if (!FuncDecl->param_empty() && !FuncDecl->param_begin())
28-
return nullptr;
31+
return;
32+
33+
if (!FuncDecl->isDefined())
34+
return;
2935

30-
bool IsLambdaStaticInvoker = false;
36+
// Set up lambda captures.
3137
if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
32-
MD && MD->isLambdaStaticInvoker()) {
33-
// For a lambda static invoker, we might have to pick a specialized
34-
// version if the lambda is generic. In that case, the picked function
35-
// will *NOT* be a static invoker anymore. However, it will still
36-
// be a non-static member function, this (usually) requiring an
37-
// instance pointer. We suppress that later in this function.
38-
IsLambdaStaticInvoker = true;
39-
40-
const CXXRecordDecl *ClosureClass = MD->getParent();
41-
assert(ClosureClass->captures_begin() == ClosureClass->captures_end());
42-
if (ClosureClass->isGenericLambda()) {
43-
const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
44-
assert(MD->isFunctionTemplateSpecialization() &&
45-
"A generic lambda's static-invoker function must be a "
46-
"template specialization");
47-
const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
48-
FunctionTemplateDecl *CallOpTemplate =
49-
LambdaCallOp->getDescribedFunctionTemplate();
50-
void *InsertPos = nullptr;
51-
const FunctionDecl *CorrespondingCallOpSpecialization =
52-
CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
53-
assert(CorrespondingCallOpSpecialization);
54-
FuncDecl = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
55-
}
56-
}
38+
MD && isLambdaCallOperator(MD)) {
39+
// Set up lambda capture to closure record field mapping.
40+
const Record *R = P.getOrCreateRecord(MD->getParent());
41+
assert(R);
42+
llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
43+
FieldDecl *LTC;
5744

58-
// Set up argument indices.
59-
unsigned ParamOffset = 0;
60-
SmallVector<PrimType, 8> ParamTypes;
61-
SmallVector<unsigned, 8> ParamOffsets;
62-
llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
63-
64-
// If the return is not a primitive, a pointer to the storage where the
65-
// value is initialized in is passed as the first argument. See 'RVO'
66-
// elsewhere in the code.
67-
QualType Ty = FuncDecl->getReturnType();
68-
bool HasRVO = false;
69-
if (!Ty->isVoidType() && !Ctx.classify(Ty)) {
70-
HasRVO = true;
71-
ParamTypes.push_back(PT_Ptr);
72-
ParamOffsets.push_back(ParamOffset);
73-
ParamOffset += align(primSize(PT_Ptr));
74-
}
45+
MD->getParent()->getCaptureFields(LC, LTC);
7546

76-
// If the function decl is a member decl, the next parameter is
77-
// the 'this' pointer. This parameter is pop()ed from the
78-
// InterpStack when calling the function.
79-
bool HasThisPointer = false;
80-
if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) {
81-
if (!IsLambdaStaticInvoker) {
82-
HasThisPointer = MD->isInstance();
83-
if (MD->isImplicitObjectMemberFunction()) {
84-
ParamTypes.push_back(PT_Ptr);
85-
ParamOffsets.push_back(ParamOffset);
86-
ParamOffset += align(primSize(PT_Ptr));
87-
}
47+
for (auto Cap : LC) {
48+
unsigned Offset = R->getField(Cap.second)->Offset;
49+
this->LambdaCaptures[Cap.first] = {
50+
Offset, Cap.second->getType()->isReferenceType()};
8851
}
89-
90-
// Set up lambda capture to closure record field mapping.
91-
if (isLambdaCallOperator(MD)) {
92-
// The parent record needs to be complete, we need to know about all
93-
// the lambda captures.
94-
if (!MD->getParent()->isCompleteDefinition())
95-
return nullptr;
96-
97-
const Record *R = P.getOrCreateRecord(MD->getParent());
98-
llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
99-
FieldDecl *LTC;
100-
101-
MD->getParent()->getCaptureFields(LC, LTC);
102-
103-
for (auto Cap : LC) {
104-
// Static lambdas cannot have any captures. If this one does,
105-
// it has already been diagnosed and we can only ignore it.
106-
if (MD->isStatic())
107-
return nullptr;
108-
109-
unsigned Offset = R->getField(Cap.second)->Offset;
110-
this->LambdaCaptures[Cap.first] = {
111-
Offset, Cap.second->getType()->isReferenceType()};
112-
}
113-
if (LTC) {
114-
QualType CaptureType = R->getField(LTC)->Decl->getType();
115-
this->LambdaThisCapture = {R->getField(LTC)->Offset,
116-
CaptureType->isReferenceType() ||
117-
CaptureType->isPointerType()};
118-
}
52+
if (LTC) {
53+
QualType CaptureType = R->getField(LTC)->Decl->getType();
54+
this->LambdaThisCapture = {R->getField(LTC)->Offset,
55+
CaptureType->isPointerOrReferenceType()};
11956
}
12057
}
12158

122-
// Assign descriptors to all parameters.
123-
// Composite objects are lowered to pointers.
124-
for (const ParmVarDecl *PD : FuncDecl->parameters()) {
59+
// Register parameters with their offset.
60+
unsigned ParamIndex = 0;
61+
unsigned Drop = Func->hasRVO() +
62+
(Func->hasThisPointer() && !Func->isThisPointerExplicit());
63+
for (auto ParamOffset : llvm::drop_begin(Func->ParamOffsets, Drop)) {
64+
const ParmVarDecl *PD = FuncDecl->parameters()[ParamIndex];
12565
std::optional<PrimType> T = Ctx.classify(PD->getType());
126-
PrimType PT = T.value_or(PT_Ptr);
127-
Descriptor *Desc = P.createDescriptor(PD, PT);
128-
ParamDescriptors.insert({ParamOffset, {PT, Desc}});
129-
Params.insert({PD, {ParamOffset, T != std::nullopt}});
130-
ParamOffsets.push_back(ParamOffset);
131-
ParamOffset += align(primSize(PT));
132-
ParamTypes.push_back(PT);
133-
}
134-
135-
// Create a handle over the emitted code.
136-
Function *Func = P.getFunction(FuncDecl);
137-
if (!Func) {
138-
Func = P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
139-
std::move(ParamDescriptors),
140-
std::move(ParamOffsets), HasThisPointer, HasRVO);
141-
}
142-
143-
assert(Func);
144-
// For not-yet-defined functions, we only create a Function instance and
145-
// compile their body later.
146-
if (!FuncDecl->isDefined() ||
147-
(FuncDecl->willHaveBody() && !FuncDecl->hasBody())) {
148-
Func->setDefined(false);
149-
return Func;
66+
this->Params.insert({PD, {ParamOffset, T != std::nullopt}});
67+
++ParamIndex;
15068
}
15169

15270
Func->setDefined(true);
15371

15472
// Lambda static invokers are a special case that we emit custom code for.
155-
bool IsEligibleForCompilation = false;
156-
if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl))
157-
IsEligibleForCompilation = MD->isLambdaStaticInvoker();
158-
if (!IsEligibleForCompilation)
159-
IsEligibleForCompilation =
160-
FuncDecl->isConstexpr() || FuncDecl->hasAttr<MSConstexprAttr>();
73+
bool IsEligibleForCompilation = Func->isLambdaStaticInvoker() ||
74+
FuncDecl->isConstexpr() ||
75+
FuncDecl->hasAttr<MSConstexprAttr>();
16176

16277
// Compile the function body.
16378
if (!IsEligibleForCompilation || !visitFunc(FuncDecl)) {
16479
Func->setIsFullyCompiled(true);
165-
return Func;
80+
return;
16681
}
16782

16883
// Create scopes from descriptors.
@@ -175,48 +90,6 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
17590
Func->setCode(NextLocalOffset, std::move(Code), std::move(SrcMap),
17691
std::move(Scopes), FuncDecl->hasBody());
17792
Func->setIsFullyCompiled(true);
178-
return Func;
179-
}
180-
181-
/// Compile an ObjC block, i.e. ^(){}, that thing.
182-
///
183-
/// FIXME: We do not support calling the block though, so we create a function
184-
/// here but do not compile any code for it.
185-
Function *ByteCodeEmitter::compileObjCBlock(const BlockExpr *BE) {
186-
const BlockDecl *BD = BE->getBlockDecl();
187-
// Set up argument indices.
188-
unsigned ParamOffset = 0;
189-
SmallVector<PrimType, 8> ParamTypes;
190-
SmallVector<unsigned, 8> ParamOffsets;
191-
llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;
192-
193-
// Assign descriptors to all parameters.
194-
// Composite objects are lowered to pointers.
195-
for (const ParmVarDecl *PD : BD->parameters()) {
196-
std::optional<PrimType> T = Ctx.classify(PD->getType());
197-
PrimType PT = T.value_or(PT_Ptr);
198-
Descriptor *Desc = P.createDescriptor(PD, PT);
199-
ParamDescriptors.insert({ParamOffset, {PT, Desc}});
200-
Params.insert({PD, {ParamOffset, T != std::nullopt}});
201-
ParamOffsets.push_back(ParamOffset);
202-
ParamOffset += align(primSize(PT));
203-
ParamTypes.push_back(PT);
204-
}
205-
206-
if (BD->hasCaptures())
207-
return nullptr;
208-
209-
// Create a handle over the emitted code.
210-
Function *Func =
211-
P.createFunction(BE, ParamOffset, std::move(ParamTypes),
212-
std::move(ParamDescriptors), std::move(ParamOffsets),
213-
/*HasThisPointer=*/false, /*HasRVO=*/false);
214-
215-
assert(Func);
216-
Func->setDefined(true);
217-
// We don't compile the BlockDecl code at all right now.
218-
Func->setIsFullyCompiled(true);
219-
return Func;
22093
}
22194

22295
Scope::Local ByteCodeEmitter::createLocal(Descriptor *D) {

clang/lib/AST/ByteCode/ByteCodeEmitter.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ class ByteCodeEmitter {
3131

3232
public:
3333
/// Compiles the function into the module.
34-
Function *compileFunc(const FunctionDecl *FuncDecl);
35-
Function *compileObjCBlock(const BlockExpr *BE);
34+
void compileFunc(const FunctionDecl *FuncDecl, Function *Func = nullptr);
3635

3736
protected:
3837
ByteCodeEmitter(Context &Ctx, Program &P) : Ctx(Ctx), P(P) {}

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3576,7 +3576,7 @@ bool Compiler<Emitter>::VisitBlockExpr(const BlockExpr *E) {
35763576
return true;
35773577

35783578
const Function *Func = nullptr;
3579-
if (auto F = Compiler<ByteCodeEmitter>(Ctx, P).compileObjCBlock(E))
3579+
if (auto F = Ctx.getOrCreateObjCBlock(E))
35803580
Func = F;
35813581

35823582
if (!Func)
@@ -4787,8 +4787,12 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
47874787
}
47884788
// Explicit calls to trivial destructors
47894789
if (const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
4790-
DD && DD->isTrivial())
4791-
return true;
4790+
DD && DD->isTrivial()) {
4791+
const auto *MemberCall = cast<CXXMemberCallExpr>(E);
4792+
if (!this->visit(MemberCall->getImplicitObjectArgument()))
4793+
return false;
4794+
return this->emitCheckDestruction(E) && this->emitPopPtr(E);
4795+
}
47924796

47934797
QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
47944798
std::optional<PrimType> T = classify(ReturnType);
@@ -5829,6 +5833,9 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
58295833
if (!this->emitThis(Dtor))
58305834
return false;
58315835

5836+
if (!this->emitCheckDestruction(Dtor))
5837+
return false;
5838+
58325839
assert(R);
58335840
if (!R->isUnion()) {
58345841
// First, destroy all fields.

0 commit comments

Comments
 (0)