Skip to content

Commit 9f53c00

Browse files
committed
Merge remote-tracking branch 'origin/main' into vplan-scalar-ph-phi-for
2 parents bd6fe32 + c16e378 commit 9f53c00

File tree

101 files changed

+2254
-1075
lines changed

Some content is hidden

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

101 files changed

+2254
-1075
lines changed

clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ void UseInternalLinkageCheck::check(const MatchFinder::MatchResult &Result) {
121121
return;
122122
}
123123
if (const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var")) {
124+
// In C++, const variables at file scope have implicit internal linkage,
125+
// so we should not warn there. This is not the case in C.
126+
// https://eel.is/c++draft/diff#basic-3
127+
if (getLangOpts().CPlusPlus && VD->getType().isConstQualified())
128+
return;
129+
124130
DiagnosticBuilder DB = diag(VD->getLocation(), Message) << "variable" << VD;
125131
SourceLocation FixLoc = VD->getTypeSpecStartLoc();
126132
if (FixLoc.isInvalid() || FixLoc.isMacroID())

clang-tools-extra/test/clang-tidy/checkers/misc/use-internal-linkage-var.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ int global_in_extern_c_1;
4242
}
4343

4444
extern "C" int global_in_extern_c_2;
45+
46+
const int const_global = 123;
47+
constexpr int constexpr_global = 123;

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,7 @@ Bug Fixes to C++ Support
962962
- Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
963963
- Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307),
964964
(#GH88081), (#GH89496), (#GH90669) and (#GH91633).
965+
- Fixed a crash in constraint instantiation under nested lambdas with dependent parameters.
965966
- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
966967
- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)
967968
- Fixed a failed assertion when attempting to convert an integer representing the difference

