Skip to content

Commit 93f18c4

Browse files
Jenkinsnicebert
authored andcommitted
merge main into amd-staging
Change-Id: I1c57628dde6e7df243b5f3a045b83af4d8646571
2 parents 51a0461 + f5a067b commit 93f18c4

File tree

162 files changed

+2887
-949
lines changed

Some content is hidden

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

162 files changed

+2887
-949
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,51 @@ cplusplus
340340
341341
C++ Checkers.
342342
343+
.. _cplusplus-ArrayDelete:
344+
345+
cplusplus.ArrayDelete (C++)
346+
"""""""""""""""""""""""""""
347+
348+
Reports destructions of arrays of polymorphic objects that are destructed as
349+
their base class. If the dynamic type of the array is different from its static
350+
type, calling `delete[]` is undefined.
351+
352+
This checker corresponds to the SEI CERT rule `EXP51-CPP: Do not delete an array through a pointer of the incorrect type <https://wiki.sei.cmu.edu/confluence/display/cplusplus/EXP51-CPP.+Do+not+delete+an+array+through+a+pointer+of+the+incorrect+type>`_.
353+
354+
.. code-block:: cpp
355+
356+
class Base {
357+
public:
358+
virtual ~Base() {}
359+
};
360+
class Derived : public Base {};
361+
362+
Base *create() {
363+
Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
364+
return x;
365+
}
366+
367+
void foo() {
368+
Base *x = create();
369+
delete[] x; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined
370+
}
371+
372+
**Limitations**
373+
374+
The checker does not emit note tags when casting to and from reference types,
375+
even though the pointer values are tracked across references.
376+
377+
.. code-block:: cpp
378+
379+
void foo() {
380+
Derived *d = new Derived[10];
381+
Derived &dref = *d;
382+
383+
Base &bref = static_cast<Base&>(dref); // no note
384+
Base *b = &bref;
385+
delete[] b; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined
386+
}
387+
343388
.. _cplusplus-InnerPointer:
344389
345390
cplusplus.InnerPointer (C++)
@@ -2139,30 +2184,6 @@ Either the comparison is useless or there is division by zero.
21392184
alpha.cplusplus
21402185
^^^^^^^^^^^^^^^
21412186
2142-
.. _alpha-cplusplus-ArrayDelete:
2143-
2144-
alpha.cplusplus.ArrayDelete (C++)
2145-
"""""""""""""""""""""""""""""""""
2146-
Reports destructions of arrays of polymorphic objects that are destructed as their base class.
2147-
This checker corresponds to the CERT rule `EXP51-CPP: Do not delete an array through a pointer of the incorrect type <https://wiki.sei.cmu.edu/confluence/display/cplusplus/EXP51-CPP.+Do+not+delete+an+array+through+a+pointer+of+the+incorrect+type>`_.
2148-
2149-
.. code-block:: cpp
2150-
2151-
class Base {
2152-
virtual ~Base() {}
2153-
};
2154-
class Derived : public Base {}
2155-
2156-
Base *create() {
2157-
Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
2158-
return x;
2159-
}
2160-
2161-
void foo() {
2162-
Base *x = create();
2163-
delete[] x; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined
2164-
}
2165-
21662187
.. _alpha-cplusplus-DeleteWithNonVirtualDtor:
21672188
21682189
alpha.cplusplus.DeleteWithNonVirtualDtor (C++)

