[clang] [CIR] Fix dynamic cast of const types (PR #192751)

via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 17 16:01:33 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

<details>
<summary>Changes</summary>

When a dynamic cast was performed using const-qualified values, we were generating a reference to const-qualified typeinfo but never emitting such const-qualified typeinfo, leading to an undefined reference at link time.

This change fixes that by stripping the type qualifiers before processing the cast. This matches the behavior of classic codegen in ItaniumCXXABI::emitDynamicCastCall.

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


2 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/dynamic-cast.cpp (+38) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index c398e6183d91c..458dc5152298b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -2324,9 +2324,9 @@ static cir::DynamicCastInfoAttr emitDynamicCastInfo(CIRGenFunction &cgf,
                                                     QualType srcRecordTy,
                                                     QualType destRecordTy) {
   auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
-      cgf.cgm.getAddrOfRTTIDescriptor(loc, srcRecordTy));
+      cgf.cgm.getAddrOfRTTIDescriptor(loc, srcRecordTy.getUnqualifiedType()));
   auto destRtti = mlir::cast<cir::GlobalViewAttr>(
-      cgf.cgm.getAddrOfRTTIDescriptor(loc, destRecordTy));
+      cgf.cgm.getAddrOfRTTIDescriptor(loc, destRecordTy.getUnqualifiedType()));
 
   cir::FuncOp runtimeFuncOp = getItaniumDynamicCastFn(cgf);
   cir::FuncOp badCastFuncOp = getBadCastFn(cgf);
diff --git a/clang/test/CIR/CodeGen/dynamic-cast.cpp b/clang/test/CIR/CodeGen/dynamic-cast.cpp
index 517ec0ae8380a..11bd7b0f73aae 100644
--- a/clang/test/CIR/CodeGen/dynamic-cast.cpp
+++ b/clang/test/CIR/CodeGen/dynamic-cast.cpp
@@ -157,3 +157,41 @@ void *ptr_cast_to_complete(Base *ptr) {
 // OGCG:   br label %[[DONE]]
 // OGCG: [[DONE]]:
 // OGCG:   %[[RET:.*]] = phi ptr [ %[[RESULT]], %[[NOT_NULL]] ], [ null, %[[NULL]] ]
+
+// Dynamic cast to a const pointer/reference must reference the typeinfo of
+// the unqualified class type (e.g. `_ZTI7Derived`), not a const-qualified
+// typeinfo symbol (`_ZTIK7Derived`), which is never emitted. Regression test
+// for a bug where CIR emitted `_ZTIK...` references that caused link-time
+// undefined-reference errors.
+
+const Derived *const_ptr_cast(const Base *b) {
+  return dynamic_cast<const Derived *>(b);
+}
+
+// CIR-BEFORE: cir.func {{.*}} @_Z14const_ptr_castPK4Base
+// CIR-BEFORE:   %{{.+}} = cir.dyn_cast ptr %{{.+}} : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived
+// CIR-BEFORE: }
+
+// LLVM: define {{.*}} @_Z14const_ptr_castPK4Base
+// LLVM:   call ptr @__dynamic_cast(ptr %{{.*}}, ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)
+// LLVM-NOT: _ZTIK4Base
+// LLVM-NOT: _ZTIK7Derived
+
+// OGCG: define {{.*}} @_Z14const_ptr_castPK4Base
+// OGCG:   call ptr @__dynamic_cast(ptr %{{.*}}, ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)
+
+const Derived &const_ref_cast(const Base &b) {
+  return dynamic_cast<const Derived &>(b);
+}
+
+// CIR-BEFORE: cir.func {{.*}} @_Z14const_ref_castRK4Base
+// CIR-BEFORE:   %{{.+}} = cir.dyn_cast ref %{{.+}} : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived
+// CIR-BEFORE: }
+
+// LLVM: define {{.*}} ptr @_Z14const_ref_castRK4Base
+// LLVM:   call ptr @__dynamic_cast(ptr %{{.*}}, ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)
+// LLVM-NOT: _ZTIK4Base
+// LLVM-NOT: _ZTIK7Derived
+
+// OGCG: define {{.*}} ptr @_Z14const_ref_castRK4Base
+// OGCG:   call ptr @__dynamic_cast(ptr %{{.*}}, ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)

``````````

</details>


https://github.com/llvm/llvm-project/pull/192751


More information about the cfe-commits mailing list