From fc01a4a7c8bbbc7df414bbbcf41f9536e6aaebb9 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 22 Jun 2017 13:55:54 +0000 Subject: [PATCH] [Support] Fix return type deduction in RetryAfterSignal 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 --- include/llvm/Support/Errno.h | 10 +++++----- unittests/Support/ErrnoTest.cpp | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/llvm/Support/Errno.h b/include/llvm/Support/Errno.h index 04fb03c5741..201b5598c02 100644 --- a/include/llvm/Support/Errno.h +++ b/include/llvm/Support/Errno.h @@ -31,11 +31,11 @@ std::string StrError(); std::string StrError(int errnum); template ::type> -inline ResultT RetryAfterSignal(ResultT Fail, const Fun &F, - const Args &... As) { - ResultT Res; + typename ResultT = std::result_of> +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); diff --git a/unittests/Support/ErrnoTest.cpp b/unittests/Support/ErrnoTest.cpp index 72b52c01ee3..888c162822d 100644 --- a/unittests/Support/ErrnoTest.cpp +++ b/unittests/Support/ErrnoTest.cpp @@ -12,6 +12,8 @@ using namespace llvm::sys; +static int *ReturnPointer() { return new int(47); } + TEST(ErrnoTest, RetryAfterSignal) { EXPECT_EQ(1, RetryAfterSignal(-1, [] { return 1; })); @@ -30,4 +32,7 @@ TEST(ErrnoTest, RetryAfterSignal) { EXPECT_EQ(2u, calls); EXPECT_EQ(1, RetryAfterSignal(-1, [](int x) { return x; }, 1)); + + std::unique_ptr P{RetryAfterSignal(nullptr, ReturnPointer)}; + EXPECT_EQ(47, *P); } -- 2.11.0