https://github.com/dyung updated 
https://github.com/llvm/llvm-project/pull/209613

>From a81c82c64917d19824769f64c1ea2f76e4c8694e Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Tue, 14 Jul 2026 22:10:27 +0200
Subject: [PATCH] Revert "[Clang] Allow devirtualization involving array
 subscripts with constant indices when the pointee type is known [CWG1504]
 (#207540) (#209596)

It caused miscompiles, see discussion on the PR.

This reverts commit ee24ac00d874ce82eaf36431f9aeb2ad744bc3b8.

(cherry picked from commit 04aa50715cafa5f205b44bc88a6f721d296ec91c)
---
 clang/lib/AST/DeclCXX.cpp                     | 35 ----------------
 clang/test/CXX/drs/cwg15xx.cpp                | 19 ---------
 .../devirtualize-virtual-function-calls.cpp   | 42 +------------------
 clang/www/cxx_dr_status.html                  |  2 +-
 4 files changed, 3 insertions(+), 95 deletions(-)

diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index ef7e58536202b..0573cdf95952a 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2600,41 +2600,6 @@ CXXMethodDecl 
*CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
     }
   }
 
-  // By CWG1504 / C++11 [expr.add]p6, pointer arithmetic on a base pointer into
-  // an array of derived objects is undefined behavior when the element type 
and
-  // pointee type are not similar. This means we can devirtualize calls on
-  // objects accessed through array subscripts or pointer arithmetic with
-  // non-zero offsets, since the dynamic type must match the static type.
-  //
-  // A single object is considered to be an array of one element, so p[0]
-  // could still be a derived object, but p[N] for N != 0 cannot.
-  const Expr *Inner = Base->IgnoreParenImpCasts();
-  if (const auto *UO = dyn_cast<UnaryOperator>(Inner))
-    if (UO->getOpcode() == UO_Deref)
-      Inner = UO->getSubExpr()->IgnoreParenImpCasts();
-
-  // Handle p[N].f() (dot syntax with array subscript).
-  if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Inner)) {
-    Expr::EvalResult Result;
-    if (ASE->getIdx()->EvaluateAsInt(Result, getASTContext()) &&
-        !Result.Val.getInt().isZero())
-      return DevirtualizedMethod;
-  }
-
-  // Handle (p + N)->f() (arrow syntax with pointer arithmetic).
-  if (const auto *BO = dyn_cast<BinaryOperator>(Inner)) {
-    if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
-      // Identify the integer operand (the offset).
-      const Expr *IdxExpr = BO->getLHS()->getType()->isPointerType()
-                                ? BO->getRHS()
-                                : BO->getLHS();
-      Expr::EvalResult Result;
-      if (IdxExpr->EvaluateAsInt(Result, getASTContext()) &&
-          !Result.Val.getInt().isZero())
-        return DevirtualizedMethod;
-    }
-  }
-
   // We can't devirtualize the call.
   return nullptr;
 }
diff --git a/clang/test/CXX/drs/cwg15xx.cpp b/clang/test/CXX/drs/cwg15xx.cpp
index 53f262740eae2..5a9b80ed028c4 100644
--- a/clang/test/CXX/drs/cwg15xx.cpp
+++ b/clang/test/CXX/drs/cwg15xx.cpp
@@ -11,25 +11,6 @@
 // cxx98-error@-1 {{variadic macros are a C99 feature}}
 #endif
 
-namespace cwg1504 { // cwg1504: 23
-#if __cplusplus >= 201103L
-  // CWG1504: Pointer arithmetic after derived-base conversion
-  struct Base { int x; };
-  struct Derived : Base { int y; };
-  constexpr Derived arr[2] = {};
-
-  // Pointer arithmetic on a base pointer into a derived array is UB,
-  // and the constexpr evaluator must diagnose it.
-  constexpr int test(int n) {
-    return ((const Base*)arr)[n].x; // #cwg1504-x
-  }
-  constexpr int bad = test(1);
-  // since-cxx11-error@-1 {{constexpr variable 'bad' must be initialized by a 
constant expression}}
-  // since-cxx11-note@#cwg1504-x {{cannot access field of pointer past the end 
of object}}
-  // since-cxx11-note@-3 {{in call to 'test(1)'}}
-#endif
-} // namespace cwg1504
-
 namespace cwg1512 { // cwg1512: 4
   void f(char *p) {
     if (p > 0) {}
diff --git a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp 
b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
index 32a887e8fbcc9..b50881db63e05 100644
--- a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
+++ b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -92,48 +92,10 @@ void fd(D d, XD xd, D *p) {
   // CHECK: call void %
   p[0].f();
 
-  // We can devirtualize this, by CWG1504 / [expr.add]/6 (if the array
+  // FIXME: We can devirtualize this, by C++1z [expr.add]/6 (if the array
   // element type and the pointee type are not similar, behavior is undefined).
-  // CHECK: call void @_ZN1A1fEv
-  p[1].f();
-
-  // Negative indices are also UB for the same reason.
-  // CHECK: call void @_ZN1A1fEv
-  p[-1].f();
-
-  // Pointer arithmetic with arrow syntax: (p + N)->f()
-  // CHECK: call void @_ZN1A1fEv
-  (p + 1)->f();
-
-  // Pointer subtraction with arrow syntax: (p - N)->f()
-  // CHECK: call void @_ZN1A1fEv
-  (p - 1)->f();
-
-  // Can't devirtualize with non-constant index; we can't prove N != 0.
-  int n = 1;
-  // CHECK: call void %
-  p[n].f();
-
-  // Zero through expression: p[1-1] evaluates to 0, can't devirtualize.
-  // CHECK: call void %
-  p[1-1].f();
-
-  // (p + 0)->f() also can't be devirtualized (same as *p).
   // CHECK: call void %
-  (p + 0)->f();
-
-  // 1 + p is legal pointer arithmetic too.
-  // CHECK: call void @_ZN1A1fEv
-  (1 + p)->f();
-
-  // Constant variables are evaluated.
-  const int N = 1;
-  // CHECK: call void @_ZN1A1fEv
-  p[N].f();
-
-  // Pointer arithmetic with deref: *(p + 1)
-  // CHECK: call void @_ZN1A1fEv
-  (*(p + 1)).f();
+  p[1].f();
 }
 
 struct B {
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 73c8be98e7848..af91ac559d274 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -10309,7 +10309,7 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td>[<a href="https://wg21.link/expr.add";>expr.add</a>]</td>
     <td>CD3</td>
     <td>Pointer arithmetic after derived-base conversion</td>
-    <td class="full" align="center">Clang 23</td>
+    <td class="unknown" align="center">Unknown</td>
   </tr>
   <tr id="1505">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/1505.html";>1505</a></td>

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to