https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/161734
>From 94d4a7d4fdcb220cbc567d347c787789b25502f2 Mon Sep 17 00:00:00 2001 From: Andy Kaylor <[email protected]> Date: Wed, 1 Oct 2025 17:52:53 -0700 Subject: [PATCH 1/2] [CIR] Upstream DynamicCastOp This adds the dialect handling for CIR_DynamicCastOp and CIR_DynamicCastInfoAttr. Support for generating these operations from source will be added in a later change. --- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 53 +++++++++++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 94 +++++++++++++++++++ .../CIR/Dialect/IR/CIRTypeConstraints.td | 8 ++ clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 43 +++++++++ clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 + clang/test/CIR/IR/dynamic-cast.cir | 59 ++++++++++++ clang/test/CIR/IR/invalid-dyn-cast.cir | 43 +++++++++ 7 files changed, 304 insertions(+) create mode 100644 clang/test/CIR/IR/dynamic-cast.cir create mode 100644 clang/test/CIR/IR/invalid-dyn-cast.cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index f8358de9a1eb9..7aa0363abd689 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -601,6 +601,59 @@ def CIR_VTableAttr : CIR_Attr<"VTable", "vtable", [TypedAttrInterface]> { }]; } +//===----------------------------------------------------------------------===// +// DynamicCastInfoAttr +//===----------------------------------------------------------------------===// + +def CIR_DynamicCastInfoAttr : CIR_Attr<"DynamicCastInfo", "dyn_cast_info"> { + let summary = "ABI specific information about a dynamic cast"; + let description = [{ + Provide ABI specific information about a dynamic cast operation. + + The `srcRtti` and the `destRtti` parameters give the RTTI of the source + record type and the destination record type, respectively. + + The `runtimeFunc` parameter gives the `__dynamic_cast` function which is + provided by the runtime. The `badCastFunc` parameter gives the + `__cxa_bad_cast` function which is also provided by the runtime. + + The `offsetHint` parameter gives the hint value that should be passed to the + `__dynamic_cast` runtime function. + }]; + + let parameters = (ins + CIR_GlobalViewAttr:$srcRtti, + CIR_GlobalViewAttr:$destRtti, + "mlir::FlatSymbolRefAttr":$runtimeFunc, + "mlir::FlatSymbolRefAttr":$badCastFunc, + CIR_IntAttr:$offsetHint + ); + + let builders = [ + AttrBuilderWithInferredContext<(ins "GlobalViewAttr":$srcRtti, + "GlobalViewAttr":$destRtti, + "mlir::FlatSymbolRefAttr":$runtimeFunc, + "mlir::FlatSymbolRefAttr":$badCastFunc, + "IntAttr":$offsetHint), [{ + return $_get(srcRtti.getContext(), srcRtti, destRtti, runtimeFunc, + badCastFunc, offsetHint); + }]>, + ]; + + let genVerifyDecl = 1; + let assemblyFormat = [{ + `<` + qualified($srcRtti) `,` qualified($destRtti) `,` + $runtimeFunc `,` $badCastFunc `,` qualified($offsetHint) + `>` + }]; + + let extraClassDeclaration = [{ + /// Get attribute alias name for this attribute. + std::string getAlias() const; + }]; +} + //===----------------------------------------------------------------------===// // ConstComplexAttr //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 0a78492aa9a86..3f4fec37a0967 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -232,6 +232,100 @@ def CIR_CastOp : CIR_Op<"cast", [ }]; } +//===----------------------------------------------------------------------===// +// DynamicCastOp +//===----------------------------------------------------------------------===// + +def CIR_DynamicCastKind : CIR_I32EnumAttr< + "DynamicCastKind", "dynamic cast kind", [ + I32EnumAttrCase<"Ptr", 0, "ptr">, + I32EnumAttrCase<"Ref", 1, "ref"> +]>; + +def CIR_DynamicCastOp : CIR_Op<"dyn_cast"> { + let summary = "Perform dynamic cast on record pointers"; + let description = [{ + The `cir.dyn_cast` operation models part of the semantics of the + `dynamic_cast` operator in C++. It can be used to perform 3 kinds of casts + on record pointers: + + - Down-cast, which casts a base class pointer to a derived class pointer; + - Side-cast, which casts a class pointer to a sibling class pointer; + - Cast-to-complete, which casts a class pointer to a void pointer. + + The input of the operation must be a record pointer. The result of the + operation is either a record pointer or a void pointer. + + The parameter `kind` specifies the semantics of this operation. If its value + is `ptr`, then the operation models dynamic casts on pointers. Otherwise, if + its value is `ref`, the operation models dynamic casts on references. + Specifically: + + - When the input pointer is a null pointer value: + - If `kind` is `ref`, the operation will invoke undefined behavior. A + sanitizer check will be emitted if sanitizer is on. + - Otherwise, the operation will return a null pointer value as its result. + - When the runtime type check fails: + - If `kind` is `ref`, the operation will throw a `bad_cast` exception. + - Otherwise, the operation will return a null pointer value as its result. + + The `info` argument gives detailed information about the requested dynamic + cast operation. It is an optional `#cir.dyn_cast_info` attribute that is + only present when the operation models a down-cast or a side-cast. + + The `relative_layout` argument specifies whether the Itanium C++ ABI vtable + uses relative layout. It is only meaningful when the operation models a + cast-to-complete operation. + + Examples: + + ```mlir + %0 = cir.dyn_cast ptr %p : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> + %1 = cir.dyn_cast ptr relative_layout %p : !cir.ptr<!rec_Base> + -> !cir.ptr<!rec_Derived> + %2 = cir.dyn_cast ref %r : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> + #cir.dyn_cast_info< + #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, + #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, + @__dynamic_cast, + @__cxa_bad_cast, + #cir.int<0> : !s64i + > + ``` + }]; + + let arguments = (ins + CIR_DynamicCastKind:$kind, + CIR_PtrToRecordType:$src, + OptionalAttr<CIR_DynamicCastInfoAttr>:$info, + UnitAttr:$relative_layout + ); + + let results = (outs + CIR_PtrToAnyOf<[CIR_VoidType, CIR_RecordType]>:$result + ); + + let assemblyFormat = [{ + $kind (`relative_layout` $relative_layout^)? $src + `:` qualified(type($src)) `->` qualified(type($result)) + (qualified($info)^)? attr-dict + }]; + + let extraClassDeclaration = [{ + /// Determine whether this operation models reference casting in C++. + bool isRefcast() { + return getKind() == ::cir::DynamicCastKind::Ref; + } + + /// Determine whether this operation represents a dynamic cast to a void + /// pointer. + bool isCastToVoid() { + return getType().isVoidPtr(); + } + }]; + + let hasLLVMLowering = false; +} //===----------------------------------------------------------------------===// // PtrStrideOp diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index da03a291a7690..9e8e1298308a4 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -171,6 +171,12 @@ def CIR_AnyComplexOrIntOrFloatType : AnyTypeOf<[ let cppFunctionName = "isComplexOrIntegerOrFloatingPointType"; } +//===----------------------------------------------------------------------===// +// Record Type predicates +//===----------------------------------------------------------------------===// + +def CIR_AnyRecordType : CIR_TypeBase<"::cir::RecordType", "record type">; + //===----------------------------------------------------------------------===// // Array Type predicates //===----------------------------------------------------------------------===// @@ -228,6 +234,8 @@ def CIR_PtrToIntOrFloatType : CIR_PtrToType<CIR_AnyIntOrFloatType>; def CIR_PtrToComplexType : CIR_PtrToType<CIR_AnyComplexType>; +def CIR_PtrToRecordType : CIR_PtrToType<CIR_AnyRecordType>; + def CIR_PtrToArray : CIR_PtrToType<CIR_AnyArrayType>; //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 95faad6746955..f95c70b5ae892 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -462,6 +462,49 @@ LogicalResult cir::VTableAttr::verify( return success(); } +//===----------------------------------------------------------------------===// +// DynamicCastInfoAtttr definitions +//===----------------------------------------------------------------------===// + +std::string DynamicCastInfoAttr::getAlias() const { + // The alias looks like: `dyn_cast_info_<src>_<dest>` + + std::string alias = "dyn_cast_info_"; + + alias.append(getSrcRtti().getSymbol().getValue()); + alias.push_back('_'); + alias.append(getDestRtti().getSymbol().getValue()); + + return alias; +} + +LogicalResult DynamicCastInfoAttr::verify( + function_ref<InFlightDiagnostic()> emitError, cir::GlobalViewAttr srcRtti, + cir::GlobalViewAttr destRtti, mlir::FlatSymbolRefAttr runtimeFunc, + mlir::FlatSymbolRefAttr badCastFunc, cir::IntAttr offsetHint) { + auto isRttiPtr = [](mlir::Type ty) { + // RTTI pointers are !cir.ptr<!u8i>. + + auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty); + if (!ptrTy) + return false; + + auto pointeeIntTy = mlir::dyn_cast<cir::IntType>(ptrTy.getPointee()); + if (!pointeeIntTy) + return false; + + return pointeeIntTy.isUnsigned() && pointeeIntTy.getWidth() == 8; + }; + + if (!isRttiPtr(srcRtti.getType())) + return emitError() << "srcRtti must be an RTTI pointer"; + + if (!isRttiPtr(destRtti.getType())) + return emitError() << "destRtti must be an RTTI pointer"; + + return success(); +} + //===----------------------------------------------------------------------===// // CIR Dialect //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 6b5cc808e9a29..cda43c98c5f01 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -71,6 +71,10 @@ struct CIROpAsmDialectInterface : public OpAsmDialectInterface { os << "bfi_" << bitfield.getName().str(); return AliasResult::FinalAlias; } + if (auto dynCastInfoAttr = mlir::dyn_cast<cir::DynamicCastInfoAttr>(attr)) { + os << dynCastInfoAttr.getAlias(); + return AliasResult::FinalAlias; + } return AliasResult::NoAlias; } }; diff --git a/clang/test/CIR/IR/dynamic-cast.cir b/clang/test/CIR/IR/dynamic-cast.cir new file mode 100644 index 0000000000000..a7468f1e97211 --- /dev/null +++ b/clang/test/CIR/IR/dynamic-cast.cir @@ -0,0 +1,59 @@ +// RUN: cir-opt --verify-roundtrip %s | FileCheck %s + +!s64i = !cir.int<s, 64> +!u8i = !cir.int<u, 8> +!void = !cir.void + +!rec_Base = !cir.record<struct "Base" {!cir.vptr}> +!rec_Derived = !cir.record<struct "Derived" {!rec_Base}> + +#dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> + +// CHECK: #dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> + +module { + cir.global "private" constant external @_ZTI4Base : !cir.ptr<!u8i> + cir.global "private" constant external @_ZTI7Derived : !cir.ptr<!u8i> + cir.func private @__dynamic_cast(!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void> + cir.func private @__cxa_bad_cast() + + cir.func @test_ptr_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + cir.return %0 : !cir.ptr<!rec_Derived> + } + + // CHECK: cir.func @test_ptr_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + // CHECK: %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + // CHECK: cir.return %0 : !cir.ptr<!rec_Derived> + // CHECK: } + + cir.func @test_ref_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + %0 = cir.dyn_cast ref %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + cir.return %0 : !cir.ptr<!rec_Derived> + } + + // CHECK: cir.func @test_ref_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + // CHECK: %0 = cir.dyn_cast ref %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + // CHECK: cir.return %0 : !cir.ptr<!rec_Derived> + // CHECK: } + + cir.func dso_local @test_cast_to_void(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + cir.return %0 : !cir.ptr<!void> + } + + // CHECK: cir.func dso_local @test_cast_to_void(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + // CHECK: %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + // CHECK: cir.return %0 : !cir.ptr<!void> + // CHECK: } + + cir.func dso_local @test_relative_layout_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + %0 = cir.dyn_cast ptr relative_layout %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + cir.return %0 : !cir.ptr<!void> + } + + // CHECK: cir.func dso_local @test_relative_layout_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + // CHECK: %0 = cir.dyn_cast ptr relative_layout %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + // CHECK: cir.return %0 : !cir.ptr<!void> + // CHECK: } +} diff --git a/clang/test/CIR/IR/invalid-dyn-cast.cir b/clang/test/CIR/IR/invalid-dyn-cast.cir new file mode 100644 index 0000000000000..b6ac3ebcfef95 --- /dev/null +++ b/clang/test/CIR/IR/invalid-dyn-cast.cir @@ -0,0 +1,43 @@ +// RUN: cir-opt %s -verify-diagnostics -split-input-file + +!s64i = !cir.int<s, 64> +!s8i = !cir.int<s, 8> +!u32i = !cir.int<u, 32> +!u8i = !cir.int<u, 8> +!void = !cir.void + +!Base = !cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}> +!Derived = !cir.record<struct "Derived" {!cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}>}> + +module { + cir.global "private" constant external @_ZTI4Base : !cir.ptr<!u32i> + cir.global "private" constant external @_ZTI7Derived : !cir.ptr<!u8i> + cir.func private @__dynamic_cast(!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void> + cir.func private @__cxa_bad_cast() + cir.func @test(%arg0 : !cir.ptr<!Base>) { + // expected-error@+1 {{srcRtti must be an RTTI pointer}} + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u32i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> + } +} + +// ----- + +!s64i = !cir.int<s, 64> +!s8i = !cir.int<s, 8> +!u32i = !cir.int<u, 32> +!u8i = !cir.int<u, 8> +!void = !cir.void + +!Base = !cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}> +!Derived = !cir.record<struct "Derived" {!cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}>}> + +module { + cir.global "private" constant external @_ZTI4Base : !cir.ptr<!u8i> + cir.global "private" constant external @_ZTI7Derived : !cir.ptr<!u32i> + cir.func private @__dynamic_cast(!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void> + cir.func private @__cxa_bad_cast() + cir.func @test(%arg0 : !cir.ptr<!Base>) { + // expected-error@+1 {{destRtti must be an RTTI pointer}} + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u32i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> + } +} >From 58710ae3a8a32d97c94692dca7bde8e48a7886f2 Mon Sep 17 00:00:00 2001 From: Andy Kaylor <[email protected]> Date: Fri, 3 Oct 2025 10:41:11 -0700 Subject: [PATCH 2/2] Apply review feedback --- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 5 +++-- clang/include/clang/CIR/Dialect/IR/CIROps.td | 12 ++++++------ clang/test/CIR/IR/dynamic-cast.cir | 4 ++-- clang/test/CIR/IR/invalid-dyn-cast.cir | 4 ++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 7aa0363abd689..2f6b3fa5d7246 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -643,8 +643,9 @@ def CIR_DynamicCastInfoAttr : CIR_Attr<"DynamicCastInfo", "dyn_cast_info"> { let genVerifyDecl = 1; let assemblyFormat = [{ `<` - qualified($srcRtti) `,` qualified($destRtti) `,` - $runtimeFunc `,` $badCastFunc `,` qualified($offsetHint) + `srcRtti` `=` qualified($srcRtti) `,` `destRtti` `=` qualified($destRtti) + `,` `runtimeFunc` `=` $runtimeFunc `,` `badCastFunc` `=` $badCastFunc `,` + `offsetHint` `=` qualified($offsetHint) `>` }]; diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 3f4fec37a0967..9231dd6d8c141 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -285,11 +285,11 @@ def CIR_DynamicCastOp : CIR_Op<"dyn_cast"> { -> !cir.ptr<!rec_Derived> %2 = cir.dyn_cast ref %r : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #cir.dyn_cast_info< - #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, - #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, - @__dynamic_cast, - @__cxa_bad_cast, - #cir.int<0> : !s64i + srcRtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, + destRtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, + runtimeFunc = @__dynamic_cast, + badCastFunc = @__cxa_bad_cast, + offsetHint = #cir.int<0> : !s64i > ``` }]; @@ -313,7 +313,7 @@ def CIR_DynamicCastOp : CIR_Op<"dyn_cast"> { let extraClassDeclaration = [{ /// Determine whether this operation models reference casting in C++. - bool isRefcast() { + bool isRefCast() { return getKind() == ::cir::DynamicCastKind::Ref; } diff --git a/clang/test/CIR/IR/dynamic-cast.cir b/clang/test/CIR/IR/dynamic-cast.cir index a7468f1e97211..3d9ac2cbebe76 100644 --- a/clang/test/CIR/IR/dynamic-cast.cir +++ b/clang/test/CIR/IR/dynamic-cast.cir @@ -7,9 +7,9 @@ !rec_Base = !cir.record<struct "Base" {!cir.vptr}> !rec_Derived = !cir.record<struct "Derived" {!rec_Base}> -#dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> +#dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<srcRtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, destRtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, runtimeFunc = @__dynamic_cast, badCastFunc = @__cxa_bad_cast, offsetHint = #cir.int<0> : !s64i> -// CHECK: #dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> +// CHECK: #dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<srcRtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, destRtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, runtimeFunc = @__dynamic_cast, badCastFunc = @__cxa_bad_cast, offsetHint = #cir.int<0> : !s64i> module { cir.global "private" constant external @_ZTI4Base : !cir.ptr<!u8i> diff --git a/clang/test/CIR/IR/invalid-dyn-cast.cir b/clang/test/CIR/IR/invalid-dyn-cast.cir index b6ac3ebcfef95..b5f0c928a634f 100644 --- a/clang/test/CIR/IR/invalid-dyn-cast.cir +++ b/clang/test/CIR/IR/invalid-dyn-cast.cir @@ -16,7 +16,7 @@ module { cir.func private @__cxa_bad_cast() cir.func @test(%arg0 : !cir.ptr<!Base>) { // expected-error@+1 {{srcRtti must be an RTTI pointer}} - %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u32i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<srcRtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u32i>, destRtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, runtimeFunc = @__dynamic_cast, badCastFunc = @__cxa_bad_cast, offsetHint = #cir.int<0> : !s64i> } } @@ -38,6 +38,6 @@ module { cir.func private @__cxa_bad_cast() cir.func @test(%arg0 : !cir.ptr<!Base>) { // expected-error@+1 {{destRtti must be an RTTI pointer}} - %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<#cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u32i>, @__dynamic_cast, @__cxa_bad_cast, #cir.int<0> : !s64i> + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<srcRtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, destRtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u32i>, runtimeFunc = @__dynamic_cast, badCastFunc = @__cxa_bad_cast, offsetHint = #cir.int<0> : !s64i> } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
