Skip to content

Commit 1ad4863

Browse files
[RTTI] Use OV dynamic cast on Android only (#28519)
### Details: OV dynamic casting causes issue in external software with badly formed OV RTTI definitions, so it's replaced with standard dynamic casting, except for Android. ### Tickets: - CVS-160749 --------- Signed-off-by: Tomasz Jankowski <tomasz1.jankowski@intel.com> Co-authored-by: Ilya Lavrenov <ilya.lavrenov@intel.com>
1 parent 155f696 commit 1ad4863

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

src/core/include/openvino/core/type.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ struct OPENVINO_API DiscreteTypeInfo {
7777
OPENVINO_API
7878
std::ostream& operator<<(std::ostream& s, const DiscreteTypeInfo& info);
7979

80+
#if defined(__ANDROID__) || defined(ANDROID)
81+
# define OPENVINO_DYNAMIC_CAST
82+
#endif
83+
8084
/// \brief Tests if value is a pointer/shared_ptr that can be statically cast to a
8185
/// Type*/shared_ptr<Type>
8286
template <typename Type, typename Value>
@@ -93,7 +97,11 @@ template <typename Type, typename Value>
9397
typename std::enable_if<std::is_convertible<decltype(static_cast<Type*>(std::declval<Value>())), Type*>::value,
9498
Type*>::type
9599
as_type(Value value) {
100+
#ifdef OPENVINO_DYNAMIC_CAST
96101
return ov::is_type<Type>(value) ? static_cast<Type*>(value) : nullptr;
102+
#else
103+
return dynamic_cast<Type*>(value);
104+
#endif
97105
}
98106

99107
namespace util {
@@ -114,7 +122,11 @@ struct AsTypePtr<std::shared_ptr<In>> {
114122
/// Type, nullptr otherwise
115123
template <typename T, typename U>
116124
auto as_type_ptr(const U& value) -> decltype(::ov::util::AsTypePtr<U>::template call<T>(value)) {
125+
#ifdef OPENVINO_DYNAMIC_CAST
117126
return ::ov::util::AsTypePtr<U>::template call<T>(value);
127+
#else
128+
return std::dynamic_pointer_cast<T>(value);
129+
#endif
118130
}
119131
} // namespace ov
120132

src/core/tests/rtti.cpp

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
#include "common_test_utils/test_tools.hpp"
66
#include "gtest/gtest.h"
77
#include "openvino/op/op.hpp"
8+
#include "openvino/pass/matcher_pass.hpp"
89

9-
using namespace ov;
1010
using namespace std;
1111

12+
namespace ov::test {
13+
1214
class OpType : public ov::op::Op {
1315
public:
1416
OPENVINO_OP("OpType");
@@ -88,3 +90,55 @@ TEST(rtti, op_with_type_version_parent_old) {
8890
ASSERT_NE(type_info.parent, nullptr);
8991
ASSERT_EQ(*type_info.parent, OpType::get_type_info_static());
9092
}
93+
94+
#if !defined(__ANDROID__) && !defined(ANDROID)
95+
96+
class IncompleteRtti : public pass::MatcherPass {
97+
public:
98+
OPENVINO_RTTI("IncompleteRtti", "rtti_test");
99+
};
100+
101+
class DerivedIncompleteRtti : public IncompleteRtti {
102+
public:
103+
OPENVINO_RTTI("DerivedIncompleteRtti", "rtti_test", IncompleteRtti);
104+
};
105+
106+
// Assert backward compatibility of RTTI definition without parent but casted with as_type or as_type_ptr pointer work.
107+
TEST(rtti, assert_casting_without_parent) {
108+
{
109+
IncompleteRtti incomplete;
110+
DerivedIncompleteRtti derived;
111+
112+
auto pass_A = as_type<pass::MatcherPass>(&incomplete);
113+
auto pass_B = as_type<pass::MatcherPass>(&derived);
114+
auto pass_C = as_type<IncompleteRtti>(&derived);
115+
116+
EXPECT_NE(nullptr, pass_A);
117+
EXPECT_NE(nullptr, pass_B);
118+
EXPECT_NE(nullptr, pass_C);
119+
120+
EXPECT_NE(nullptr, as_type<IncompleteRtti>(pass_A));
121+
EXPECT_NE(nullptr, as_type<IncompleteRtti>(pass_B));
122+
EXPECT_NE(nullptr, as_type<DerivedIncompleteRtti>(pass_B));
123+
EXPECT_NE(nullptr, as_type<DerivedIncompleteRtti>(pass_C));
124+
}
125+
{
126+
auto incomplete = std::make_shared<IncompleteRtti>();
127+
auto derived = std::make_shared<DerivedIncompleteRtti>();
128+
129+
auto pass_A = as_type_ptr<pass::MatcherPass>(incomplete);
130+
auto pass_B = as_type_ptr<pass::MatcherPass>(derived);
131+
auto pass_C = as_type_ptr<IncompleteRtti>(derived);
132+
133+
EXPECT_NE(nullptr, pass_A);
134+
EXPECT_NE(nullptr, pass_B);
135+
EXPECT_NE(nullptr, pass_C);
136+
137+
EXPECT_NE(nullptr, as_type_ptr<IncompleteRtti>(pass_A));
138+
EXPECT_NE(nullptr, as_type_ptr<IncompleteRtti>(pass_B));
139+
EXPECT_NE(nullptr, as_type_ptr<DerivedIncompleteRtti>(pass_B));
140+
EXPECT_NE(nullptr, as_type_ptr<DerivedIncompleteRtti>(pass_C));
141+
}
142+
}
143+
#endif // ANDROID
144+
} // namespace ov::test

0 commit comments

Comments
 (0)