llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: AZero13 (AZero13)

<details>
<summary>Changes</summary>

By C++1z [expr.add]/6, if the array element type and the pointee type are not 
similar, behavior is undefined.

---
Full diff: https://github.com/llvm/llvm-project/pull/207540.diff


2 Files Affected:

- (modified) clang/lib/AST/DeclCXX.cpp (+14) 
- (modified) clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp 
(+2-2) 


``````````diff
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index e7e0f75fdc84d..eb010b5d43718 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2600,6 +2600,20 @@ CXXMethodDecl 
*CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
     }
   }
 
+  // We can devirtualize calls on an object accessed by an array subscript
+  // expression with a non-zero index. A pointer to the base of an array must
+  // point to an object of the array element type, so the dynamic type of the
+  // element can't be a derived class. 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.
+  if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Base)) {
+    Expr::EvalResult Result;
+    if (ASE->getIdx()->EvaluateAsInt(Result, getASTContext())) {
+      if (Result.Val.getInt() != 0)
+        return DevirtualizedMethod;
+    }
+  }
+
   // We can't devirtualize the call.
   return nullptr;
 }
diff --git a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp 
b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
index b50881db63e05..9851b88ebffcd 100644
--- a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
+++ b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -92,9 +92,9 @@ void fd(D d, XD xd, D *p) {
   // CHECK: call void %
   p[0].f();
 
-  // FIXME: We can devirtualize this, by C++1z [expr.add]/6 (if the array
+  // 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 %
+  // CHECK: call void @_ZN1A1fEv
   p[1].f();
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/207540
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to