Skip to content

Commit d44d329

Browse files
authored
[clang][bytecode] Fix compound assign operators for IntAP(S) (#169303)
We didn't take `IntAP`/`IntAPS` into account when casting to and from the computation LHS type. This broke the `std/ranges/range.factories/range.iota.view/end.pass.cpp` test.
1 parent 74a62b1 commit d44d329

File tree

3 files changed

+62
-8
lines changed

3 files changed

+62
-8
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,10 +2827,10 @@ bool Compiler<Emitter>::VisitCompoundAssignOperator(
28272827
return false;
28282828
if (!this->emitLoad(*LT, E))
28292829
return false;
2830-
if (LT != LHSComputationT) {
2831-
if (!this->emitCast(*LT, *LHSComputationT, E))
2832-
return false;
2833-
}
2830+
if (LT != LHSComputationT &&
2831+
!this->emitIntegralCast(*LT, *LHSComputationT, E->getComputationLHSType(),
2832+
E))
2833+
return false;
28342834

28352835
// Get the RHS value on the stack.
28362836
if (!this->emitGetLocal(*RT, TempOffset, E))
@@ -2883,10 +2883,9 @@ bool Compiler<Emitter>::VisitCompoundAssignOperator(
28832883
}
28842884

28852885
// And now cast from LHSComputationT to ResultT.
2886-
if (ResultT != LHSComputationT) {
2887-
if (!this->emitCast(*LHSComputationT, *ResultT, E))
2888-
return false;
2889-
}
2886+
if (ResultT != LHSComputationT &&
2887+
!this->emitIntegralCast(*LHSComputationT, *ResultT, E->getType(), E))
2888+
return false;
28902889

28912890
// And store the result in LHS.
28922891
if (DiscardResult) {
@@ -7243,6 +7242,19 @@ bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
72437242
return false;
72447243
}
72457244

7245+
template <class Emitter>
7246+
bool Compiler<Emitter>::emitIntegralCast(PrimType FromT, PrimType ToT,
7247+
QualType ToQT, const Expr *E) {
7248+
assert(FromT != ToT);
7249+
7250+
if (ToT == PT_IntAP)
7251+
return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
7252+
if (ToT == PT_IntAPS)
7253+
return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
7254+
7255+
return this->emitCast(FromT, ToT, E);
7256+
}
7257+
72467258
/// Emits __real(SubExpr)
72477259
template <class Emitter>
72487260
bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
393393
}
394394

395395
bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E);
396+
bool emitIntegralCast(PrimType FromT, PrimType ToT, QualType ToQT,
397+
const Expr *E);
396398
PrimType classifyComplexElementType(QualType T) const {
397399
assert(T->isAnyComplexType());
398400

clang/test/AST/ByteCode/intap.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,46 @@ namespace UnderlyingInt128 {
305305
static_assert(foo() == 0, ""); // both-error {{not an integral constant expression}} \
306306
// both-note {{in call to}}
307307
}
308+
309+
namespace CompoundAssignOperators {
310+
constexpr unsigned __int128 foo() {
311+
long b = 10;
312+
313+
b += (__int128)1;
314+
b -= (__int128)1;
315+
b *= (__int128)1;
316+
b /= (__int128)1;
317+
318+
b += (unsigned __int128)1;
319+
b -= (unsigned __int128)1;
320+
b *= (unsigned __int128)1;
321+
b /= (unsigned __int128)1;
322+
323+
__int128 i = 10;
324+
i += (__int128)1;
325+
i -= (__int128)1;
326+
i *= (__int128)1;
327+
i /= (__int128)1;
328+
i += (unsigned __int128)1;
329+
i -= (unsigned __int128)1;
330+
i *= (unsigned __int128)1;
331+
i /= (unsigned __int128)1;
332+
333+
unsigned __int128 i2 = 10;
334+
i2 += (__int128)1;
335+
i2 -= (__int128)1;
336+
i2 *= (__int128)1;
337+
i2 /= (__int128)1;
338+
i2 += (unsigned __int128)1;
339+
i2 -= (unsigned __int128)1;
340+
i2 *= (unsigned __int128)1;
341+
i2 /= (unsigned __int128)1;
342+
343+
return (int)b;
344+
}
345+
static_assert(foo() == 10);
346+
}
347+
308348
#endif
309349

310350
#endif

0 commit comments

Comments
 (0)