[clang] [clang][bytecode] Fix compound assign operators for IntAP(S) (PR #169303)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 24 01:35:31 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/169303.diff
3 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+20-8)
- (modified) clang/lib/AST/ByteCode/Compiler.h (+2)
- (modified) clang/test/AST/ByteCode/intap.cpp (+40)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 958373ed94fe3..dd0b8e790d444 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2827,10 +2827,10 @@ bool Compiler<Emitter>::VisitCompoundAssignOperator(
return false;
if (!this->emitLoad(*LT, E))
return false;
- if (LT != LHSComputationT) {
- if (!this->emitCast(*LT, *LHSComputationT, E))
- return false;
- }
+ if (LT != LHSComputationT &&
+ !this->emitIntegralCast(*LT, *LHSComputationT, E->getComputationLHSType(),
+ E))
+ return false;
// Get the RHS value on the stack.
if (!this->emitGetLocal(*RT, TempOffset, E))
@@ -2883,10 +2883,9 @@ bool Compiler<Emitter>::VisitCompoundAssignOperator(
}
// And now cast from LHSComputationT to ResultT.
- if (ResultT != LHSComputationT) {
- if (!this->emitCast(*LHSComputationT, *ResultT, E))
- return false;
- }
+ if (ResultT != LHSComputationT &&
+ !this->emitIntegralCast(*LHSComputationT, *ResultT, E->getType(), E))
+ return false;
// And store the result in LHS.
if (DiscardResult) {
@@ -7243,6 +7242,19 @@ bool Compiler<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
return false;
}
+template <class Emitter>
+bool Compiler<Emitter>::emitIntegralCast(PrimType FromT, PrimType ToT,
+ QualType ToQT, const Expr *E) {
+ assert(FromT != ToT);
+
+ if (ToT == PT_IntAP)
+ return this->emitCastAP(FromT, Ctx.getBitWidth(ToQT), E);
+ if (ToT == PT_IntAPS)
+ return this->emitCastAPS(FromT, Ctx.getBitWidth(ToQT), E);
+
+ return this->emitCast(FromT, ToT, E);
+}
+
/// Emits __real(SubExpr)
template <class Emitter>
bool Compiler<Emitter>::emitComplexReal(const Expr *SubExpr) {
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index 6a9fe1e954530..54d39bbc25952 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -393,6 +393,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
}
bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E);
+ bool emitIntegralCast(PrimType FromT, PrimType ToT, QualType ToQT,
+ const Expr *E);
PrimType classifyComplexElementType(QualType T) const {
assert(T->isAnyComplexType());
diff --git a/clang/test/AST/ByteCode/intap.cpp b/clang/test/AST/ByteCode/intap.cpp
index 05ab319bf16df..efb60cb0abffe 100644
--- a/clang/test/AST/ByteCode/intap.cpp
+++ b/clang/test/AST/ByteCode/intap.cpp
@@ -305,6 +305,46 @@ namespace UnderlyingInt128 {
static_assert(foo() == 0, ""); // both-error {{not an integral constant expression}} \
// both-note {{in call to}}
}
+
+namespace CompoundAssignOperators {
+ constexpr unsigned __int128 foo() {
+ long b = 10;
+
+ b += (__int128)1;
+ b -= (__int128)1;
+ b *= (__int128)1;
+ b /= (__int128)1;
+
+ b += (unsigned __int128)1;
+ b -= (unsigned __int128)1;
+ b *= (unsigned __int128)1;
+ b /= (unsigned __int128)1;
+
+ __int128 i = 10;
+ i += (__int128)1;
+ i -= (__int128)1;
+ i *= (__int128)1;
+ i /= (__int128)1;
+ i += (unsigned __int128)1;
+ i -= (unsigned __int128)1;
+ i *= (unsigned __int128)1;
+ i /= (unsigned __int128)1;
+
+ unsigned __int128 i2 = 10;
+ i2 += (__int128)1;
+ i2 -= (__int128)1;
+ i2 *= (__int128)1;
+ i2 /= (__int128)1;
+ i2 += (unsigned __int128)1;
+ i2 -= (unsigned __int128)1;
+ i2 *= (unsigned __int128)1;
+ i2 /= (unsigned __int128)1;
+
+ return (int)b;
+ }
+ static_assert(foo() == 10);
+}
+
#endif
#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/169303
More information about the cfe-commits
mailing list