This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v3] Provide a C++ version of iseqsig


On 11/14/2017 02:21 PM, Gabriel F. T. Gomes wrote:

diff --git a/math/math.h b/math/math.h
index 326fd8ebe1..acc909d37f 100644
--- a/math/math.h
+++ b/math/math.h
@@ -1152,8 +1152,76 @@ iszero (__T __val)
/* Return X == Y but raising "invalid" and setting errno if X or Y is
     a NaN.  */
-# define iseqsig(x, y) \
-  __MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
+# if !defined __cplusplus || (__cplusplus < 201103L && !defined __GNUC__)
+#  define iseqsig(x, y) \
+   __MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
+# else
+/* In C++ mode, __MATH_TG cannot be used, because it relies on
+   __builtin_types_compatible_p, which is a C-only builtin.  Moreover,
+   the comparison macros from ISO C take two floating-point arguments,
+   which need not have the same type.  Choosing what underlying function
+   to call requires evaluating the formats of the arguments, then
+   selecting which is wider.  The macro __MATH_EVAL_FMT2 provides this
+   information, however, only the type of the macro expansion is
+   relevant (actually evaluating the expression would be incorrect).
+   Thus, the type is used as a template parameter for __iseqsig_type,
+   which calls the appropriate underlying function.  */

+template<typename _T1, typename _T2>
+inline int
+iseqsig(_T1 __x, _T2 __y) throw()
+{
+#  if __cplusplus >= 201103L
+  typedef __decltype (__MATH_EVAL_FMT2 (__x, __y)) _T3;
+#  else
+  typedef __typeof (__MATH_EVAL_FMT2 (__x, __y)) _T3;
+#  endif
+  return __iseqsig_type<_T3>::__call(__x, __y);
+}
+
+} /* extern "C++" */
+# endif /* __cplusplus */

Would these two expressions have the same types, assuming _T1 and _T2 are the template parameters from the iseqsig definition?

  __MATH_EVAL_FMT2 (__x, __y)
  __MATH_EVAL_FMT2 (_T1 (), _T2 ())

I believe the second expression would be safe to evaluate, so it could be used to select a suitable inline function. This would then work with any C++ version.

But the current approach is okay as well.

diff --git a/math/test-math-iseqsig.cc b/math/test-math-iseqsig.cc
new file mode 100644
index 0000000000..0316340638
--- /dev/null
+++ b/math/test-math-iseqsig.cc

+static bool errors;

Maybe use support_record_failure from <support/check.h> instead?

+static void
+check (int actual, int expected, const char *actual_expr, int line)
+{
+  if (actual != expected)
+    {
+      errors = true;
+      printf ("%s:%d: error: %s\n", __FILE__, line, actual_expr);
+      printf ("%s:%d:   expected: %d\n", __FILE__, line, expected);
+      printf ("%s:%d:   actual: %d\n", __FILE__, line, actual);
+    }
+}
+
+#define CHECK(actual, expected) \
+  check ((actual), (expected), #actual, __LINE__)

I think my memory protection key patches contain a more general implementation of this called TEST_COMPARE. Adhemerval requested just a minor documentation change, so I could commit that separately if you want to use it.

Thanks,
Florian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]