Skip to content

Commit

Permalink
Fixed dtor mocking on MSVC.
Browse files Browse the repository at this point in the history
  • Loading branch information
FranckRJ committed Apr 2, 2023
1 parent 7994353 commit 5619839
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
10 changes: 10 additions & 0 deletions include/mockutils/DynamicProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,17 @@ namespace fakeit {
void stubDtor(MethodInvocationHandler<void> *methodInvocationHandler) {
auto offset = VTUtils::getDestructorOffset<C>();
MethodProxyCreator<void> creator;
// MSVC use an indirection for destructors, the "initial" destructor (VirtualTable::dtor, an helper) will be
// called through a member-function call, but the "final" destructor (the method proxy) will be called through
// a free-function call (inside the initial destructor). Therefor we use the free-function version
// (static method, but it's the same) of MethodProxy.
// For GCC / Clang, the destructor is directly called, like normal methods, so we use the member-function
// version.
#ifdef _MSC_VER
bindDtor(creator.createMethodProxyStatic<0>(offset), methodInvocationHandler);
#else
bindDtor(creator.createMethodProxy<0>(offset), methodInvocationHandler);
#endif
}

template<typename R, typename ... arglist>
Expand Down
19 changes: 19 additions & 0 deletions include/mockutils/MethodProxyCreator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ namespace fakeit {
return MethodProxy(id, offset, union_cast<void *>(&MethodProxyCreator::methodProxyX < id > ));
}

template<unsigned int id>
MethodProxy createMethodProxyStatic(unsigned int offset) {
return MethodProxy(id, offset, union_cast<void *>(&MethodProxyCreator::methodProxyXStatic < id > ));
}

protected:

R methodProxy(unsigned int id, const typename fakeit::production_arg<arglist>::type... args) {
Expand All @@ -49,5 +54,19 @@ namespace fakeit {
R methodProxyX(arglist ... args) {
return methodProxy(id, std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
}

static R methodProxyStatic(void* instance, unsigned int id, const typename fakeit::production_arg<arglist>::type... args) {
InvocationHandlerCollection *invocationHandlerCollection = InvocationHandlerCollection::getInvocationHandlerCollection(
instance);
MethodInvocationHandler<R, arglist...> *invocationHandler =
(MethodInvocationHandler<R, arglist...> *) invocationHandlerCollection->getInvocatoinHandlerPtrById(
id);
return invocationHandler->handleMethodInvocation(std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
}

template<int id>
static R methodProxyXStatic(void* instance, arglist ... args) {
return methodProxyStatic(instance, id, std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
}
};
}

0 comments on commit 5619839

Please sign in to comment.