The default value of the ResultT template argument (which was there only
to avoid spelling out the long std::result_of template multiple times)
was being overriden by function call template argument deduction. This
manifested itself as a compiler error when calling the function as
FILE *X = RetryAfterSignal(nullptr, fopen, ...)
because the function would try to assign the result of fopen to
nullptr_t, but a more insidious side effect was that
RetryAfterSignal(-1, read, ...) would return "int" instead of "ssize_t",
losing precision along the way.
I fix this by having the function take the argument in a way that
prevents argument deduction from kicking in and add a test that makes
sure the return type is correct.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306003
91177308-0d34-0410-b5e6-
96231b3b80d8
std::string StrError(int errnum);
template <typename Fun, typename... Args,
- typename ResultT =
- typename std::result_of<Fun const &(const Args &...)>::type>
-inline ResultT RetryAfterSignal(ResultT Fail, const Fun &F,
- const Args &... As) {
- ResultT Res;
+ typename ResultT = std::result_of<Fun const &(const Args &...)>>
+inline typename ResultT::type RetryAfterSignal(typename ResultT::type Fail,
+ const Fun &F,
+ const Args &... As) {
+ typename ResultT::type Res;
do
Res = F(As...);
while (Res == Fail && errno == EINTR);
using namespace llvm::sys;
+static int *ReturnPointer() { return new int(47); }
+
TEST(ErrnoTest, RetryAfterSignal) {
EXPECT_EQ(1, RetryAfterSignal(-1, [] { return 1; }));
EXPECT_EQ(2u, calls);
EXPECT_EQ(1, RetryAfterSignal(-1, [](int x) { return x; }, 1));
+
+ std::unique_ptr<int> P{RetryAfterSignal(nullptr, ReturnPointer)};
+ EXPECT_EQ(47, *P);
}