aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/EvalEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/EvalEmitter.cpp')
-rw-r--r--clang/lib/AST/ByteCode/EvalEmitter.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index 81ebc56..976b7c0 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -53,6 +53,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
bool CheckFullyInitialized) {
this->CheckFullyInitialized = CheckFullyInitialized;
S.EvaluatingDecl = VD;
+ S.setEvalLocation(VD->getLocation());
EvalResult.setSource(VD);
if (const Expr *Init = VD->getAnyInitializer()) {
@@ -233,6 +234,14 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
return false;
}
} else {
+ // If this is pointing to a local variable, just return
+ // the result, even if the pointer is dead.
+ // This will later be diagnosed by CheckLValueConstantExpression.
+ if (Ptr.isBlockPointer() && !Ptr.block()->isStatic()) {
+ EvalResult.setValue(Ptr.toAPValue(Ctx.getASTContext()));
+ return true;
+ }
+
if (!Ptr.isLive() && !Ptr.isTemporary())
return false;
@@ -282,6 +291,10 @@ bool EvalEmitter::emitGetLocal(uint32_t I, const SourceInfo &Info) {
using T = typename PrimConv<OpType>::T;
Block *B = getLocal(I);
+
+ if (!CheckLocalLoad(S, OpPC, Pointer(B)))
+ return false;
+
S.Stk.push<T>(*reinterpret_cast<T *>(B->data()));
return true;
}