Author: Timm Baeder
Date: 2025-04-27T20:10:41+02:00
New Revision: 7904298c794913489202467599c7eacc860dd6d7

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

LOG: [clang][bytecode] Don't ignore discarded ArraySubScriptExprs (#137526)

We need to evaluate them since the index might be out of bounds.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp
    clang/test/AST/ByteCode/arrays.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 58fe2c184cf3f..a9610835c81e6 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1695,9 +1695,6 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const 
ArraySubscriptExpr *E) {
   const Expr *Index = E->getIdx();
   const Expr *Base = E->getBase();
 
-  if (DiscardResult)
-    return this->discard(LHS) && this->discard(RHS);
-
   // C++17's rules require us to evaluate the LHS first, regardless of which
   // side is the base.
   bool Success = true;
@@ -1728,7 +1725,11 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const 
ArraySubscriptExpr *E) {
       return false;
   }
 
-  return this->emitArrayElemPtrPop(*IndexT, E);
+  if (!this->emitArrayElemPtrPop(*IndexT, E))
+    return false;
+  if (DiscardResult)
+    return this->emitPopPtr(E);
+  return true;
 }
 
 template <class Emitter>

diff  --git a/clang/test/AST/ByteCode/arrays.cpp 
b/clang/test/AST/ByteCode/arrays.cpp
index 934c3a3e7aff1..2dd51c2fa6711 100644
--- a/clang/test/AST/ByteCode/arrays.cpp
+++ b/clang/test/AST/ByteCode/arrays.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter 
-verify=expected,both %s
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 
-verify=expected,both %s
-// RUN: %clang_cc1 -verify=ref,both %s
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter 
-verify=expected,both            %s
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter 
-verify=expected,both -std=c++20 %s
+// RUN: %clang_cc1 -verify=ref,both            %s
 // RUN: %clang_cc1 -verify=ref,both -std=c++20 %s
 
 constexpr int m = 3;
@@ -771,3 +771,11 @@ namespace OnePastEndDiag {
   constexpr int k = a(foo + 2); // both-error {{must be initialized by a 
constant expression}} \
                                 // both-note {{in call to 'a(&foo[2])'}}
 }
+
+namespace DiscardedSubScriptExpr {
+  constexpr bool foo() { // both-error {{never produces a constant expression}}
+    int a[2] = {};
+    (void)a[3]; // both-note {{cannot refer to element 3 of array of 2 
elements in a constant expression}}
+    return true;
+  }
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to