[llvm] r306003 - [Support] Fix return type deduction in RetryAfterSignal

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 22 06:55:54 PDT 2017


Author: labath
Date: Thu Jun 22 08:55:54 2017
New Revision: 306003

URL: http://llvm.org/viewvc/llvm-project?rev=306003&view=rev
Log:
[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.

Modified:
    llvm/trunk/include/llvm/Support/Errno.h
    llvm/trunk/unittests/Support/ErrnoTest.cpp

Modified: llvm/trunk/include/llvm/Support/Errno.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Errno.h?rev=306003&r1=306002&r2=306003&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Errno.h (original)
+++ llvm/trunk/include/llvm/Support/Errno.h Thu Jun 22 08:55:54 2017
@@ -31,11 +31,11 @@ std::string StrError();
 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);

Modified: llvm/trunk/unittests/Support/ErrnoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrnoTest.cpp?rev=306003&r1=306002&r2=306003&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/ErrnoTest.cpp (original)
+++ llvm/trunk/unittests/Support/ErrnoTest.cpp Thu Jun 22 08:55:54 2017
@@ -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<int> P{RetryAfterSignal(nullptr, ReturnPointer)};
+  EXPECT_EQ(47, *P);
 }




More information about the llvm-commits mailing list