Skip to content

Commit f09726f

Browse files
authored
merge main into amd-staging (llvm#1855)
2 parents ab1a20c + 932a56e commit f09726f

File tree

59 files changed

+864
-352
lines changed

Some content is hidden

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

59 files changed

+864
-352
lines changed

clang/include/clang/Interpreter/Interpreter.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class CXXRecordDecl;
4141
class Decl;
4242
class IncrementalExecutor;
4343
class IncrementalParser;
44+
class IncrementalCUDADeviceParser;
4445

4546
/// Create a pre-configured \c CompilerInstance for incremental processing.
4647
class IncrementalCompilerBuilder {
@@ -93,7 +94,10 @@ class Interpreter {
9394
std::unique_ptr<IncrementalExecutor> IncrExecutor;
9495

9596
// An optional parser for CUDA offloading
96-
std::unique_ptr<IncrementalParser> DeviceParser;
97+
std::unique_ptr<IncrementalCUDADeviceParser> DeviceParser;
98+
99+
// An optional action for CUDA offloading
100+
std::unique_ptr<IncrementalAction> DeviceAct;
97101

98102
/// List containing information about each incrementally parsed piece of code.
99103
std::list<PartialTranslationUnit> PTUs;
@@ -175,10 +179,11 @@ class Interpreter {
175179
llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E);
176180
llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD);
177181

178-
CodeGenerator *getCodeGen() const;
179-
std::unique_ptr<llvm::Module> GenModule();
182+
CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const;
183+
std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr);
180184
PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU,
181-
std::unique_ptr<llvm::Module> M = {});
185+
std::unique_ptr<llvm::Module> M = {},
186+
IncrementalAction *Action = nullptr);
182187

183188
// A cache for the compiled destructors used to for de-allocation of managed
184189
// clang::Values.

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,6 +3011,17 @@ bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(
30113011
return this->VisitCastExpr(E);
30123012
}
30133013

3014+
template <class Emitter>
3015+
bool Compiler<Emitter>::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
3016+
3017+
if (!Ctx.getLangOpts().CPlusPlus20) {
3018+
if (!this->emitInvalidCast(CastKind::Dynamic, /*Fatal=*/false, E))
3019+
return false;
3020+
}
3021+
3022+
return this->VisitCastExpr(E);
3023+
}
3024+
30143025
template <class Emitter>
30153026
bool Compiler<Emitter>::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
30163027
assert(E->getType()->isBooleanType());

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
180180
bool VisitPredefinedExpr(const PredefinedExpr *E);
181181
bool VisitCXXThrowExpr(const CXXThrowExpr *E);
182182
bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E);
183+
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E);
183184
bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
184185
bool VisitCXXConstructExpr(const CXXConstructExpr *E);
185186
bool VisitSourceLocExpr(const SourceLocExpr *E);

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,8 +1078,7 @@ bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
10781078
if (AK == AK_Read || AK == AK_Increment || AK == AK_Decrement)
10791079
return diagnoseUnknownDecl(S, OpPC, D);
10801080

1081-
assert(AK == AK_Assign);
1082-
if (S.getLangOpts().CPlusPlus14) {
1081+
if (AK == AK_Destroy || S.getLangOpts().CPlusPlus14) {
10831082
const SourceInfo &E = S.Current->getSource(OpPC);
10841083
S.FFDiag(E, diag::note_constexpr_modify_global);
10851084
}

clang/lib/AST/ByteCode/Interp.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,8 @@ bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
13201320

13211321
static inline bool Kill(InterpState &S, CodePtr OpPC) {
13221322
const auto &Ptr = S.Stk.pop<Pointer>();
1323+
if (!CheckDummy(S, OpPC, Ptr, AK_Destroy))
1324+
return false;
13231325
Ptr.endLifetime();
13241326
return true;
13251327
}
@@ -2197,6 +2199,21 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) {
21972199
//===----------------------------------------------------------------------===//
21982200

21992201
inline bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I) {
2202+
assert(S.Current->getFunction());
2203+
2204+
// FIXME: We iterate the scope once here and then again in the destroy() call
2205+
// below.
2206+
for (auto &Local : S.Current->getFunction()->getScope(I).locals_reverse()) {
2207+
const Pointer &Ptr = S.Current->getLocalPointer(Local.Offset);
2208+
2209+
if (Ptr.getLifetime() == Lifetime::Ended) {
2210+
auto *D = cast<NamedDecl>(Ptr.getFieldDesc()->asDecl());
2211+
S.FFDiag(D->getLocation(), diag::note_constexpr_destroy_out_of_lifetime)
2212+
<< D->getNameAsString();
2213+
return false;
2214+
}
2215+
}
2216+
22002217
S.Current->destroy(I);
22012218
return true;
22022219
}
@@ -2345,8 +2362,12 @@ template <PrimType Name, class T = typename PrimConv<Name>::T>
23452362
bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
23462363
const Pointer &Ptr = S.Stk.pop<Pointer>();
23472364

