(root)/
glibc-2.38/
math/
test-nan-payload.c
       1  /* Test nan functions payload handling (bug 16961).
       2     Copyright (C) 2015-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <float.h>
      20  #include <math.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <string.h>
      24  
      25  /* Avoid built-in functions.  */
      26  #define WRAP_NAN(FUNC, STR) \
      27    ({ const char *volatile wns = (STR); FUNC (wns); })
      28  #define WRAP_STRTO(FUNC, STR) \
      29    ({ const char *volatile wss = (STR); FUNC (wss, NULL); })
      30  
      31  #define CHECK_IS_NAN(TYPE, A)			\
      32    do						\
      33      {						\
      34        if (isnan (A))				\
      35  	puts ("PASS: " #TYPE " " #A);		\
      36        else					\
      37  	{					\
      38  	  puts ("FAIL: " #TYPE " " #A);		\
      39  	  result = 1;				\
      40  	}					\
      41      }						\
      42    while (0)
      43  
      44  #define CHECK_SAME_NAN(TYPE, A, B)			\
      45    do							\
      46      {							\
      47        if (memcmp (&(A), &(B), sizeof (A)) == 0)		\
      48  	puts ("PASS: " #TYPE " " #A " = " #B);		\
      49        else						\
      50  	{						\
      51  	  puts ("FAIL: " #TYPE " " #A " = " #B);	\
      52  	  result = 1;					\
      53  	}						\
      54      }							\
      55    while (0)
      56  
      57  #define CHECK_DIFF_NAN(TYPE, A, B)			\
      58    do							\
      59      {							\
      60        if (memcmp (&(A), &(B), sizeof (A)) != 0)		\
      61  	puts ("PASS: " #TYPE " " #A " != " #B);		\
      62        else						\
      63  	{						\
      64  	  puts ("FAIL: " #TYPE " " #A " != " #B);	\
      65  	  result = 1;					\
      66  	}						\
      67      }							\
      68    while (0)
      69  
      70  /* Cannot test payloads by memcmp for formats where NaNs have padding
      71     bits.  */
      72  #define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
      73  
      74  #define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG)		\
      75    do							\
      76      {							\
      77       TYPE n123 = WRAP_NAN (FUNC, "123");		\
      78       CHECK_IS_NAN (TYPE, n123);				\
      79       TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)");	\
      80       CHECK_IS_NAN (TYPE, s123);				\
      81       TYPE n456 = WRAP_NAN (FUNC, "456");		\
      82       CHECK_IS_NAN (TYPE, n456);				\
      83       TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)");	\
      84       CHECK_IS_NAN (TYPE, s456);				\
      85       TYPE n123x = WRAP_NAN (FUNC, "123)");		\
      86       CHECK_IS_NAN (TYPE, n123x);			\
      87       TYPE nemp = WRAP_NAN (FUNC, "");			\
      88       CHECK_IS_NAN (TYPE, nemp);				\
      89       TYPE semp = WRAP_STRTO (SFUNC, "NAN()");		\
      90       CHECK_IS_NAN (TYPE, semp);				\
      91       TYPE sx = WRAP_STRTO (SFUNC, "NAN");		\
      92       CHECK_IS_NAN (TYPE, sx);				\
      93       if (CAN_TEST_EQ (MANT_DIG))			\
      94         CHECK_SAME_NAN (TYPE, n123, s123);		\
      95       if (CAN_TEST_EQ (MANT_DIG))			\
      96         CHECK_SAME_NAN (TYPE, n456, s456);		\
      97       if (CAN_TEST_EQ (MANT_DIG))			\
      98         CHECK_SAME_NAN (TYPE, nemp, semp);		\
      99       if (CAN_TEST_EQ (MANT_DIG))			\
     100         CHECK_SAME_NAN (TYPE, n123x, sx);		\
     101       CHECK_DIFF_NAN (TYPE, n123, n456);			\
     102       CHECK_DIFF_NAN (TYPE, n123, nemp);			\
     103       CHECK_DIFF_NAN (TYPE, n123, n123x);		\
     104       CHECK_DIFF_NAN (TYPE, n456, nemp);			\
     105       CHECK_DIFF_NAN (TYPE, n456, n123x);		\
     106      }							\
     107    while (0)
     108  
     109  static int
     110  do_test (void)
     111  {
     112    int result = 0;
     113    RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG);
     114    RUN_TESTS (double, strtod, nan, DBL_MANT_DIG);
     115    RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG);
     116    return result;
     117  }
     118  
     119  #define TEST_FUNCTION do_test ()
     120  #include "../test-skeleton.c"