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--); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits