https://github.com/el-ev updated 
https://github.com/llvm/llvm-project/pull/196544

>From bc2dedb178950e86afee2ef2af29d1029ca9cdf9 Mon Sep 17 00:00:00 2001
From: Iris Shi <[email protected]>
Date: Fri, 8 May 2026 22:18:54 +0800
Subject: [PATCH 1/2] [clang][AST] Teach `CXXTypeidExpr::isMostDerived` to use
 `isEffectivelyFinal`

---
 clang/lib/AST/ExprCXX.cpp                     |  5 ++
 clang/test/CodeGenCXX/typeid-most-derived.cpp | 57 +++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/typeid-most-derived.cpp

diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index be1bd3ba913ea..40e129d03dcea 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -149,6 +149,11 @@ bool CXXTypeidExpr::isPotentiallyEvaluated() const {
 bool CXXTypeidExpr::isMostDerived(const ASTContext &Context) const {
   assert(!isTypeOperand() && "Cannot call isMostDerived for typeid(type)");
   const Expr *E = getExprOperand()->IgnoreParenNoopCasts(Context);
+
+  if (const CXXRecordDecl *RD = E->getType()->getAsCXXRecordDecl())
+    if (RD->isEffectivelyFinal())
+      return true;
+
   if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
     QualType Ty = DRE->getDecl()->getType();
     if (!Ty->isPointerOrReferenceType())
diff --git a/clang/test/CodeGenCXX/typeid-most-derived.cpp 
b/clang/test/CodeGenCXX/typeid-most-derived.cpp
new file mode 100644
index 0000000000000..a2d9f2e2bc6eb
--- /dev/null
+++ b/clang/test/CodeGenCXX/typeid-most-derived.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -Wno-unused-value -emit-llvm 
-o - -std=c++11 | FileCheck %s
+
+namespace std {
+  class type_info {};
+}
+
+struct Poly {
+  virtual int foo() { return 42; }
+  virtual ~Poly();
+};
+
+struct Derived : Poly {};
+struct Final final : Poly {
+    int foo() override { return 84; }
+};
+
+// Most derived
+void value(Poly p) { typeid(p); }
+// CHECK-LABEL: define {{.*}}void @_Z5value4Poly
+// CHECK-NOT:   %vtable
+// CHECK:       ret void
+
+// Most derived
+void final_ref(Final &f) { typeid(f); }
+// CHECK-LABEL: define {{.*}}void @_Z9final_refR5Final
+// CHECK-NOT:   %vtable
+// CHECK:       ret void
+
+// Most derived
+void final_deref(Final *f) { typeid(*f); }
+// CHECK-LABEL: define {{.*}}void @_Z11final_derefP5Final
+// CHECK-NOT:   %vtable
+// CHECK:       ret void
+
+// Not most derived
+void poly_ref(Poly &p) { typeid(p); }
+// CHECK-LABEL: define {{.*}}void @_Z8poly_refR4Poly
+// CHECK:       %vtable
+// CHECK:       ret void
+
+// Not most derived
+void poly_deref(Poly *p) { typeid(*p); }
+// CHECK-LABEL: define {{.*}}void @_Z10poly_derefP4Poly
+// CHECK:       %vtable
+// CHECK:       ret void
+
+// Not most derived
+void derived_ref(Derived &d) { typeid(d); }
+// CHECK-LABEL: define {{.*}}void @_Z11derived_refR7Derived
+// CHECK:       %vtable
+// CHECK:       ret void
+
+// Not most derived
+void derived_deref(Derived *d) { typeid(*d); }
+// CHECK-LABEL: define {{.*}}void @_Z13derived_derefP7Derived
+// CHECK:       %vtable
+// CHECK:       ret void

>From a9257f7f1a7f1422db5160546f643d943c80b637 Mon Sep 17 00:00:00 2001
From: Iris Shi <[email protected]>
Date: Mon, 11 May 2026 21:12:38 +0800
Subject: [PATCH 2/2] address review comments

---
 clang/docs/ReleaseNotes.rst                   |  3 ++
 clang/test/CodeGenCXX/typeid-most-derived.cpp | 28 +++++++++----------
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 40b97b4c8bf4b..0c6ad0707d196 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -250,6 +250,9 @@ Non-comprehensive list of changes in this release
   enabling tools such as language servers and refactoring engines to accurately
   map source locations back to explicit instantiation sites.
 
+- ``typeid`` on references and pointers of ``final`` types no longer emits a
+  vtable lookup at runtime.
+
 New Compiler Flags
 ------------------
 - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added
diff --git a/clang/test/CodeGenCXX/typeid-most-derived.cpp 
b/clang/test/CodeGenCXX/typeid-most-derived.cpp
index a2d9f2e2bc6eb..2b6bb850ff415 100644
--- a/clang/test/CodeGenCXX/typeid-most-derived.cpp
+++ b/clang/test/CodeGenCXX/typeid-most-derived.cpp
@@ -4,19 +4,19 @@ namespace std {
   class type_info {};
 }
 
-struct Poly {
+struct Base {
   virtual int foo() { return 42; }
-  virtual ~Poly();
+  virtual ~Base();
 };
 
-struct Derived : Poly {};
-struct Final final : Poly {
+struct NonFinal : Base {};
+struct Final final : Base {
     int foo() override { return 84; }
 };
 
 // Most derived
-void value(Poly p) { typeid(p); }
-// CHECK-LABEL: define {{.*}}void @_Z5value4Poly
+void base_by_value(Base b) { typeid(b); }
+// CHECK-LABEL: define {{.*}}void @_Z13base_by_value4Base
 // CHECK-NOT:   %vtable
 // CHECK:       ret void
 
@@ -33,25 +33,25 @@ void final_deref(Final *f) { typeid(*f); }
 // CHECK:       ret void
 
 // Not most derived
-void poly_ref(Poly &p) { typeid(p); }
-// CHECK-LABEL: define {{.*}}void @_Z8poly_refR4Poly
+void base_ref(Base &b) { typeid(b); }
+// CHECK-LABEL: define {{.*}}void @_Z8base_refR4Base
 // CHECK:       %vtable
 // CHECK:       ret void
 
 // Not most derived
-void poly_deref(Poly *p) { typeid(*p); }
-// CHECK-LABEL: define {{.*}}void @_Z10poly_derefP4Poly
+void base_deref(Base *b) { typeid(*b); }
+// CHECK-LABEL: define {{.*}}void @_Z10base_derefP4Base
 // CHECK:       %vtable
 // CHECK:       ret void
 
 // Not most derived
-void derived_ref(Derived &d) { typeid(d); }
-// CHECK-LABEL: define {{.*}}void @_Z11derived_refR7Derived
+void nonfinal_ref(NonFinal &d) { typeid(d); }
+// CHECK-LABEL: define {{.*}}void @_Z12nonfinal_refR8NonFinal
 // CHECK:       %vtable
 // CHECK:       ret void
 
 // Not most derived
-void derived_deref(Derived *d) { typeid(*d); }
-// CHECK-LABEL: define {{.*}}void @_Z13derived_derefP7Derived
+void nonfinal_deref(NonFinal *d) { typeid(*d); }
+// CHECK-LABEL: define {{.*}}void @_Z14nonfinal_derefP8NonFinal
 // CHECK:       %vtable
 // CHECK:       ret void

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

Reply via email to