clang/include/clang/Interpreter/Interpreter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
namespace llvm {
3131
namespace orc {
3232
class LLJIT;
33+
class LLJITBuilder;
3334
class ThreadSafeContext;
3435
} // namespace orc
3536
} // namespace llvm
@@ -127,6 +128,13 @@ class Interpreter {
127128
// custom runtime.
128129
virtual std::unique_ptr<RuntimeInterfaceBuilder> FindRuntimeInterface();
129130

131+
// Lazily construct thev ORCv2 JITBuilder. This called when the internal
132+
// IncrementalExecutor is created. The default implementation populates an
133+
// in-process JIT with debugging support. Override this to configure the JIT
134+
// engine used for execution.
135+
virtual llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
136+
CreateJITBuilder(CompilerInstance &CI);
137+
130138
public:
131139
virtual ~Interpreter();
132140

clang/include/clang/Interpreter/Value.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class QualType;
7676
X(bool, Bool) \
7777
X(char, Char_S) \
7878
X(signed char, SChar) \
79+
X(unsigned char, Char_U) \
7980
X(unsigned char, UChar) \
8081
X(short, Short) \
8182
X(unsigned short, UShort) \

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,11 @@ def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
622622

623623
let ParentPackage = Cplusplus in {
624624

625+
def ArrayDeleteChecker : Checker<"ArrayDelete">,
626+
HelpText<"Reports destructions of arrays of polymorphic objects that are "
627+
"destructed as their base class.">,
628+
Documentation<HasDocumentation>;
629+
625630
def InnerPointerChecker : Checker<"InnerPointer">,
626631
HelpText<"Check for inner pointers of C++ containers used after "
627632
"re/deallocation">,
@@ -777,11 +782,6 @@ def ContainerModeling : Checker<"ContainerModeling">,
777782
Documentation<NotDocumented>,
778783
Hidden;
779784

780-
def CXXArrayDeleteChecker : Checker<"ArrayDelete">,
781-
HelpText<"Reports destructions of arrays of polymorphic objects that are "
782-
"destructed as their base class.">,
783-
Documentation<HasDocumentation>;
784-
785785
def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
786786
HelpText<"Reports destructions of polymorphic objects with a non-virtual "
787787
"destructor in their base class">,

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 71 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3720,7 +3720,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
37203720

37213721
// Forward declarations are emitted lazily on first use.
37223722
if (!FD->doesThisDeclarationHaveABody()) {
3723-
if (!FD->doesDeclarationForceExternallyVisibleDefinition())
3723+
if (!FD->doesDeclarationForceExternallyVisibleDefinition() &&
3724+
!FD->isTargetVersionMultiVersion())
37243725
return;
37253726

37263727
StringRef MangledName = getMangledName(GD);
@@ -4101,77 +4102,78 @@ llvm::GlobalValue::LinkageTypes getMultiversionLinkage(CodeGenModule &CGM,
41014102
return llvm::GlobalValue::WeakODRLinkage;
41024103
}
41034104

4105+
static FunctionDecl *createDefaultTargetVersionFrom(const FunctionDecl *FD) {
4106+
DeclContext *DeclCtx = FD->getASTContext().getTranslationUnitDecl();
4107+
TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
4108+
StorageClass SC = FD->getStorageClass();
4109+
DeclarationName Name = FD->getNameInfo().getName();
4110+
4111+
FunctionDecl *NewDecl =
4112+
FunctionDecl::Create(FD->getASTContext(), DeclCtx, FD->getBeginLoc(),
4113+
FD->getEndLoc(), Name, TInfo->getType(), TInfo, SC);
4114+
4115+
NewDecl->setIsMultiVersion();
4116+
NewDecl->addAttr(TargetVersionAttr::CreateImplicit(
4117+
NewDecl->getASTContext(), "default", NewDecl->getSourceRange()));
4118+
4119+
return NewDecl;
4120+
}
4121+
41044122
void CodeGenModule::emitMultiVersionFunctions() {
41054123
std::vector<GlobalDecl> MVFuncsToEmit;
41064124
MultiVersionFuncs.swap(MVFuncsToEmit);
41074125
for (GlobalDecl GD : MVFuncsToEmit) {
41084126
const auto *FD = cast<FunctionDecl>(GD.getDecl());
41094127
assert(FD && "Expected a FunctionDecl");
41104128

4111-
bool EmitResolver = !FD->isTargetVersionMultiVersion();
4129+
auto createFunction = [&](const FunctionDecl *Decl, unsigned MVIdx = 0) {
4130+
GlobalDecl CurGD{Decl->isDefined() ? Decl->getDefinition() : Decl, MVIdx};
4131+
StringRef MangledName = getMangledName(CurGD);
4132+
llvm::Constant *Func = GetGlobalValue(MangledName);
4133+
if (!Func) {
4134+
if (Decl->isDefined()) {
4135+
EmitGlobalFunctionDefinition(CurGD, nullptr);
4136+
Func = GetGlobalValue(MangledName);
4137+
} else {
4138+
const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(CurGD);
4139+
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
4140+
Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
4141+
/*DontDefer=*/false, ForDefinition);
4142+
}
4143+
assert(Func && "This should have just been created");
4144+
}
4145+
return cast<llvm::Function>(Func);
4146+
};
4147+
4148+
bool HasDefaultDecl = !FD->isTargetVersionMultiVersion();
4149+
bool ShouldEmitResolver = !FD->isTargetVersionMultiVersion();
41124150
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;
41134151
if (FD->isTargetMultiVersion()) {
41144152
getContext().forEachMultiversionedFunctionVersion(
4115-
FD, [this, &GD, &Options, &EmitResolver](const FunctionDecl *CurFD) {
4116-
GlobalDecl CurGD{
4117-
(CurFD->isDefined() ? CurFD->getDefinition() : CurFD)};
4118-
StringRef MangledName = getMangledName(CurGD);
4119-
llvm::Constant *Func = GetGlobalValue(MangledName);
4120-
if (!Func) {
4121-
if (CurFD->isDefined()) {
4122-
EmitGlobalFunctionDefinition(CurGD, nullptr);
4123-
Func = GetGlobalValue(MangledName);
4124-
} else {
4125-
const CGFunctionInfo &FI =
4126-
getTypes().arrangeGlobalDeclaration(GD);
4127-
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
4128-
Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
4129-
/*DontDefer=*/false, ForDefinition);
4130-
}
4131-
assert(Func && "This should have just been created");
4132-
}
4133-
if (CurFD->getMultiVersionKind() == MultiVersionKind::Target) {
4134-
const auto *TA = CurFD->getAttr<TargetAttr>();
4135-
llvm::SmallVector<StringRef, 8> Feats;
4153+
FD, [&](const FunctionDecl *CurFD) {
4154+
llvm::SmallVector<StringRef, 8> Feats;
4155+
llvm::Function *Func = createFunction(CurFD);
4156+
4157+
if (const auto *TA = CurFD->getAttr<TargetAttr>()) {
41364158
TA->getAddedFeatures(Feats);
4137-
Options.emplace_back(cast<llvm::Function>(Func),
4138-
TA->getArchitecture(), Feats);
4139-
} else {
4140-
const auto *TVA = CurFD->getAttr<TargetVersionAttr>();
4141-
if (CurFD->isUsed() || (TVA->isDefaultVersion() &&
4142-
CurFD->doesThisDeclarationHaveABody()))
4143-
EmitResolver = true;
4144-
llvm::SmallVector<StringRef, 8> Feats;
4159+
Options.emplace_back(Func, TA->getArchitecture(), Feats);
4160+
} else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) {
4161+
bool HasDefaultDef = TVA->isDefaultVersion() &&
4162+
CurFD->doesThisDeclarationHaveABody();
4163+
HasDefaultDecl |= TVA->isDefaultVersion();
4164+
ShouldEmitResolver |= (CurFD->isUsed() || HasDefaultDef);
41454165
TVA->getFeatures(Feats);
4146-
Options.emplace_back(cast<llvm::Function>(Func),
4147-
/*Architecture*/ "", Feats);
4148-
}
4166+
Options.emplace_back(Func, /*Architecture*/ "", Feats);
4167+
} else
4168+
llvm_unreachable("unexpected MultiVersionKind");
41494169
});
4150-
} else if (FD->isTargetClonesMultiVersion()) {
4151-
const auto *TC = FD->getAttr<TargetClonesAttr>();
4152-
for (unsigned VersionIndex = 0; VersionIndex < TC->featuresStrs_size();
4153-
++VersionIndex) {
4154-
if (!TC->isFirstOfVersion(VersionIndex))
4170+
} else if (const auto *TC = FD->getAttr<TargetClonesAttr>()) {
4171+
for (unsigned I = 0; I < TC->featuresStrs_size(); ++I) {
4172+
if (!TC->isFirstOfVersion(I))
41554173
continue;
4156-
GlobalDecl CurGD{(FD->isDefined() ? FD->getDefinition() : FD),
4157-
VersionIndex};
4158-
StringRef Version = TC->getFeatureStr(VersionIndex);
4159-
StringRef MangledName = getMangledName(CurGD);
4160-
llvm::Constant *Func = GetGlobalValue(MangledName);
4161-
if (!Func) {
4162-
if (FD->isDefined()) {
4163-
EmitGlobalFunctionDefinition(CurGD, nullptr);
4164-
Func = GetGlobalValue(MangledName);
4165-
} else {
4166-
const CGFunctionInfo &FI =
4167-
getTypes().arrangeGlobalDeclaration(CurGD);
4168-
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
4169-
Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
4170-
/*DontDefer=*/false, ForDefinition);
4171-
}
4172-
assert(Func && "This should have just been created");
4173-
}
41744174

4175+
llvm::Function *Func = createFunction(FD, I);
4176+
StringRef Version = TC->getFeatureStr(I);
41754177
StringRef Architecture;
41764178
llvm::SmallVector<StringRef, 1> Feature;
41774179

@@ -4189,16 +4191,23 @@ void CodeGenModule::emitMultiVersionFunctions() {
41894191
Feature.push_back(Version);
41904192
}
41914193

4192-
Options.emplace_back(cast<llvm::Function>(Func), Architecture, Feature);
4194+
Options.emplace_back(Func, Architecture, Feature);
41934195
}
41944196
} else {
41954197
assert(0 && "Expected a target or target_clones multiversion function");
41964198
continue;
41974199
}
41984200

4199-
if (!EmitResolver)
4201+
if (!ShouldEmitResolver)
42004202
continue;
42014203

4204+
if (!HasDefaultDecl) {
4205+
FunctionDecl *NewFD = createDefaultTargetVersionFrom(FD);
4206+
llvm::Function *Func = createFunction(NewFD);
4207+
llvm::SmallVector<StringRef, 1> Feats;
4208+
Options.emplace_back(Func, /*Architecture*/ "", Feats);
4209+
}
4210+
42024211
llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD);
42034212
if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) {
42044213
ResolverConstant = IFunc->getResolver();
@@ -4489,7 +4498,9 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
44894498

44904499
if (FD->isMultiVersion()) {
44914500
UpdateMultiVersionNames(GD, FD, MangledName);
4492-
if (!IsForDefinition)
4501+
if (FD->isTargetVersionMultiVersion() && !FD->isUsed())
4502+
AddDeferredMultiVersionResolverToEmit(GD);
4503+
else if (!IsForDefinition)
44934504
return GetOrCreateMultiVersionResolver(GD);
44944505
}
44954506
}

clang/lib/Interpreter/IncrementalExecutor.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
2121
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
2222
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
23+
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
2324
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
2425
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
2526
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
@@ -36,26 +37,28 @@ LLVM_ATTRIBUTE_USED void linkComponents() {
3637

3738
namespace clang {
3839

40+
llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
41+
IncrementalExecutor::createDefaultJITBuilder(
42+
llvm::orc::JITTargetMachineBuilder JTMB) {
43+
auto JITBuilder = std::make_unique<llvm::orc::LLJITBuilder>();
44+
JITBuilder->setJITTargetMachineBuilder(std::move(JTMB));
45+
JITBuilder->setPrePlatformSetup([](llvm::orc::LLJIT &J) {
46+
// Try to enable debugging of JIT'd code (only works with JITLink for
47+
// ELF and MachO).
48+
consumeError(llvm::orc::enableDebuggerSupport(J));
49+
return llvm::Error::success();
50+
});
51+
return std::move(JITBuilder);
52+
}
53+
3954
IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
40-
llvm::Error &Err,
41-
const clang::TargetInfo &TI)
55+
llvm::orc::LLJITBuilder &JITBuilder,
56+
llvm::Error &Err)
4257
: TSCtx(TSC) {
4358
using namespace llvm::orc;
4459
llvm::ErrorAsOutParameter EAO(&Err);
4560

46-
auto JTMB = JITTargetMachineBuilder(TI.getTriple());
47-
JTMB.addFeatures(TI.getTargetOpts().Features);
48-
LLJITBuilder Builder;
49-
Builder.setJITTargetMachineBuilder(JTMB);
50-
Builder.setPrePlatformSetup(
51-
[](LLJIT &J) {
52-
// Try to enable debugging of JIT'd code (only works with JITLink for
53-
// ELF and MachO).
54-
consumeError(enableDebuggerSupport(J));
55-
return llvm::Error::success();
56-
});
57-
58-
if (auto JitOrErr = Builder.create())
61+
if (auto JitOrErr = JITBuilder.create())
5962
Jit = std::move(*JitOrErr);
6063
else {
6164
Err = JitOrErr.takeError();

0 commit comments

Comments
 (0)