Skip to content

Commit 91ebd01

Browse files
committed
[clang][Interp] Remove dereference()
This function tried to be smart about the dereferenced value, but it ended up hurting more than it helped. At least in the current state, where we still try get the correct output. I might add something similar back later.
1 parent 61bc5f6 commit 91ebd01

File tree

3 files changed

+18
-176
lines changed

3 files changed

+18
-176
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 12 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,15 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
8181
if (DiscardResult)
8282
return this->discard(SubExpr);
8383

84-
return dereference(
85-
SubExpr, DerefKind::Read,
86-
[](PrimType) {
87-
// Value loaded - nothing to do here.
88-
return true;
89-
},
90-
[this, CE](PrimType T) {
91-
// Pointer on stack - dereference it.
92-
return this->emitLoadPop(T, CE);
93-
});
84+
if (SubExpr->getType()->isAnyComplexType())
85+
return this->delegate(SubExpr);
86+
87+
if (!this->visit(SubExpr))
88+
return false;
89+
90+
if (std::optional<PrimType> SubExprT = classify(SubExpr->getType()))
91+
return this->emitLoadPop(*SubExprT, CE);
92+
return false;
9493
}
9594

9695
case CK_UncheckedDerivedToBase:
@@ -2326,134 +2325,6 @@ bool ByteCodeExprGen<Emitter>::visitZeroRecordInitializer(const Record *R,
23262325
return true;
23272326
}
23282327

2329-
template <class Emitter>
2330-
bool ByteCodeExprGen<Emitter>::dereference(
2331-
const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
2332-
llvm::function_ref<bool(PrimType)> Indirect) {
2333-
if (std::optional<PrimType> T = classify(LV->getType())) {
2334-
if (!LV->refersToBitField()) {
2335-
// Only primitive, non bit-field types can be dereferenced directly.
2336-
if (const auto *DE = dyn_cast<DeclRefExpr>(LV)) {
2337-
if (!DE->getDecl()->getType()->isReferenceType()) {
2338-
if (const auto *PD = dyn_cast<ParmVarDecl>(DE->getDecl()))
2339-
return dereferenceParam(LV, *T, PD, AK, Direct, Indirect);
2340-
if (const auto *VD = dyn_cast<VarDecl>(DE->getDecl()))
2341-
return dereferenceVar(LV, *T, VD, AK, Direct, Indirect);
2342-
}
2343-
}
2344-
}
2345-
2346-
if (!visit(LV))
2347-
return false;
2348-
return Indirect(*T);
2349-
}
2350-
2351-
if (LV->getType()->isAnyComplexType())
2352-
return this->delegate(LV);
2353-
2354-
return false;
2355-
}
2356-
2357-
template <class Emitter>
2358-
bool ByteCodeExprGen<Emitter>::dereferenceParam(
2359-
const Expr *LV, PrimType T, const ParmVarDecl *PD, DerefKind AK,
2360-
llvm::function_ref<bool(PrimType)> Direct,
2361-
llvm::function_ref<bool(PrimType)> Indirect) {
2362-
if (auto It = this->Params.find(PD); It != this->Params.end()) {
2363-
unsigned Idx = It->second.Offset;
2364-
switch (AK) {
2365-
case DerefKind::Read:
2366-
return DiscardResult ? true : this->emitGetParam(T, Idx, LV);
2367-
2368-
case DerefKind::Write:
2369-
if (!Direct(T))
2370-
return false;
2371-
if (!this->emitSetParam(T, Idx, LV))
2372-
return false;
2373-
return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
2374-
2375-
case DerefKind::ReadWrite:
2376-
if (!this->emitGetParam(T, Idx, LV))
2377-
return false;
2378-
if (!Direct(T))
2379-
return false;
2380-
if (!this->emitSetParam(T, Idx, LV))
2381-
return false;
2382-
return DiscardResult ? true : this->emitGetPtrParam(Idx, LV);
2383-
}
2384-
return true;
2385-
}
2386-
2387-
// If the param is a pointer, we can dereference a dummy value.
2388-
if (!DiscardResult && T == PT_Ptr && AK == DerefKind::Read) {
2389-
if (auto Idx = P.getOrCreateDummy(PD))
2390-
return this->emitGetPtrGlobal(*Idx, PD);
2391-
return false;
2392-
}
2393-
2394-
// Value cannot be produced - try to emit pointer and do stuff with it.
2395-
return visit(LV) && Indirect(T);
2396-
}
2397-
2398-
template <class Emitter>
2399-
bool ByteCodeExprGen<Emitter>::dereferenceVar(
2400-
const Expr *LV, PrimType T, const VarDecl *VD, DerefKind AK,
2401-
llvm::function_ref<bool(PrimType)> Direct,
2402-
llvm::function_ref<bool(PrimType)> Indirect) {
2403-
auto It = Locals.find(VD);
2404-
if (It != Locals.end()) {
2405-
const auto &L = It->second;
2406-
switch (AK) {
2407-
case DerefKind::Read:
2408-
if (!this->emitGetLocal(T, L.Offset, LV))
2409-
return false;
2410-
return DiscardResult ? this->emitPop(T, LV) : true;
2411-
2412-
case DerefKind::Write:
2413-
if (!Direct(T))
2414-
return false;
2415-
if (!this->emitSetLocal(T, L.Offset, LV))
2416-
return false;
2417-
return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
2418-
2419-
case DerefKind::ReadWrite:
2420-
if (!this->emitGetLocal(T, L.Offset, LV))
2421-
return false;
2422-
if (!Direct(T))
2423-
return false;
2424-
if (!this->emitSetLocal(T, L.Offset, LV))
2425-
return false;
2426-
return DiscardResult ? true : this->emitGetPtrLocal(L.Offset, LV);
2427-
}
2428-
} else if (auto Idx = P.getGlobal(VD)) {
2429-
switch (AK) {
2430-
case DerefKind::Read:
2431-
if (!this->emitGetGlobal(T, *Idx, LV))
2432-
return false;
2433-
return DiscardResult ? this->emitPop(T, LV) : true;
2434-
2435-
case DerefKind::Write:
2436-
if (!Direct(T))
2437-
return false;
2438-
if (!this->emitSetGlobal(T, *Idx, LV))
2439-
return false;
2440-
return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
2441-
2442-
case DerefKind::ReadWrite:
2443-
if (!this->emitGetGlobal(T, *Idx, LV))
2444-
return false;
2445-
if (!Direct(T))
2446-
return false;
2447-
if (!this->emitSetGlobal(T, *Idx, LV))
2448-
return false;
2449-
return DiscardResult ? true : this->emitGetPtrGlobal(*Idx, LV);
2450-
}
2451-
}
2452-
2453-
// Value cannot be produced - try to emit pointer.
2454-
return visit(LV) && Indirect(T);
2455-
}
2456-
24572328
template <class Emitter>
24582329
template <typename T>
24592330
bool ByteCodeExprGen<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
@@ -3092,15 +2963,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
30922963
// We should already have a pointer when we get here.
30932964
return this->delegate(SubExpr);
30942965
case UO_Deref: // *x
3095-
return dereference(
3096-
SubExpr, DerefKind::Read,
3097-
[](PrimType) {
3098-
llvm_unreachable("Dereferencing requires a pointer");
3099-
return false;
3100-
},
3101-
[this, E](PrimType T) {
3102-
return DiscardResult ? this->emitPop(T, E) : true;
3103-
});
2966+
if (DiscardResult)
2967+
return this->discard(SubExpr);
2968+
return this->visit(SubExpr);
31042969
case UO_Not: // ~x
31052970
if (!this->visit(SubExpr))
31062971
return false;

