[clang] 562f061 - [clang][Interp] Load result of pre-inc/dec operation if necessary
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 17 23:30:24 PDT 2024
Author: Timm Bäder
Date: 2024-04-18T08:30:09+02:00
New Revision: 562f061e7e710543578875d33d64837abecc23d2
URL: https://github.com/llvm/llvm-project/commit/562f061e7e710543578875d33d64837abecc23d2
DIFF: https://github.com/llvm/llvm-project/commit/562f061e7e710543578875d33d64837abecc23d2.diff
LOG: [clang][Interp] Load result of pre-inc/dec operation if necessary
This can happen in C.
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/c.c
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 52e3efff2359d2..47cd32c2ab8673 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3211,15 +3211,20 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return false;
if (!this->emitAddf(getRoundingMode(E), E))
return false;
- return this->emitStoreFloat(E);
+ if (!this->emitStoreFloat(E))
+ return false;
+ } else {
+ assert(isIntegralType(*T));
+ if (!this->emitLoad(*T, E))
+ return false;
+ if (!this->emitConst(1, E))
+ return false;
+ if (!this->emitAdd(*T, E))
+ return false;
+ if (!this->emitStore(*T, E))
+ return false;
}
- if (!this->emitLoad(*T, E))
- return false;
- if (!this->emitConst(1, E))
- return false;
- if (!this->emitAdd(*T, E))
- return false;
- return this->emitStore(*T, E);
+ return E->isGLValue() || this->emitLoadPop(*T, E);
}
case UO_PreDec: { // --x
if (!this->visit(SubExpr))
@@ -3250,15 +3255,20 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return false;
if (!this->emitSubf(getRoundingMode(E), E))
return false;
- return this->emitStoreFloat(E);
+ if (!this->emitStoreFloat(E))
+ return false;
+ } else {
+ assert(isIntegralType(*T));
+ if (!this->emitLoad(*T, E))
+ return false;
+ if (!this->emitConst(1, E))
+ return false;
+ if (!this->emitSub(*T, E))
+ return false;
+ if (!this->emitStore(*T, E))
+ return false;
}
- if (!this->emitLoad(*T, E))
- return false;
- if (!this->emitConst(1, E))
- return false;
- if (!this->emitSub(*T, E))
- return false;
- return this->emitStore(*T, E);
+ return E->isGLValue() || this->emitLoadPop(*T, E);
}
case UO_LNot: // !x
if (DiscardResult)
diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index e0b18120fd2110..38df38d1ccfae6 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -233,3 +233,15 @@ _Static_assert(funcp == (void*)0, ""); // all-error {{failed due to requirement
// pedantic-warning {{expression is not an integer constant expression}}
_Static_assert(funcp == (void*)123, ""); // pedantic-warning {{equality comparison between function pointer and void pointer}} \
// pedantic-warning {{expression is not an integer constant expression}}
+
+void unaryops(void) {
+ (void)(++(struct x {unsigned x;}){3}.x);
+ (void)(--(struct y {unsigned x;}){3}.x);
+ (void)(++(struct z {float x;}){3}.x);
+ (void)(--(struct w {float x;}){3}.x);
+
+ (void)((struct xx {unsigned x;}){3}.x++);
+ (void)((struct yy {unsigned x;}){3}.x--);
+ (void)((struct zz {float x;}){3}.x++);
+ (void)((struct ww {float x;}){3}.x--);
+}
More information about the cfe-commits
mailing list