Skip to content

Commit

Permalink
[RTTI] Use OV dynamic cast on Android only (#28519)
Browse files Browse the repository at this point in the history
### 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 <[email protected]>
Co-authored-by: Ilya Lavrenov <[email protected]>
  • Loading branch information
t-jankowski and ilya-lavrenov authored Jan 20, 2025
1 parent 155f696 commit 1ad4863
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/core/include/openvino/core/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ struct OPENVINO_API DiscreteTypeInfo {
OPENVINO_API
std::ostream& operator<<(std::ostream& s, const DiscreteTypeInfo& info);

#if defined(__ANDROID__) || defined(ANDROID)
# define OPENVINO_DYNAMIC_CAST
#endif

/// \brief Tests if value is a pointer/shared_ptr that can be statically cast to a
/// Type*/shared_ptr<Type>
template <typename Type, typename Value>
Expand All @@ -93,7 +97,11 @@ template <typename Type, typename Value>
typename std::enable_if<std::is_convertible<decltype(static_cast<Type*>(std::declval<Value>())), Type*>::value,
Type*>::type
as_type(Value value) {
#ifdef OPENVINO_DYNAMIC_CAST
return ov::is_type<Type>(value) ? static_cast<Type*>(value) : nullptr;
#else
return dynamic_cast<Type*>(value);
#endif
}

namespace util {
Expand All @@ -114,7 +122,11 @@ struct AsTypePtr<std::shared_ptr<In>> {
/// Type, nullptr otherwise
template <typename T, typename U>
auto as_type_ptr(const U& value) -> decltype(::ov::util::AsTypePtr<U>::template call<T>(value)) {
#ifdef OPENVINO_DYNAMIC_CAST
return ::ov::util::AsTypePtr<U>::template call<T>(value);
#else
return std::dynamic_pointer_cast<T>(value);
#endif
}
} // namespace ov

Expand Down
56 changes: 55 additions & 1 deletion src/core/tests/rtti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
#include "common_test_utils/test_tools.hpp"
#include "gtest/gtest.h"
#include "openvino/op/op.hpp"
#include "openvino/pass/matcher_pass.hpp"

using namespace ov;
using namespace std;

namespace ov::test {

class OpType : public ov::op::Op {
public:
OPENVINO_OP("OpType");
Expand Down Expand Up @@ -88,3 +90,55 @@ TEST(rtti, op_with_type_version_parent_old) {
ASSERT_NE(type_info.parent, nullptr);
ASSERT_EQ(*type_info.parent, OpType::get_type_info_static());
}

#if !defined(__ANDROID__) && !defined(ANDROID)

class IncompleteRtti : public pass::MatcherPass {
public:
OPENVINO_RTTI("IncompleteRtti", "rtti_test");
};

class DerivedIncompleteRtti : public IncompleteRtti {
public:
OPENVINO_RTTI("DerivedIncompleteRtti", "rtti_test", IncompleteRtti);
};

// Assert backward compatibility of RTTI definition without parent but casted with as_type or as_type_ptr pointer work.
TEST(rtti, assert_casting_without_parent) {
{
IncompleteRtti incomplete;
DerivedIncompleteRtti derived;

auto pass_A = as_type<pass::MatcherPass>(&incomplete);
auto pass_B = as_type<pass::MatcherPass>(&derived);
auto pass_C = as_type<IncompleteRtti>(&derived);

EXPECT_NE(nullptr, pass_A);
EXPECT_NE(nullptr, pass_B);
EXPECT_NE(nullptr, pass_C);

EXPECT_NE(nullptr, as_type<IncompleteRtti>(pass_A));
EXPECT_NE(nullptr, as_type<IncompleteRtti>(pass_B));
EXPECT_NE(nullptr, as_type<DerivedIncompleteRtti>(pass_B));
EXPECT_NE(nullptr, as_type<DerivedIncompleteRtti>(pass_C));
}
{
auto incomplete = std::make_shared<IncompleteRtti>();
auto derived = std::make_shared<DerivedIncompleteRtti>();

auto pass_A = as_type_ptr<pass::MatcherPass>(incomplete);
auto pass_B = as_type_ptr<pass::MatcherPass>(derived);
auto pass_C = as_type_ptr<IncompleteRtti>(derived);

EXPECT_NE(nullptr, pass_A);
EXPECT_NE(nullptr, pass_B);
EXPECT_NE(nullptr, pass_C);

EXPECT_NE(nullptr, as_type_ptr<IncompleteRtti>(pass_A));
EXPECT_NE(nullptr, as_type_ptr<IncompleteRtti>(pass_B));
EXPECT_NE(nullptr, as_type_ptr<DerivedIncompleteRtti>(pass_B));
EXPECT_NE(nullptr, as_type_ptr<DerivedIncompleteRtti>(pass_C));
}
}
#endif // ANDROID
} // namespace ov::test

0 comments on commit 1ad4863

Please sign in to comment.