Subject: bug#47698: [powerpc64le-linux] "check" package fails to build

From: Chris Marusich <[email-masked]>
Date: Sat, 10 Apr 2021 18:00:40 -0700

Hi,

On commit 83f8b6d32c76c56e4bb58eeb5af1259028d7ee72, on
powerpc64le-linux, the "check" package fails to build.  This prevents
many other packages from being built successfully.  It succeeds when
built on x86_64-linux, so the problem is probably specific to
powerpc64le-linux.

The following tests failed - I have attached test-suite.log:

FAIL: check_check_export
FAIL: check_check

I've attached test-suite.log.  There's a lot of messages.  However, the
following ones caught my eye:

> check.c:584: Bad status in set_fork_status

I tried adding some debug statements here, and it seems like the value
is -1 for some reason.  I don't know if that's really a problem,
though.  I suspect maybe it's just irrelevant noise...  Not sure.

> 19%: Checks: 260, Failures: 165, Errors: 45

Lots of failures, lots of errors.  Consider these:

> check_check_sub.c:74:P:Simple Tests:test_fail_if_pass:0: Passed
> check_check_sub.c:83:F:Simple Tests:test_fail_if_fail:0: This test should fail

The code is:

--8<---------------cut here---------------start------------->8---
START_TEST(test_fail_if_pass)
{
  record_test_name(tcase_name());

  fail_if(1 == 2, "This test should pass");
  fail_if(0, "This test should pass");
}
END_TEST

START_TEST(test_fail_if_fail)
{
  record_test_name(tcase_name());

  record_failure_line_num(__LINE__);
  fail_if(1 == 1, "This test should fail");
}
END_TEST
--8<---------------cut here---------------end--------------->8---

The fail_if macro is defined thusly:

--8<---------------cut here---------------start------------->8---
/*                                                                                                                                                                                             
 * Fail the test case if expr is false                                                                                                                                                         
 *                                                                                                                                                                                             
 * This call is deprecated.                                                                                                                                                                    
 *                                                                                                                                                                                             
 * NOTE: The space before the comma sign before ## is essential to be compatible                                                                                                               
 * with gcc 2.95.3 and earlier.                                                                                                                                                                
 * FIXME: these macros may conflict with C89 if expr is                                                                                                                                        
 * FIXME:   strcmp (str1, str2) due to excessive string length.                                                                                                                                
 */
#define fail_if(expr, ...)\
  (expr) ? \
     _ck_assert_failed(__FILE__, __LINE__, "Failure '"#expr"' occurred" , ## __VA_ARGS__, NULL) \
     : _mark_point(__FILE__, __LINE__)
--8<---------------cut here---------------end--------------->8---

This is pretty confusing to me.  The comment says "Fail the test case if
expr is false", but it sure looks to me like it fails the test case when
expr evaluates to true.  Am I confused?  I feel confused.  :-)

Anyway, regardless of how both of those test cases are supposed to run,
it seems likely that something funky is going on in the 1 == 1
evaluation.

Here's another example:

> check_check_sub.c:219:F:Simple Tests:test_ck_assert:0: Assertion 'x ==
> y' failed

The test is:

--8<---------------cut here---------------start------------->8---
/* These ck_assert tests are all designed to fail on the last                                                                                                                                  
   assertion. */

START_TEST(test_ck_assert)
{
  int x = 3;
  int y = 3;

  record_test_name(tcase_name());

  ck_assert(1);
  ck_assert(x == y);
  y++;
  ck_assert(x != y);
  record_failure_line_num(__LINE__);
  ck_assert(x == y);
}
END_TEST
--8<---------------cut here---------------end--------------->8---

There are some double-related test failures, too:

> check_check_sub.c:1458:F:Simple Tests:test_ck_assert_double_finite:0:
> Assertion 'x is finite' failed: x == inf

The corresponding test code:

--8<---------------cut here---------------start------------->8---
START_TEST(test_ck_assert_double_finite)
{
  double x = 0.0001;
  double t = 1;

  record_test_name(tcase_name());

  ck_assert_double_finite(x);
  /* MS VS doesn't allow explicit division by zero */
  x = 1.0 / (1.0 - t);
  record_failure_line_num(__LINE__);
  ck_assert_double_finite(x);
}
END_TEST
--8<---------------cut here---------------end--------------->8---

Some timeout-related tests fail, too:

> check_check_sub.c:2650:E:Timeout Double Scaling
> Tests:test_sleep9_fail:0: (after this point) Test timeout expired

A particularly suspicious failure involving "long double":

> check_check_sub.c:1830:F:Simple
> Tests:test_ck_assert_ldouble_eq_tol_with_mod:0: Assertion 'fabsl(2%f -
> 3%d) < 2%p' failed: 3%d == 1, 2%f == 0, 2%p == 0

The code:

--8<---------------cut here---------------start------------->8---
START_TEST(test_ck_assert_ldouble_eq_tol_with_mod)
{
  int d = 2;
  int f = 2;
  int p = 2;
  
  record_test_name(tcase_name());
  
  record_failure_line_num(__LINE__);
  ck_assert_ldouble_eq_tol(3%d, 2%f, 2%p);
}
END_TEST
--8<---------------cut here---------------end--------------->8---

The ck_assert_ldouble_eq_tol macro is:

--8<---------------cut here---------------start------------->8---
/**                                                                                                                                                                                            
 * Check two double precision floating point numbers to determine if X≈Y                                                                                                                       
 * with specified tolerance                                                                                                                                                                    
 *                                                                                                                                                                                             
 * If not X ≈ Y with error < T, the test fails.                                                                                                                                                
 *                                                                                                                                                                                             
 * @param X floating point number (long double)                                                                                                                                                
 * @param Y floating point number (long double) to compare against X                                                                                                                           
 * @param T tolerance (long double)                                                                                                                                                            
 *                                                                                                                                                                                             
 * @note If the check fails, the remaining of the test is aborted                                                                                                                              
 *                                                                                                                                                                                             
 * @since 0.11.0                                                                                                                                                                               
 */
#define ck_assert_ldouble_eq_tol(X, Y, T)  _ck_assert_floating_absdiff_op_tol(X, Y, <, T, long double, "L")
--8<---------------cut here---------------end--------------->8---

I know that there are "long double" problems on POWER9 in some cases...
I wonder if this is the root cause of the issue here?  Perhaps we need
to pass a flag or something?  Could it be that we need to compile gcc
with the --with-long-double configuration option after all, to fix this?
As described here, we don't currently do that:

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=47349#11

I don't really know what's going on, but I'll try compiling GCC 7.5.0
with the --with-long-double option, and I'll report whether it fixes
this issue.  If someone has any other idea before then, I'm all ears.

-- 
Chris