2365+
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
2366+
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
2367+
<< S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2368+
23482369
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, T::bitWidth()))
2349-
return false;
2370+
return Invalid(S, OpPC);
23502371

23512372
S.Stk.push<T>(T::from(Ptr.getIntegerRepresentation()));
23522373
return true;
@@ -2918,6 +2939,11 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
29182939
S.FFDiag(E);
29192940

29202941
return false;
2942+
} else if (Kind == CastKind::Dynamic) {
2943+
assert(!S.getLangOpts().CPlusPlus20);
2944+
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
2945+
<< diag::ConstexprInvalidCastKind::Dynamic;
2946+
return true;
29212947
}
29222948

29232949
return false;

clang/lib/AST/ByteCode/InterpState.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ bool InterpState::maybeDiagnoseDanglingAllocations() {
113113
<< (It.second.size() - 1) << Source->getSourceRange();
114114
}
115115
}
116-
return NoAllocationsLeft;
116+
// Keep evaluating before C++20, since the CXXNewExpr wasn't valid there
117+
// in the first place.
118+
return NoAllocationsLeft || !getLangOpts().CPlusPlus20;
117119
}
118120

119121
StdAllocatorCaller InterpState::getStdAllocatorCaller(StringRef Name) const {

clang/lib/AST/ByteCode/PrimType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ inline constexpr bool isPtrType(PrimType T) {
5656
enum class CastKind : uint8_t {
5757
Reinterpret,
5858
Volatile,
59+
Dynamic,
5960
};
6061

6162
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@@ -67,6 +68,9 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
6768
case interp::CastKind::Volatile:
6869
OS << "volatile";
6970
break;
71+
case interp::CastKind::Dynamic:
72+
OS << "dynamic";
73+
break;
7074
}
7175
return OS;
7276
}

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,7 +1357,7 @@ bool UnwrappedLineParser::parseModuleImport() {
13571357
// Handle import <foo/bar.h> as we would an include statement.
13581358
else if (FormatTok->is(tok::less)) {
13591359
nextToken();
1360-
while (!FormatTok->isOneOf(tok::semi, tok::greater, tok::eof)) {
1360+
while (!FormatTok->isOneOf(tok::semi, tok::greater) && !eof()) {
13611361
// Mark tokens up to the trailing line comments as implicit string
13621362
// literals.
13631363
if (FormatTok->isNot(tok::comment) &&
@@ -3106,7 +3106,7 @@ void UnwrappedLineParser::parseTryCatch() {
31063106
parseParens();
31073107
continue;
31083108
}
3109-
if (FormatTok->isOneOf(tok::semi, tok::r_brace, tok::eof)) {
3109+
if (FormatTok->isOneOf(tok::semi, tok::r_brace) || eof()) {
31103110
if (Style.RemoveBracesLLVM)
31113111
NestedTooDeep.pop_back();
31123112
return;

clang/lib/Interpreter/DeviceOffload.cpp

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,17 @@ IncrementalCUDADeviceParser::IncrementalCUDADeviceParser(
3131
llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs)
3232
: IncrementalParser(*DeviceInstance, Err), PTUs(PTUs), VFS(FS),
3333
CodeGenOpts(HostInstance.getCodeGenOpts()),
34-
TargetOpts(HostInstance.getTargetOpts()) {
34+
TargetOpts(DeviceInstance->getTargetOpts()) {
3535
if (Err)
3636
return;
37-
DeviceCI = std::move(DeviceInstance);
3837
StringRef Arch = TargetOpts.CPU;
3938
if (!Arch.starts_with("sm_") || Arch.substr(3).getAsInteger(10, SMVersion)) {
4039
Err = llvm::joinErrors(std::move(Err), llvm::make_error<llvm::StringError>(
4140
"Invalid CUDA architecture",
4241
llvm::inconvertibleErrorCode()));
4342
return;
4443
}
45-
}
46-
47-
llvm::Expected<TranslationUnitDecl *>
48-
IncrementalCUDADeviceParser::Parse(llvm::StringRef Input) {
49-
auto PTU = IncrementalParser::Parse(Input);
50-
if (!PTU)
51-
return PTU.takeError();
52-
53-
auto PTX = GeneratePTX();
54-
if (!PTX)
55-
return PTX.takeError();
56-
57-
auto Err = GenerateFatbinary();
58-
if (Err)
59-
return std::move(Err);
60-
61-
std::string FatbinFileName =
62-
"/incr_module_" + std::to_string(PTUs.size()) + ".fatbin";
63-
VFS->addFile(FatbinFileName, 0,
64-
llvm::MemoryBuffer::getMemBuffer(
65-
llvm::StringRef(FatbinContent.data(), FatbinContent.size()),
66-
"", false));
67-
68-
CodeGenOpts.CudaGpuBinaryFileName = FatbinFileName;
69-
70-
FatbinContent.clear();
71-
72-
return PTU;
44+
DeviceCI = std::move(DeviceInstance);
7345
}
7446

7547
llvm::Expected<llvm::StringRef> IncrementalCUDADeviceParser::GeneratePTX() {
@@ -172,6 +144,19 @@ llvm::Error IncrementalCUDADeviceParser::GenerateFatbinary() {
172144

173145
FatbinContent.append(PTXCode.begin(), PTXCode.end());
174146

147+
const PartialTranslationUnit &PTU = PTUs.back();
148+
149+
std::string FatbinFileName = "/" + PTU.TheModule->getName().str() + ".fatbin";
150+
151+
VFS->addFile(FatbinFileName, 0,
152+
llvm::MemoryBuffer::getMemBuffer(
153+
llvm::StringRef(FatbinContent.data(), FatbinContent.size()),
154+
"", false));
155+
156+
CodeGenOpts.CudaGpuBinaryFileName = FatbinFileName;
157+
158+
FatbinContent.clear();
159+
175160
return llvm::Error::success();
176161
}
177162

clang/lib/Interpreter/DeviceOffload.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ class IncrementalCUDADeviceParser : public IncrementalParser {
3333
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS,
3434
llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs);
3535

36-
llvm::Expected<TranslationUnitDecl *> Parse(llvm::StringRef Input) override;
37-
3836
// Generate PTX for the last PTU.
3937
llvm::Expected<llvm::StringRef> GeneratePTX();
4038

clang/lib/Interpreter/Interpreter.cpp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -481,20 +481,34 @@ Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
481481
OverlayVFS->pushOverlay(IMVFS);
482482
CI->createFileManager(OverlayVFS);
483483

484-
auto Interp = Interpreter::create(std::move(CI));
485-
if (auto E = Interp.takeError())
486-
return std::move(E);
484+
llvm::Expected<std::unique_ptr<Interpreter>> InterpOrErr =
485+
Interpreter::create(std::move(CI));
486+
if (!InterpOrErr)
487+
return InterpOrErr;
488+
489+
std::unique_ptr<Interpreter> Interp = std::move(*InterpOrErr);
487490

488491
llvm::Error Err = llvm::Error::success();
489-
auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
490-
std::move(DCI), *(*Interp)->getCompilerInstance(), IMVFS, Err,
491-
(*Interp)->PTUs);
492+
llvm::LLVMContext &LLVMCtx = *Interp->TSCtx->getContext();
493+
494+
auto DeviceAct =
495+
std::make_unique<IncrementalAction>(*DCI, LLVMCtx, Err, *Interp);
496+
492497
if (Err)
493498
return std::move(Err);
494499

495-
(*Interp)->DeviceParser = std::move(DeviceParser);
500+
Interp->DeviceAct = std::move(DeviceAct);
501+
502+
DCI->ExecuteAction(*Interp->DeviceAct);
503+
504+
auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
505+
std::move(DCI), *Interp->getCompilerInstance(), IMVFS, Err, Interp->PTUs);
506+
507+
if (Err)
508+
return std::move(Err);
496509

497-
return Interp;
510+
Interp->DeviceParser = std::move(DeviceParser);
511+
return std::move(Interp);
498512
}
499513

500514
const CompilerInstance *Interpreter::getCompilerInstance() const {
@@ -532,15 +546,17 @@ size_t Interpreter::getEffectivePTUSize() const {
532546

533547
PartialTranslationUnit &
534548
Interpreter::RegisterPTU(TranslationUnitDecl *TU,
535-
std::unique_ptr<llvm::Module> M /*={}*/) {
549+
std::unique_ptr<llvm::Module> M /*={}*/,
550+
IncrementalAction *Action) {
536551
PTUs.emplace_back(PartialTranslationUnit());
537552
PartialTranslationUnit &LastPTU = PTUs.back();
538553
LastPTU.TUPart = TU;
539554

540555
if (!M)
541-
M = GenModule();
556+
M = GenModule(Action);
542557

543-
assert((!getCodeGen() || M) && "Must have a llvm::Module at this point");
558+
assert((!getCodeGen(Action) || M) &&
559+
"Must have a llvm::Module at this point");
544560

545561
LastPTU.TheModule = std::move(M);
546562
LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1
@@ -560,6 +576,16 @@ Interpreter::Parse(llvm::StringRef Code) {
560576
llvm::Expected<TranslationUnitDecl *> DeviceTU = DeviceParser->Parse(Code);
561577
if (auto E = DeviceTU.takeError())
562578
return std::move(E);
579+
580+
RegisterPTU(*DeviceTU, nullptr, DeviceAct.get());
581+
582+
llvm::Expected<llvm::StringRef> PTX = DeviceParser->GeneratePTX();
583+
if (!PTX)
584+
return PTX.takeError();
585+
586+
llvm::Error Err = DeviceParser->GenerateFatbinary();
587+
if (Err)
588+
return std::move(Err);
563589
}
564590

565591
// Tell the interpreter sliently ignore unused expressions since value
@@ -736,9 +762,10 @@ llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
736762
return llvm::Error::success();
737763
}
738764

739-
std::unique_ptr<llvm::Module> Interpreter::GenModule() {
765+
std::unique_ptr<llvm::Module>
766+
Interpreter::GenModule(IncrementalAction *Action) {
740767
static unsigned ID = 0;
741-
if (CodeGenerator *CG = getCodeGen()) {
768+
if (CodeGenerator *CG = getCodeGen(Action)) {
742769
// Clang's CodeGen is designed to work with a single llvm::Module. In many
743770
// cases for convenience various CodeGen parts have a reference to the
744771
// llvm::Module (TheModule or Module) which does not change when a new
@@ -760,8 +787,10 @@ std::unique_ptr<llvm::Module> Interpreter::GenModule() {
760787
return nullptr;
761788
}
762789

763-
CodeGenerator *Interpreter::getCodeGen() const {
764-
FrontendAction *WrappedAct = Act->getWrapped();
790+
CodeGenerator *Interpreter::getCodeGen(IncrementalAction *Action) const {
791+
if (!Action)
792+
Action = Act.get();
793+
FrontendAction *WrappedAct = Action->getWrapped();
765794
if (!WrappedAct->hasIRSupport())
766795
return nullptr;
767796
return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();

clang/test/AST/ByteCode/cxx11-pedantic.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 -triple x86_64-linux -pedantic %s
2-
// RUN: %clang_cc1 -verify=both,ref -std=c++11 -triple x86_64-linux -pedantic %s
1+
// RUN: %clang_cc1 -verify=both,expected -std=c++11 -triple x86_64-linux -pedantic %s -fexperimental-new-constant-interpreter
2+
// RUN: %clang_cc1 -verify=both,ref -std=c++11 -triple x86_64-linux -pedantic %s
33

44
struct T { int n; };
55
const T t = { 42 }; // both-note 2{{declared here}}
@@ -11,3 +11,19 @@ struct S {
1111

1212
static_assert(t.n == 42, ""); // both-error {{expression is not an integral constant expression}} \
1313
// both-note {{read of non-constexpr variable 't' is not allowed}}
14+
15+
namespace DynamicCast {
16+
struct S { int n; };
17+
constexpr S s { 16 };
18+
struct T {
19+
int n : dynamic_cast<const S*>(&s)->n; // both-warning {{constant expression}} \
20+
// both-note {{dynamic_cast}}
21+
};
22+
}
23+
24+
namespace NewDelete {
25+
struct T {
26+
int n : *new int(4); // both-warning {{constant expression}} \
27+
// both-note {{until C++20}}
28+
};
29+
}

0 commit comments

Comments
 (0)