Skip to content

Commit cc8fa1e

Browse files
committed
[clang][Interp][NFC] Refactor lvalue-to-rvalue conversion code
Really perform the conversion always if the flag is set and don't make it dependent on whether we're checking the result for initialization.
1 parent 715a5d8 commit cc8fa1e

File tree

2 files changed

+20
-19
lines changed

2 files changed

+20
-19
lines changed

clang/lib/AST/Interp/EvalEmitter.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void EvalEmitter::cleanup() { S.cleanup(); }
4040
EvaluationResult EvalEmitter::interpretExpr(const Expr *E,
4141
bool ConvertResultToRValue) {
4242
S.setEvalLocation(E->getExprLoc());
43-
this->ConvertResultToRValue = ConvertResultToRValue;
43+
this->ConvertResultToRValue = ConvertResultToRValue && !isa<ConstantExpr>(E);
4444
this->CheckFullyInitialized = isa<ConstantExpr>(E);
4545
EvalResult.setSource(E);
4646

@@ -56,10 +56,14 @@ EvaluationResult EvalEmitter::interpretExpr(const Expr *E,
5656
EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
5757
bool CheckFullyInitialized) {
5858
this->CheckFullyInitialized = CheckFullyInitialized;
59-
this->ConvertResultToRValue =
60-
VD->getAnyInitializer() &&
61-
(VD->getAnyInitializer()->getType()->isAnyComplexType() ||
62-
VD->getAnyInitializer()->getType()->isVectorType());
59+
60+
if (const Expr *Init = VD->getAnyInitializer()) {
61+
QualType T = VD->getType();
62+
this->ConvertResultToRValue = !Init->isGLValue() && !T->isPointerType() &&
63+
!T->isObjCObjectPointerType();
64+
} else
65+
this->ConvertResultToRValue = false;
66+
6367
EvalResult.setSource(VD);
6468

6569
if (!this->visitDecl(VD) && EvalResult.empty())
@@ -138,6 +142,10 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
138142
return true;
139143

140144
const Pointer &Ptr = S.Stk.pop<Pointer>();
145+
146+
if (CheckFullyInitialized && !EvalResult.checkFullyInitialized(S, Ptr))
147+
return false;
148+
141149
// Implicitly convert lvalue to rvalue, if requested.
142150
if (ConvertResultToRValue) {
143151
if (std::optional<APValue> V = Ptr.toRValue(Ctx)) {
@@ -146,17 +154,7 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
146154
return false;
147155
}
148156
} else {
149-
if (CheckFullyInitialized) {
150-
if (!EvalResult.checkFullyInitialized(S, Ptr))
151-
return false;
152-
153-
std::optional<APValue> RValueResult = Ptr.toRValue(Ctx);
154-
if (!RValueResult)
155-
return false;
156-
EvalResult.setValue(*RValueResult);
157-
} else {
158-
EvalResult.setValue(Ptr.toAPValue());
159-
}
157+
EvalResult.setValue(Ptr.toAPValue());
160158
}
161159

162160
return true;

clang/lib/AST/Interp/EvaluationResult.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,12 @@ bool EvaluationResult::checkFullyInitialized(InterpState &S,
151151

152152
if (const Record *R = Ptr.getRecord())
153153
return CheckFieldsInitialized(S, InitLoc, Ptr, R);
154-
const auto *CAT =
155-
cast<ConstantArrayType>(Ptr.getType()->getAsArrayTypeUnsafe());
156-
return CheckArrayInitialized(S, InitLoc, Ptr, CAT);
154+
155+
if (const auto *CAT = dyn_cast_if_present<ConstantArrayType>(
156+
Ptr.getType()->getAsArrayTypeUnsafe()))
157+
return CheckArrayInitialized(S, InitLoc, Ptr, CAT);
158+
159+
return true;
157160
}
158161

159162
} // namespace interp

0 commit comments

Comments
 (0)