clang/lib/AST/Interp/ByteCodeEmitter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class ByteCodeEmitter {
4646
/// Methods implemented by the compiler.
4747
virtual bool visitFunc(const FunctionDecl *E) = 0;
4848
virtual bool visitExpr(const Expr *E) = 0;
49-
virtual bool visitDecl(const VarDecl *E, bool ConstantContext) = 0;
49+
virtual bool visitDeclAndReturn(const VarDecl *E, bool ConstantContext) = 0;
5050

5151
/// Emits jumps.
5252
bool jumpTrue(const LabelTy &Label);

clang/lib/AST/Interp/Compiler.cpp

Lines changed: 86 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ namespace clang {
2525
namespace interp {
2626

2727
/// Scope used to handle temporaries in toplevel variable declarations.
28-
template <class Emitter> class DeclScope final : public VariableScope<Emitter> {
28+
template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
2929
public:
3030
DeclScope(Compiler<Emitter> *Ctx, const ValueDecl *VD)
31-
: VariableScope<Emitter>(Ctx, nullptr), Scope(Ctx->P, VD),
31+
: LocalScope<Emitter>(Ctx, VD), Scope(Ctx->P, VD),
3232
OldGlobalDecl(Ctx->GlobalDecl),
3333
OldInitializingDecl(Ctx->InitializingDecl) {
3434
Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD);
@@ -1794,6 +1794,8 @@ bool Compiler<Emitter>::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
17941794

17951795
if (!this->visitArrayElemInit(I, SubExpr))
17961796
return false;
1797+
if (!BS.destroyLocals())
1798+
return false;
17971799
}
17981800
return true;
17991801
}
@@ -2204,7 +2206,7 @@ bool Compiler<Emitter>::VisitCompoundAssignOperator(
22042206

22052207
template <class Emitter>
22062208
bool Compiler<Emitter>::VisitExprWithCleanups(const ExprWithCleanups *E) {
2207-
ExprScope<Emitter> ES(this);
2209+
LocalScope<Emitter> ES(this);
22082210
const Expr *SubExpr = E->getSubExpr();
22092211

22102212
assert(E->getNumObjects() == 0 && "TODO: Implement cleanups");
@@ -3080,7 +3082,7 @@ bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) {
30803082
return false;
30813083
}
30823084

3083-
return true;
3085+
return BS.destroyLocals();
30843086
}
30853087

30863088
template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
@@ -3425,7 +3427,7 @@ const Function *Compiler<Emitter>::getFunction(const FunctionDecl *FD) {
34253427
}
34263428

34273429
template <class Emitter> bool Compiler<Emitter>::visitExpr(const Expr *E) {
3428-
ExprScope<Emitter> RootScope(this);
3430+
LocalScope<Emitter> RootScope(this);
34293431
// Void expressions.
34303432
if (E->getType()->isVoidType()) {
34313433
if (!visit(E))
@@ -3462,40 +3464,52 @@ template <class Emitter> bool Compiler<Emitter>::visitExpr(const Expr *E) {
34623464
return false;
34633465
}
34643466

3465-
/// Toplevel visitDecl().
3467+
template <class Emitter>
3468+
VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD) {
3469+
3470+
auto R = this->visitVarDecl(VD, /*Toplevel=*/true);
3471+
3472+
if (R.notCreated())
3473+
return R;
3474+
3475+
if (R)
3476+
return true;
3477+
3478+
if (!R && Context::shouldBeGloballyIndexed(VD)) {
3479+
if (auto GlobalIndex = P.getGlobal(VD)) {
3480+
Block *GlobalBlock = P.getGlobal(*GlobalIndex);
3481+
GlobalInlineDescriptor &GD =
3482+
*reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
3483+
3484+
GD.InitState = GlobalInitState::InitializerFailed;
3485+
GlobalBlock->invokeDtor();
3486+
}
3487+
}
3488+
3489+
return R;
3490+
}
3491+
3492+
/// Toplevel visitDeclAndReturn().
34663493
/// We get here from evaluateAsInitializer().
34673494
/// We need to evaluate the initializer and return its value.
34683495
template <class Emitter>
3469-
bool Compiler<Emitter>::visitDecl(const VarDecl *VD, bool ConstantContext) {
3470-
assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl");
3471-
3496+
bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
3497+
bool ConstantContext) {
34723498
std::optional<PrimType> VarT = classify(VD->getType());
34733499

34743500
// We only create variables if we're evaluating in a constant context.
34753501
// Otherwise, just evaluate the initializer and return it.
34763502
if (!ConstantContext) {
3477-
DeclScope<Emitter> LocalScope(this, VD);
3503+
DeclScope<Emitter> LS(this, VD);
34783504
if (!this->visit(VD->getAnyInitializer()))
34793505
return false;
3480-
return this->emitRet(VarT.value_or(PT_Ptr), VD);
3481-
}
3482-
3483-
// If we've seen the global variable already and the initializer failed,
3484-
// just return false immediately.
3485-
if (std::optional<unsigned> Index = P.getGlobal(VD)) {
3486-
const Pointer &Ptr = P.getPtrGlobal(*Index);
3487-
const GlobalInlineDescriptor &GD =
3488-
*reinterpret_cast<const GlobalInlineDescriptor *>(
3489-
Ptr.block()->rawData());
3490-
if (GD.InitState == GlobalInitState::InitializerFailed)
3491-
return false;
3506+
return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals();
34923507
}
34933508

3494-
// Create and initialize the variable.
3509+
LocalScope<Emitter> VDScope(this, VD);
34953510
if (!this->visitVarDecl(VD, /*Toplevel=*/true))
34963511
return false;
34973512

3498-
// Get a pointer to the variable
34993513
if (Context::shouldBeGloballyIndexed(VD)) {
35003514
auto GlobalIndex = P.getGlobal(VD);
35013515
assert(GlobalIndex); // visitVarDecl() didn't return false.
@@ -3535,7 +3549,7 @@ bool Compiler<Emitter>::visitDecl(const VarDecl *VD, bool ConstantContext) {
35353549
return false;
35363550
}
35373551

3538-
return true;
3552+
return VDScope.destroyLocals();
35393553
}
35403554

35413555
template <class Emitter>
@@ -3552,12 +3566,12 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve
35523566
const Expr *Init = VD->getInit();
35533567
std::optional<PrimType> VarT = classify(VD->getType());
35543568

3555-
auto checkDecl = [&]() -> bool {
3556-
bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
3557-
return !NeedsOp || this->emitCheckDecl(VD, VD);
3558-
};
3559-
35603569
if (Context::shouldBeGloballyIndexed(VD)) {
3570+
auto checkDecl = [&]() -> bool {
3571+
bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
3572+
return !NeedsOp || this->emitCheckDecl(VD, VD);
3573+
};
3574+
35613575
auto initGlobal = [&](unsigned GlobalIndex) -> bool {
35623576
assert(Init);
35633577
DeclScope<Emitter> LocalScope(this, VD);
@@ -3589,26 +3603,34 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve
35893603

35903604
return !Init || (checkDecl() && initGlobal(*GlobalIndex));
35913605
} else {
3592-
VariableScope<Emitter> LocalScope(this, VD);
35933606
InitLinkScope<Emitter> ILS(this, InitLink::Decl(VD));
35943607

35953608
if (VarT) {
35963609
unsigned Offset = this->allocateLocalPrimitive(
35973610
VD, *VarT, VD->getType().isConstQualified());
35983611
if (Init) {
3599-
// Compile the initializer in its own scope.
3600-
ExprScope<Emitter> Scope(this);
3601-
if (!this->visit(Init))
3602-
return false;
3603-
3604-
return this->emitSetLocal(*VarT, Offset, VD);
3612+
// If this is a toplevel declaration, create a scope for the
3613+
// initializer.
3614+
if (Toplevel) {
3615+
LocalScope<Emitter> Scope(this);
3616+
if (!this->visit(Init))
3617+
return false;
3618+
return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
3619+
} else {
3620+
if (!this->visit(Init))
3621+
return false;
3622+
return this->emitSetLocal(*VarT, Offset, VD);
3623+
}
36053624
}
36063625
} else {
3607-
if (std::optional<unsigned> Offset = this->allocateLocal(VD))
3608-
return !Init || this->visitLocalInitializer(Init, *Offset);
3626+
if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
3627+
if (!Init)
3628+
return true;
3629+
3630+
return this->visitLocalInitializer(Init, *Offset);
3631+
}
36093632
return false;
36103633
}
3611-
36123634
return true;
36133635
}
36143636

@@ -4074,7 +4096,7 @@ bool Compiler<Emitter>::visitCompoundStmt(const CompoundStmt *S) {
40744096
for (const auto *InnerStmt : S->body())
40754097
if (!visitStmt(InnerStmt))
40764098
return false;
4077-
return true;
4099+
return Scope.destroyLocals();
40784100
}
40794101

40804102
template <class Emitter>
@@ -4100,7 +4122,7 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
41004122
return this->emitUnsupported(RS);
41014123

41024124
if (const Expr *RE = RS->getRetValue()) {
4103-
ExprScope<Emitter> RetScope(this);
4125+
LocalScope<Emitter> RetScope(this);
41044126
if (ReturnType) {
41054127
// Primitive types are simply returned.
41064128
if (!this->visit(RE))
@@ -4170,7 +4192,7 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
41704192
this->emitLabel(LabelEnd);
41714193
}
41724194

4173-
return true;
4195+
return IfScope.destroyLocals();
41744196
}
41754197

41764198
template <class Emitter>
@@ -4636,6 +4658,9 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
46364658
if (!this->emitPopPtr(InitExpr))
46374659
return false;
46384660
}
4661+
4662+
if (!Scope.destroyLocals())
4663+
return false;
46394664
}
46404665
}
46414666

@@ -5010,6 +5035,18 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
50105035
}
50115036
}
50125037