clang/lib/AST/Interp/ByteCodeExprGen.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -236,29 +236,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
236236
bool visitZeroInitializer(PrimType T, QualType QT, const Expr *E);
237237
bool visitZeroRecordInitializer(const Record *R, const Expr *E);
238238

239-
enum class DerefKind {
240-
/// Value is read and pushed to stack.
241-
Read,
242-
/// Direct method generates a value which is written. Returns pointer.
243-
Write,
244-
/// Direct method receives the value, pushes mutated value. Returns pointer.
245-
ReadWrite,
246-
};
247-
248-
/// Method to directly load a value. If the value can be fetched directly,
249-
/// the direct handler is called. Otherwise, a pointer is left on the stack
250-
/// and the indirect handler is expected to operate on that.
251-
bool dereference(const Expr *LV, DerefKind AK,
252-
llvm::function_ref<bool(PrimType)> Direct,
253-
llvm::function_ref<bool(PrimType)> Indirect);
254-
bool dereferenceParam(const Expr *LV, PrimType T, const ParmVarDecl *PD,
255-
DerefKind AK,
256-
llvm::function_ref<bool(PrimType)> Direct,
257-
llvm::function_ref<bool(PrimType)> Indirect);
258-
bool dereferenceVar(const Expr *LV, PrimType T, const VarDecl *PD,
259-
DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
260-
llvm::function_ref<bool(PrimType)> Indirect);
261-
262239
/// Emits an APSInt constant.
263240
bool emitConst(const llvm::APSInt &Value, PrimType Ty, const Expr *E);
264241
bool emitConst(const llvm::APSInt &Value, const Expr *E);

clang/lib/AST/Interp/Interp.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -362,13 +362,13 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
362362
if (Ptr.isInitialized())
363363
return true;
364364

365+
if (const auto *VD = Ptr.getDeclDesc()->asVarDecl();
366+
VD && VD->hasGlobalStorage()) {
367+
const SourceInfo &Loc = S.Current->getSource(OpPC);
368+
S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
369+
S.Note(VD->getLocation(), diag::note_declared_at);
370+
}
365371
if (!S.checkingPotentialConstantExpression()) {
366-
if (const auto *VD = Ptr.getDeclDesc()->asVarDecl();
367-
VD && VD->hasGlobalStorage()) {
368-
const SourceInfo &Loc = S.Current->getSource(OpPC);
369-
S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
370-
S.Note(VD->getLocation(), diag::note_declared_at);
371-
}
372372
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_uninit)
373373
<< AK << /*uninitialized=*/true << S.Current->getRange(OpPC);
374374
}

0 commit comments

Comments
 (0)