Skip to content

Commit 562f061

Browse files
committed
[clang][Interp] Load result of pre-inc/dec operation if necessary
This can happen in C.
1 parent ff3523f commit 562f061

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3211,15 +3211,20 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
32113211
return false;
32123212
if (!this->emitAddf(getRoundingMode(E), E))
32133213
return false;
3214-
return this->emitStoreFloat(E);
3214+
if (!this->emitStoreFloat(E))
3215+
return false;
3216+
} else {
3217+
assert(isIntegralType(*T));
3218+
if (!this->emitLoad(*T, E))
3219+
return false;
3220+
if (!this->emitConst(1, E))
3221+
return false;
3222+
if (!this->emitAdd(*T, E))
3223+
return false;
3224+
if (!this->emitStore(*T, E))
3225+
return false;
32153226
}
3216-
if (!this->emitLoad(*T, E))
3217-
return false;
3218-
if (!this->emitConst(1, E))
3219-
return false;
3220-
if (!this->emitAdd(*T, E))
3221-
return false;
3222-
return this->emitStore(*T, E);
3227+
return E->isGLValue() || this->emitLoadPop(*T, E);
32233228
}
32243229
case UO_PreDec: { // --x
32253230
if (!this->visit(SubExpr))
@@ -3250,15 +3255,20 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
32503255
return false;
32513256
if (!this->emitSubf(getRoundingMode(E), E))
32523257
return false;
3253-
return this->emitStoreFloat(E);
3258+
if (!this->emitStoreFloat(E))
3259+
return false;
3260+
} else {
3261+
assert(isIntegralType(*T));
3262+
if (!this->emitLoad(*T, E))
3263+
return false;
3264+
if (!this->emitConst(1, E))
3265+
return false;
3266+
if (!this->emitSub(*T, E))
3267+
return false;
3268+
if (!this->emitStore(*T, E))
3269+
return false;
32543270
}
3255-
if (!this->emitLoad(*T, E))
3256-
return false;
3257-
if (!this->emitConst(1, E))
3258-
return false;
3259-
if (!this->emitSub(*T, E))
3260-
return false;
3261-
return this->emitStore(*T, E);
3271+
return E->isGLValue() || this->emitLoadPop(*T, E);
32623272
}
32633273
case UO_LNot: // !x
32643274
if (DiscardResult)

clang/test/AST/Interp/c.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,15 @@ _Static_assert(funcp == (void*)0, ""); // all-error {{failed due to requirement
233233
// pedantic-warning {{expression is not an integer constant expression}}
234234
_Static_assert(funcp == (void*)123, ""); // pedantic-warning {{equality comparison between function pointer and void pointer}} \
235235
// pedantic-warning {{expression is not an integer constant expression}}
236+
237+
void unaryops(void) {
238+
(void)(++(struct x {unsigned x;}){3}.x);
239+
(void)(--(struct y {unsigned x;}){3}.x);
240+
(void)(++(struct z {float x;}){3}.x);
241+
(void)(--(struct w {float x;}){3}.x);
242+
243+
(void)((struct xx {unsigned x;}){3}.x++);
244+
(void)((struct yy {unsigned x;}){3}.x--);
245+
(void)((struct zz {float x;}){3}.x++);
246+
(void)((struct ww {float x;}){3}.x--);
247+
}

0 commit comments

Comments
 (0)