[clang] de3a3cb - [clang][Interp] Fix compound assign operator types

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 25 01:12:44 PST 2023


Author: Timm Bäder
Date: 2023-01-25T10:12:26+01:00
New Revision: de3a3cb987f11075a62680c001d3cadd0a1d1397

URL: https://github.com/llvm/llvm-project/commit/de3a3cb987f11075a62680c001d3cadd0a1d1397
DIFF: https://github.com/llvm/llvm-project/commit/de3a3cb987f11075a62680c001d3cadd0a1d1397.diff

LOG: [clang][Interp] Fix compound assign operator types

Just like we do (or will do) for floating types, we need to take into
acocunt that the LHSComputationType, ResultType and type of the
expression (what we ultimately store) might be different.

Do this by emitting cast ops before and after doing the computation.

This fixes the test failures introduced by
490e8214fca48824beda8b508d6d6bbbf3d8d9a7 on big endian machines.

Differential Revision: https://reviews.llvm.org/D142328

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 615dbdefefbe..a777768061c4 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -498,10 +498,13 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
     const CompoundAssignOperator *E) {
   const Expr *LHS = E->getLHS();
   const Expr *RHS = E->getRHS();
-  std::optional<PrimType> LT = classify(E->getLHS()->getType());
-  std::optional<PrimType> RT = classify(E->getRHS()->getType());
+  std::optional<PrimType> LHSComputationT =
+      classify(E->getComputationLHSType());
+  std::optional<PrimType> LT = classify(LHS->getType());
+  std::optional<PrimType> RT = classify(E->getComputationResultType());
+  std::optional<PrimType> ResultT = classify(E->getType());
 
-  if (!LT || !RT)
+  if (!LT || !RT || !ResultT || !LHSComputationT)
     return false;
 
   assert(!E->getType()->isPointerType() &&
@@ -512,29 +515,36 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
     return false;
   if (!this->emitLoad(*LT, E))
     return false;
+  // If necessary, cast LHS to its computation type.
+  if (*LT != *LHSComputationT) {
+    if (!this->emitCast(*LT, *LHSComputationT, E))
+      return false;
+  }
+
   if (!visit(RHS))
     return false;
 
   // Perform operation.
   switch (E->getOpcode()) {
   case BO_AddAssign:
-    if (!this->emitAdd(*LT, E))
+    if (!this->emitAdd(*LHSComputationT, E))
       return false;
     break;
   case BO_SubAssign:
-    if (!this->emitSub(*LT, E))
+    if (!this->emitSub(*LHSComputationT, E))
       return false;
     break;
 
   case BO_MulAssign:
   case BO_DivAssign:
   case BO_RemAssign:
+
   case BO_ShlAssign:
-    if (!this->emitShl(*LT, *RT, E))
+    if (!this->emitShl(*LHSComputationT, *RT, E))
       return false;
     break;
   case BO_ShrAssign:
-    if (!this->emitShr(*LT, *RT, E))
+    if (!this->emitShr(*LHSComputationT, *RT, E))
       return false;
     break;
   case BO_AndAssign:
@@ -544,10 +554,16 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
     llvm_unreachable("Unimplemented compound assign operator");
   }
 
+  // And now cast from LHSComputationT to ResultT.
+  if (*ResultT != *LHSComputationT) {
+    if (!this->emitCast(*LHSComputationT, *ResultT, E))
+      return false;
+  }
+
   // And store the result in LHS.
   if (DiscardResult)
-    return this->emitStorePop(*LT, E);
-  return this->emitStore(*LT, E);
+    return this->emitStorePop(*ResultT, E);
+  return this->emitStore(*ResultT, E);
 }
 
 template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {


        


More information about the cfe-commits mailing list