5038+
// In case we need to re-visit a declaration.
5039+
auto revisit = [&](const VarDecl *VD) -> bool {
5040+
auto VarState = this->visitDecl(VD);
5041+
5042+
if (VarState.notCreated())
5043+
return true;
5044+
if (!VarState)
5045+
return false;
5046+
// Retry.
5047+
return this->visitDeclRef(D, E);
5048+
};
5049+
50135050
// Handle lambda captures.
50145051
if (auto It = this->LambdaCaptures.find(D);
50155052
It != this->LambdaCaptures.end()) {
@@ -5020,12 +5057,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
50205057
return this->emitGetPtrThisField(Offset, E);
50215058
} else if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
50225059
DRE && DRE->refersToEnclosingVariableOrCapture()) {
5023-
if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture()) {
5024-
if (!this->visitVarDecl(cast<VarDecl>(D)))
5025-
return false;
5026-
// Retry.
5027-
return this->visitDeclRef(D, E);
5028-
}
5060+
if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture())
5061+
return revisit(VD);
50295062
}
50305063

50315064
if (D != InitializingDecl) {
@@ -5044,28 +5077,14 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
50445077
// Visit local const variables like normal.
50455078
if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||
50465079
VD->isStaticDataMember()) &&
5047-
typeShouldBeVisited(VD->getType())) {
5048-
auto VarState = this->visitVarDecl(VD, true);
5049-
if (VarState.notCreated())
5050-
return true;
5051-
if (!VarState)
5052-
return false;
5053-
// Retry.
5054-
return this->visitDeclRef(VD, E);
5055-
}
5080+
typeShouldBeVisited(VD->getType()))
5081+
return revisit(VD);
50565082
}
50575083
} else {
50585084
if (const auto *VD = dyn_cast<VarDecl>(D);
50595085
VD && VD->getAnyInitializer() &&
5060-
VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak()) {
5061-
auto VarState = this->visitVarDecl(VD, true);
5062-
if (VarState.notCreated())
5063-
return true;
5064-
if (!VarState)
5065-
return false;
5066-
// Retry.
5067-
return this->visitDeclRef(VD, E);
5068-
}
5086+
VD->getType().isConstant(Ctx.getASTContext()) && !VD->isWeak())
5087+
return revisit(VD);
50695088
}
50705089
}
50715090

