summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Interp/ByteCodeExprGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Interp/ByteCodeExprGen.cpp')
-rw-r--r--clang/lib/AST/Interp/ByteCodeExprGen.cpp36
1 files changed, 26 insertions, 10 deletions
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 0dd645990d1d..86304a54473c 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3138,16 +3138,17 @@ bool ByteCodeExprGen<Emitter>::VisitComplexUnaryOperator(
return this->discard(SubExpr);
std::optional<PrimType> ResT = classify(E);
+ auto prepareResult = [=]() -> bool {
+ if (!ResT && !Initializing) {
+ std::optional<unsigned> LocalIndex =
+ allocateLocal(SubExpr, /*IsExtended=*/false);
+ if (!LocalIndex)
+ return false;
+ return this->emitGetPtrLocal(*LocalIndex, E);
+ }
- // Prepare storage for result.
- if (!ResT && !Initializing) {
- std::optional<unsigned> LocalIndex =
- allocateLocal(SubExpr, /*IsExtended=*/false);
- if (!LocalIndex)
- return false;
- if (!this->emitGetPtrLocal(*LocalIndex, E))
- return false;
- }
+ return true;
+ };
// The offset of the temporary, if we created one.
unsigned SubExprOffset = ~0u;
@@ -3167,6 +3168,8 @@ bool ByteCodeExprGen<Emitter>::VisitComplexUnaryOperator(
switch (E->getOpcode()) {
case UO_Minus:
+ if (!prepareResult())
+ return false;
if (!createTemp())
return false;
for (unsigned I = 0; I != 2; ++I) {
@@ -3179,9 +3182,22 @@ bool ByteCodeExprGen<Emitter>::VisitComplexUnaryOperator(
}
break;
- case UO_AddrOf:
+ case UO_Plus: // +x
+ case UO_AddrOf: // &x
+ case UO_Deref: // *x
return this->delegate(SubExpr);
+ case UO_LNot:
+ if (!this->visit(SubExpr))
+ return false;
+ if (!this->emitComplexBoolCast(SubExpr))
+ return false;
+ if (!this->emitInvBool(E))
+ return false;
+ if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
+ return this->emitCast(PT_Bool, ET, E);
+ return true;
+
case UO_Real:
return this->emitComplexReal(SubExpr);