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