clang/lib/AST/Interp/Compiler.h

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,10 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
212212
protected:
213213
bool visitStmt(const Stmt *S);
214214
bool visitExpr(const Expr *E) override;
215-
bool visitDecl(const VarDecl *VD, bool ConstantContext) override;
216215
bool visitFunc(const FunctionDecl *F) override;
217216

217+
bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override;
218+
218219
protected:
219220
/// Emits scope cleanup instructions.
220221
void emitCleanup();
@@ -267,6 +268,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
267268
bool delegate(const Expr *E);
268269
/// Creates and initializes a variable from the given decl.
269270
VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel = false);
271+
VarCreationState visitDecl(const VarDecl *VD);
270272
/// Visit an APValue.
271273
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E);
272274
bool visitAPValueInitializer(const APValue &Val, const Expr *E);
@@ -496,6 +498,8 @@ template <class Emitter> class VariableScope {
496498
template <class Emitter> class LocalScope : public VariableScope<Emitter> {
497499
public:
498500
LocalScope(Compiler<Emitter> *Ctx) : VariableScope<Emitter>(Ctx, nullptr) {}
501+
LocalScope(Compiler<Emitter> *Ctx, const ValueDecl *VD)
502+
: VariableScope<Emitter>(Ctx, VD) {}
499503

500504
/// Emit a Destroy op for this scope.
501505
~LocalScope() override {
@@ -585,20 +589,10 @@ template <class Emitter> class DestructorScope final {
585589
LocalScope<Emitter> &OtherScope;
586590
};
587591

588-
/// Like a regular LocalScope, except that the destructors of all local
589-
/// variables are automatically emitted when the AutoScope is destroyed.
590-
template <class Emitter> class AutoScope : public LocalScope<Emitter> {
591-
public:
592-
AutoScope(Compiler<Emitter> *Ctx) : LocalScope<Emitter>(Ctx), DS(*this) {}
593-
594-
private:
595-
DestructorScope<Emitter> DS;
596-
};
597-
598592
/// Scope for storage declared in a compound statement.
599-
template <class Emitter> class BlockScope final : public AutoScope<Emitter> {
593+
template <class Emitter> class BlockScope final : public LocalScope<Emitter> {
600594
public:
601-
BlockScope(Compiler<Emitter> *Ctx) : AutoScope<Emitter>(Ctx) {}
595+
BlockScope(Compiler<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {}
602596

603597
void addExtended(const Scope::Local &Local) override {
604598
// If we to this point, just add the variable as a normal local
@@ -608,11 +602,6 @@ template <class Emitter> class BlockScope final : public AutoScope<Emitter> {
608602
}
609603
};
610604

611-
template <class Emitter> class ExprScope final : public AutoScope<Emitter> {
612-
public:
613-
ExprScope(Compiler<Emitter> *Ctx) : AutoScope<Emitter>(Ctx) {}
614-
};
615-
616605
template <class Emitter> class ArrayIndexScope final {
617606
public:
618607
ArrayIndexScope(Compiler<Emitter> *Ctx, uint64_t Index) : Ctx(Ctx) {

0 commit comments

Comments
 (0)