[clang] [clang][Interp] Fix assignment eval order (PR #101834)

via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 3 08:28:25 PDT 2024


https://github.com/cIamor created https://github.com/llvm/llvm-project/pull/101834

RHS first

>From ddb379384065566c7b89de29f8084b172d885f52 Mon Sep 17 00:00:00 2001
From: layta <nmiop at compiler.town>
Date: Sat, 3 Aug 2024 16:28:10 +0100
Subject: [PATCH] [clang][Interp] Fix assignment eval order

RHS first
---
 clang/lib/AST/Interp/Compiler.cpp | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index ada22b569b2b0..d9db1c788314c 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -733,8 +733,8 @@ bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
   }
 
   // Typecheck the args.
-  std::optional<PrimType> LT = classify(LHS->getType());
-  std::optional<PrimType> RT = classify(RHS->getType());
+  std::optional<PrimType> LT = classify(LHS);
+  std::optional<PrimType> RT = classify(RHS);
   std::optional<PrimType> T = classify(BO->getType());
 
   // Special case for C++'s three-way/spaceship operator <=>, which
@@ -769,8 +769,16 @@ bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
       return this->VisitPointerArithBinOp(BO);
   }
 
-  if (!visit(LHS) || !visit(RHS))
-    return false;
+  // Assignmentes require us to evalute the RHS first.
+  if (BO->getOpcode() == BO_Assign) {
+    if (!visit(RHS) || !visit(LHS))
+      return false;
+    if (!this->emitFlip(*LT, *RT, BO))
+      return false;
+  } else {
+    if (!visit(LHS) || !visit(RHS))
+      return false;
+  }
 
   // For languages such as C, cast the result of one
   // of our comparision opcodes to T (which is usually int).



More information about the cfe-commits mailing list