diff --git a/c/common/test/includes/standard-library/math.h b/c/common/test/includes/standard-library/math.h index 14f28ec8c6..4acad05f16 100644 --- a/c/common/test/includes/standard-library/math.h +++ b/c/common/test/includes/standard-library/math.h @@ -11,30 +11,30 @@ extern "C" { #define __NEED_double_t #include -#if 100*__GNUC__+__GNUC_MINOR__ >= 303 -#define NAN __builtin_nanf("") -#define INFINITY __builtin_inff() +#if 100 * __GNUC__ + __GNUC_MINOR__ >= 303 +#define NAN __builtin_nanf("") +#define INFINITY __builtin_inff() #else -#define NAN (0.0f/0.0f) -#define INFINITY 1e5000f +#define NAN (0.0f / 0.0f) +#define INFINITY 1e5000f #endif #define HUGE_VALF INFINITY -#define HUGE_VAL ((double)INFINITY) +#define HUGE_VAL ((double)INFINITY) #define HUGE_VALL ((long double)INFINITY) -#define MATH_ERRNO 1 +#define MATH_ERRNO 1 #define MATH_ERREXCEPT 2 #define math_errhandling 2 -#define FP_ILOGBNAN (-1-0x7fffffff) +#define FP_ILOGBNAN (-1 - 0x7fffffff) #define FP_ILOGB0 FP_ILOGBNAN -#define FP_NAN 0 -#define FP_INFINITE 1 -#define FP_ZERO 2 +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 #define FP_SUBNORMAL 3 -#define FP_NORMAL 4 +#define FP_NORMAL 4 #ifdef __FP_FAST_FMA #define FP_FAST_FMA 1 @@ -52,58 +52,68 @@ int __fpclassify(double); int __fpclassifyf(float); int __fpclassifyl(long double); -static __inline unsigned __FLOAT_BITS(float __f) -{ - union {float __f; unsigned __i;} __u; - __u.__f = __f; - return __u.__i; +static __inline unsigned __FLOAT_BITS(float __f) { + union { + float __f; + unsigned __i; + } __u; + __u.__f = __f; + return __u.__i; } -static __inline unsigned long long __DOUBLE_BITS(double __f) -{ - union {double __f; unsigned long long __i;} __u; - __u.__f = __f; - return __u.__i; +static __inline unsigned long long __DOUBLE_BITS(double __f) { + union { + double __f; + unsigned long long __i; + } __u; + __u.__f = __f; + return __u.__i; } -#define fpclassify(x) ( \ - sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \ - sizeof(x) == sizeof(double) ? __fpclassify(x) : \ - __fpclassifyl(x) ) - -#define isinf(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \ - __fpclassifyl(x) == FP_INFINITE) - -#define isnan(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \ - __fpclassifyl(x) == FP_NAN) - -#define isnormal(x) ( \ - sizeof(x) == sizeof(float) ? ((__FLOAT_BITS(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : \ - sizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x)+(1ULL<<52)) & -1ULL>>1) >= 1ULL<<53 : \ - __fpclassifyl(x) == FP_NORMAL) - -#define isfinite(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) < 0x7ffULL<<52 : \ - __fpclassifyl(x) > FP_INFINITE) +#define fpclassify(x) \ + (sizeof(x) == sizeof(float) ? __fpclassifyf(x) \ + : sizeof(x) == sizeof(double) ? __fpclassify(x) \ + : __fpclassifyl(x)) + +#define isinf(x) \ + (sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 \ + : sizeof(x) == sizeof(double) \ + ? (__DOUBLE_BITS(x) & -1ULL >> 1) == 0x7ffULL << 52 \ + : __fpclassifyl(x) == FP_INFINITE) + +#define isnan(x) \ + (sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 \ + : sizeof(x) == sizeof(double) \ + ? (__DOUBLE_BITS(x) & -1ULL >> 1) > 0x7ffULL << 52 \ + : __fpclassifyl(x) == FP_NAN) + +#define isnormal(x) \ + (sizeof(x) == sizeof(float) \ + ? ((__FLOAT_BITS(x) + 0x00800000) & 0x7fffffff) >= 0x01000000 \ + : sizeof(x) == sizeof(double) \ + ? ((__DOUBLE_BITS(x) + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53 \ + : __fpclassifyl(x) == FP_NORMAL) + +#define isfinite(x) \ + (sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 \ + : sizeof(x) == sizeof(double) \ + ? (__DOUBLE_BITS(x) & -1ULL >> 1) < 0x7ffULL << 52 \ + : __fpclassifyl(x) > FP_INFINITE) int __signbit(double); int __signbitf(float); int __signbitl(long double); -#define signbit(x) ( \ - sizeof(x) == sizeof(float) ? (int)(__FLOAT_BITS(x)>>31) : \ - sizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x)>>63) : \ - __signbitl(x) ) +#define signbit(x) \ + (sizeof(x) == sizeof(float) ? (int)(__FLOAT_BITS(x) >> 31) \ + : sizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x) >> 63) \ + : __signbitl(x)) -#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y))) +#define isunordered(x, y) (isnan((x)) ? ((void)(y), 1) : isnan((y))) -#define __ISREL_DEF(rel, op, type) \ -static __inline int __is##rel(type __x, type __y) \ -{ return !isunordered(__x,__y) && __x op __y; } +#define __ISREL_DEF(rel, op, type) \ + static __inline int __is##rel(type __x, type __y) { \ + return !isunordered(__x, __y) && __x op __y; \ + } __ISREL_DEF(lessf, <, float_t) __ISREL_DEF(less, <, double_t) @@ -121,317 +131,316 @@ __ISREL_DEF(greaterequalf, >=, float_t) __ISREL_DEF(greaterequal, >=, double_t) __ISREL_DEF(greaterequall, >=, long double) -#define __tg_pred_2(x, y, p) ( \ - sizeof((x)+(y)) == sizeof(float) ? p##f(x, y) : \ - sizeof((x)+(y)) == sizeof(double) ? p(x, y) : \ - p##l(x, y) ) +#define __tg_pred_2(x, y, p) \ + (sizeof((x) + (y)) == sizeof(float) ? p##f(x, y) \ + : sizeof((x) + (y)) == sizeof(double) ? p(x, y) \ + : p##l(x, y)) -#define isless(x, y) __tg_pred_2(x, y, __isless) -#define islessequal(x, y) __tg_pred_2(x, y, __islessequal) -#define islessgreater(x, y) __tg_pred_2(x, y, __islessgreater) -#define isgreater(x, y) __tg_pred_2(x, y, __isgreater) -#define isgreaterequal(x, y) __tg_pred_2(x, y, __isgreaterequal) +#define isless(x, y) __tg_pred_2(x, y, __isless) +#define islessequal(x, y) __tg_pred_2(x, y, __islessequal) +#define islessgreater(x, y) __tg_pred_2(x, y, __islessgreater) +#define isgreater(x, y) __tg_pred_2(x, y, __isgreater) +#define isgreaterequal(x, y) __tg_pred_2(x, y, __isgreaterequal) -double acos(double); -float acosf(float); +double acos(double); +float acosf(float); long double acosl(long double); -double acosh(double); -float acoshf(float); +double acosh(double); +float acoshf(float); long double acoshl(long double); -double asin(double); -float asinf(float); +double asin(double); +float asinf(float); long double asinl(long double); -double asinh(double); -float asinhf(float); +double asinh(double); +float asinhf(float); long double asinhl(long double); -double atan(double); -float atanf(float); +double atan(double); +float atanf(float); long double atanl(long double); -double atan2(double, double); -float atan2f(float, float); +double atan2(double, double); +float atan2f(float, float); long double atan2l(long double, long double); -double atanh(double); -float atanhf(float); +double atanh(double); +float atanhf(float); long double atanhl(long double); -double cbrt(double); -float cbrtf(float); +double cbrt(double); +float cbrtf(float); long double cbrtl(long double); -double ceil(double); -float ceilf(float); +double ceil(double); +float ceilf(float); long double ceill(long double); -double copysign(double, double); -float copysignf(float, float); +double copysign(double, double); +float copysignf(float, float); long double copysignl(long double, long double); -double cos(double); -float cosf(float); +double cos(double); +float cosf(float); long double cosl(long double); -double cosh(double); -float coshf(float); +double cosh(double); +float coshf(float); long double coshl(long double); -double erf(double); -float erff(float); +double erf(double); +float erff(float); long double erfl(long double); -double erfc(double); -float erfcf(float); +double erfc(double); +float erfcf(float); long double erfcl(long double); -double exp(double); -float expf(float); +double exp(double); +float expf(float); long double expl(long double); -double exp2(double); -float exp2f(float); +double exp2(double); +float exp2f(float); long double exp2l(long double); -double expm1(double); -float expm1f(float); +double expm1(double); +float expm1f(float); long double expm1l(long double); -double fabs(double); -float fabsf(float); +double fabs(double); +float fabsf(float); long double fabsl(long double); -double fdim(double, double); -float fdimf(float, float); +double fdim(double, double); +float fdimf(float, float); long double fdiml(long double, long double); -double floor(double); -float floorf(float); +double floor(double); +float floorf(float); long double floorl(long double); -double fma(double, double, double); -float fmaf(float, float, float); +double fma(double, double, double); +float fmaf(float, float, float); long double fmal(long double, long double, long double); -double fmax(double, double); -float fmaxf(float, float); +double fmax(double, double); +float fmaxf(float, float); long double fmaxl(long double, long double); -double fmin(double, double); -float fminf(float, float); +double fmin(double, double); +float fminf(float, float); long double fminl(long double, long double); -double fmod(double, double); -float fmodf(float, float); +double fmod(double, double); +float fmodf(float, float); long double fmodl(long double, long double); -double frexp(double, int *); -float frexpf(float, int *); +double frexp(double, int *); +float frexpf(float, int *); long double frexpl(long double, int *); -double hypot(double, double); -float hypotf(float, float); +double hypot(double, double); +float hypotf(float, float); long double hypotl(long double, long double); -int ilogb(double); -int ilogbf(float); -int ilogbl(long double); +int ilogb(double); +int ilogbf(float); +int ilogbl(long double); -double ldexp(double, int); -float ldexpf(float, int); +double ldexp(double, int); +float ldexpf(float, int); long double ldexpl(long double, int); -double lgamma(double); -float lgammaf(float); +double lgamma(double); +float lgammaf(float); long double lgammal(long double); -long long llrint(double); -long long llrintf(float); -long long llrintl(long double); +long long llrint(double); +long long llrintf(float); +long long llrintl(long double); -long long llround(double); -long long llroundf(float); -long long llroundl(long double); +long long llround(double); +long long llroundf(float); +long long llroundl(long double); -double log(double); -float logf(float); +double log(double); +float logf(float); long double logl(long double); -double log10(double); -float log10f(float); +double log10(double); +float log10f(float); long double log10l(long double); -double log1p(double); -float log1pf(float); +double log1p(double); +float log1pf(float); long double log1pl(long double); -double log2(double); -float log2f(float); +double log2(double); +float log2f(float); long double log2l(long double); -double logb(double); -float logbf(float); +double logb(double); +float logbf(float); long double logbl(long double); -long lrint(double); -long lrintf(float); -long lrintl(long double); +long lrint(double); +long lrintf(float); +long lrintl(long double); -long lround(double); -long lroundf(float); -long lroundl(long double); +long lround(double); +long lroundf(float); +long lroundl(long double); -double modf(double, double *); -float modff(float, float *); +double modf(double, double *); +float modff(float, float *); long double modfl(long double, long double *); -double nan(const char *); -float nanf(const char *); +double nan(const char *); +float nanf(const char *); long double nanl(const char *); -double nearbyint(double); -float nearbyintf(float); +double nearbyint(double); +float nearbyintf(float); long double nearbyintl(long double); -double nextafter(double, double); -float nextafterf(float, float); +double nextafter(double, double); +float nextafterf(float, float); long double nextafterl(long double, long double); -double nexttoward(double, long double); -float nexttowardf(float, long double); +double nexttoward(double, long double); +float nexttowardf(float, long double); long double nexttowardl(long double, long double); -double pow(double, double); -float powf(float, float); +double pow(double, double); +float powf(float, float); long double powl(long double, long double); -double remainder(double, double); -float remainderf(float, float); +double remainder(double, double); +float remainderf(float, float); long double remainderl(long double, long double); -double remquo(double, double, int *); -float remquof(float, float, int *); +double remquo(double, double, int *); +float remquof(float, float, int *); long double remquol(long double, long double, int *); -double rint(double); -float rintf(float); +double rint(double); +float rintf(float); long double rintl(long double); -double round(double); -float roundf(float); +double round(double); +float roundf(float); long double roundl(long double); -double scalbln(double, long); -float scalblnf(float, long); +double scalbln(double, long); +float scalblnf(float, long); long double scalblnl(long double, long); -double scalbn(double, int); -float scalbnf(float, int); +double scalbn(double, int); +float scalbnf(float, int); long double scalbnl(long double, int); -double sin(double); -float sinf(float); +double sin(double); +float sinf(float); long double sinl(long double); -double sinh(double); -float sinhf(float); +double sinh(double); +float sinhf(float); long double sinhl(long double); -double sqrt(double); -float sqrtf(float); +double sqrt(double); +float sqrtf(float); long double sqrtl(long double); -double tan(double); -float tanf(float); +double tan(double); +float tanf(float); long double tanl(long double); -double tanh(double); -float tanhf(float); +double tanh(double); +float tanhf(float); long double tanhl(long double); -double tgamma(double); -float tgammaf(float); +double tgamma(double); +float tgammaf(float); long double tgammal(long double); -double trunc(double); -float truncf(float); +double trunc(double); +float truncf(float); long double truncl(long double); - #if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) -#undef MAXFLOAT -#define MAXFLOAT 3.40282346638528859812e+38F +#undef MAXFLOAT +#define MAXFLOAT 3.40282346638528859812e+38F #endif #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#define M_E 2.7182818284590452354 /* e */ -#define M_LOG2E 1.4426950408889634074 /* log_2 e */ -#define M_LOG10E 0.43429448190325182765 /* log_10 e */ -#define M_LN2 0.69314718055994530942 /* log_e 2 */ -#define M_LN10 2.30258509299404568402 /* log_e 10 */ -#define M_PI 3.14159265358979323846 /* pi */ -#define M_PI_2 1.57079632679489661923 /* pi/2 */ -#define M_PI_4 0.78539816339744830962 /* pi/4 */ -#define M_1_PI 0.31830988618379067154 /* 1/pi */ -#define M_2_PI 0.63661977236758134308 /* 2/pi */ -#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#define M_E 2.7182818284590452354 /* e */ +#define M_LOG2E 1.4426950408889634074 /* log_2 e */ +#define M_LOG10E 0.43429448190325182765 /* log_10 e */ +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#define M_PI 3.14159265358979323846 /* pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_1_PI 0.31830988618379067154 /* 1/pi */ +#define M_2_PI 0.63661977236758134308 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ extern int signgam; -double j0(double); -double j1(double); -double jn(int, double); +double j0(double); +double j1(double); +double jn(int, double); -double y0(double); -double y1(double); -double yn(int, double); +double y0(double); +double y1(double); +double yn(int, double); #endif #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#define HUGE 3.40282346638528859812e+38F +#define HUGE 3.40282346638528859812e+38F -double drem(double, double); -float dremf(float, float); +double drem(double, double); +float dremf(float, float); -int finite(double); -int finitef(float); +int finite(double); +int finitef(float); -double scalb(double, double); -float scalbf(float, float); +double scalb(double, double); +float scalbf(float, float); -double significand(double); -float significandf(float); +double significand(double); +float significandf(float); -double lgamma_r(double, int*); -float lgammaf_r(float, int*); +double lgamma_r(double, int *); +float lgammaf_r(float, int *); -float j0f(float); -float j1f(float); -float jnf(int, float); +float j0f(float); +float j1f(float); +float jnf(int, float); -float y0f(float); -float y1f(float); -float ynf(int, float); +float y0f(float); +float y1f(float); +float ynf(int, float); #endif #ifdef _GNU_SOURCE -long double lgammal_r(long double, int*); +long double lgammal_r(long double, int *); -void sincos(double, double*, double*); -void sincosf(float, float*, float*); -void sincosl(long double, long double*, long double*); +void sincos(double, double *, double *); +void sincosf(float, float *, float *); +void sincosl(long double, long double *, long double *); -double exp10(double); -float exp10f(float); +double exp10(double); +float exp10f(float); long double exp10l(long double); -double pow10(double); -float pow10f(float); +double pow10(double); +float pow10f(float); long double pow10l(long double); #endif diff --git a/c/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected b/c/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected index bf440fe311..9059b0d815 100644 --- a/c/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected +++ b/c/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected @@ -1,18 +1,30 @@ -| test.c:4:3:4:6 | call to acos | Domain error in call to acos: the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | -| test.c:8:3:8:6 | call to acos | Domain error in call to acos: the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | -| test.c:9:3:9:6 | call to asin | Domain error in call to asin: the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | -| test.c:13:3:13:6 | call to asin | Domain error in call to asin: the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | -| test.c:14:3:14:7 | call to atanh | Domain error in call to atanh: the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | -| test.c:18:3:18:7 | call to atanh | Domain error in call to atanh: the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | -| test.c:19:3:19:7 | call to atan2 | Domain error in call to atan2: both arguments are equal to zero. | -| test.c:23:3:23:5 | call to pow | Domain error in call to pow: both arguments are equal to zero. | -| test.c:27:3:27:5 | call to pow | Domain error in call to pow: both arguments are less than zero. | -| test.c:33:3:33:7 | call to acosh | Domain error in call to acosh: argument is less than 1. | -| test.c:34:3:34:7 | call to ilogb | Domain error in call to ilogb: argument is equal to zero. | -| test.c:37:3:37:5 | call to log | Domain error in call to log: argument is negative. | -| test.c:40:3:40:7 | call to log10 | Domain error in call to log10: argument is negative. | -| test.c:43:3:43:6 | call to log2 | Domain error in call to log2: argument is negative. | -| test.c:46:3:46:6 | call to sqrt | Domain error in call to sqrt: argument is negative. | -| test.c:49:3:49:7 | call to log1p | Domain error in call to log1p: argument is less than 1. | -| test.c:52:3:52:6 | call to logb | Domain error in call to logb: argument is equal to zero. | -| test.c:55:3:55:8 | call to tgamma | Domain error in call to tgamma: argument is equal to zero. | +| test.c:6:3:6:6 | call to acos | Domain error in call to 'acos': the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | +| test.c:10:3:10:6 | call to acos | Domain error in call to 'acos': the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | +| test.c:11:3:11:6 | call to asin | Domain error in call to 'asin': the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | +| test.c:15:3:15:6 | call to asin | Domain error in call to 'asin': the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | +| test.c:16:3:16:7 | call to atanh | Domain error in call to 'atanh': the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | +| test.c:18:3:18:7 | call to atanh | Domain error in call to 'atanh': the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | +| test.c:19:3:19:7 | call to atan2 | Domain error in call to 'atan2': both arguments are equal to zero. | +| test.c:23:3:23:5 | call to pow | Domain error in call to 'pow': both arguments are equal to zero. | +| test.c:27:3:27:5 | call to pow | Domain error in call to 'pow': both arguments are less than zero. | +| test.c:32:3:32:7 | call to acosh | Domain error in call to 'acosh': argument is less than 1. | +| test.c:33:3:33:7 | call to ilogb | Domain error in call to 'ilogb': argument is equal to zero. | +| test.c:36:3:36:5 | call to log | Domain error in call to 'log': argument is negative. | +| test.c:38:3:38:7 | call to log10 | Domain error in call to 'log10': argument is negative. | +| test.c:40:3:40:6 | call to log2 | Domain error in call to 'log2': argument is negative. | +| test.c:42:3:42:6 | call to sqrt | Domain error in call to 'sqrt': argument is negative. | +| test.c:45:3:45:7 | call to log1p | Domain error in call to 'log1p': argument is less than 1. | +| test.c:47:3:47:6 | call to logb | Domain error in call to 'logb': argument is equal to zero. | +| test.c:50:3:50:8 | call to tgamma | Domain error in call to 'tgamma': argument is equal to zero. | +| test.c:56:3:56:5 | call to abs | Range error in call to 'abs': argument is most negative number. | +| test.c:57:3:57:6 | call to fmod | Domain error in call to 'fmod': y is 0. | +| test.c:59:3:59:7 | call to frexp | Unspecified error in call to 'frexp': Arg is Nan or infinity and exp is unspecified as a result. | +| test.c:60:3:60:7 | call to frexp | Unspecified error in call to 'frexp': Arg is Nan or infinity and exp is unspecified as a result. | +| test.c:64:3:64:7 | call to atanh | Pole error in call to 'atanh': argument is plus or minus 1. | +| test.c:65:3:65:7 | call to atanh | Pole error in call to 'atanh': argument is plus or minus 1. | +| test.c:66:3:66:5 | call to log | Pole error in call to 'log': argument is equal to zero. | +| test.c:67:3:67:7 | call to log10 | Pole error in call to 'log10': argument is equal to zero. | +| test.c:68:3:68:6 | call to log2 | Pole error in call to 'log2': argument is equal to zero. | +| test.c:69:3:69:7 | call to log1p | Pole error in call to 'log1p': argument is equal to negative one. | +| test.c:71:3:71:5 | call to pow | Pole error in call to 'pow': base is zero and exp is negative. | +| test.c:72:3:72:8 | call to lgamma | Pole error in call to 'lgamma': argument is equal to zero. | diff --git a/c/common/test/rules/uncheckedrangedomainpoleerrors/test.c b/c/common/test/rules/uncheckedrangedomainpoleerrors/test.c index 47d7b1e683..ab34302f21 100644 --- a/c/common/test/rules/uncheckedrangedomainpoleerrors/test.c +++ b/c/common/test/rules/uncheckedrangedomainpoleerrors/test.c @@ -1,6 +1,8 @@ +#include #include +#include -void test() { +void test_domain_errors() { acos(-1.1f); // NON_COMPLIANT acos(-1.0f); // COMPLIANT acos(0.0f); // COMPLIANT @@ -12,9 +14,7 @@ void test() { asin(1.0f); // COMPLIANT asin(1.1f); // NON_COMPLIANT atanh(-1.1f); // NON_COMPLIANT - atanh(-1.0f); // COMPLIANT atanh(0.0f); // COMPLIANT - atanh(1.0f); // COMPLIANT atanh(1.1f); // NON_COMPLIANT atan2(0.0f, 0.0f); // NON_COMPLIANT atan2(1.0f, 0.0f); // COMPLIANT @@ -26,7 +26,6 @@ void test() { pow(1.0f, 1.0f); // COMPLIANT pow(-1.0f, -1.0f); // NON_COMPLIANT pow(-1.0f, 0.0f); // COMPLIANT - pow(0.0f, -1.0f); // COMPLIANT pow(1.0f, -1.0f); // COMPLIANT pow(-1.0f, 1.0f); // COMPLIANT acosh(1.0f); // COMPLIANT @@ -35,19 +34,15 @@ void test() { ilogb(1.0f); // COMPLIANT ilogb(-1.0f); // COMPLIANT log(-1.0f); // NON_COMPLIANT - log(0.0f); // COMPLIANT log(1.0f); // COMPLIANT log10(-1.0f); // NON_COMPLIANT - log10(0.0f); // COMPLIANT log10(1.0f); // COMPLIANT log2(-1.0f); // NON_COMPLIANT - log2(0.0f); // COMPLIANT log2(1.0f); // COMPLIANT sqrt(-1.0f); // NON_COMPLIANT sqrt(0.0f); // COMPLIANT sqrt(1.0f); // COMPLIANT log1p(-2.0f); // NON_COMPLIANT - log1p(-1.0f); // COMPLIANT log1p(0.0f); // COMPLIANT logb(0.0f); // NON_COMPLIANT logb(1.0f); // COMPLIANT @@ -56,3 +51,24 @@ void test() { tgamma(1.0f); // COMPLIANT tgamma(-1.1f); // COMPLIANT } + +void fn_in_193_missing_domain_or_range_cases() { + abs(INT_MIN); // NON_COMPLIANT + fmod(1.0f, 0.0f); // NON_COMPLIANT + int *exp; + frexp(NAN, exp); // NON_COMPLIANT + frexp(INFINITY, exp); // NON_COMPLIANT +} + +void test_pole_errors() { + atanh(-1.0f); // NON_COMPLIANT + atanh(1.0f); // NON_COMPLIANT + log(0.0f); // NON_COMPLIANT + log10(0.0f); // NON_COMPLIANT + log2(0.0f); // NON_COMPLIANT + log1p(-1.0f); // NON_COMPLIANT + // logb(x) already covered in domain cases + pow(0.0f, -1.0f); // NON_COMPLIANT + lgamma(0.0f); // NON_COMPLIANT + lgamma(-1); // NON_COMPLIANT[FALSE_NEGATIVE] +} \ No newline at end of file diff --git a/change_notes/2024-04-23-fix-fp-193.md b/change_notes/2024-04-23-fix-fp-193.md new file mode 100644 index 0000000000..1a89edf190 --- /dev/null +++ b/change_notes/2024-04-23-fix-fp-193.md @@ -0,0 +1,2 @@ +- `A0-4-4`,`FLP32-C` - `UncheckedRangeDomainPoleErrors.ql`: + - Fixes #193. Adds missing cases for domain errors, an unspecified result case and pole error cases. \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.qll b/cpp/common/src/codingstandards/cpp/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.qll index 13a937151c..ad93f70bd4 100644 --- a/cpp/common/src/codingstandards/cpp/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.qll +++ b/cpp/common/src/codingstandards/cpp/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.qll @@ -42,6 +42,7 @@ predicate hasDomainError(FunctionCall fc, string description) { upperBound(fc.getArgument(0)) < 1.0 and description = "argument is less than 1" or + //pole error is the same as domain for logb and tgamma (but not ilogb - no pole error exists) functionWithDomainError = getMathVariants(["ilogb", "logb", "tgamma"]) and fc.getArgument(0).getValue().toFloat() = 0 and description = "argument is equal to zero" @@ -53,18 +54,95 @@ predicate hasDomainError(FunctionCall fc, string description) { functionWithDomainError = getMathVariants("log1p") and upperBound(fc.getArgument(0)) < -1.0 and description = "argument is less than 1" + or + functionWithDomainError = getMathVariants("fmod") and + fc.getArgument(1).getValue().toFloat() = 0 and + description = "y is 0" ) } +predicate hasRangeError(FunctionCall fc, string description) { + exists(Function functionWithRangeError | fc.getTarget() = functionWithRangeError | + functionWithRangeError.hasGlobalOrStdName(["abs", "labs", "llabs", "imaxabs"]) and + fc.getArgument(0) = any(MINMacro m).getAnInvocation().getExpr() and + description = "argument is most negative number" + ) +} + +predicate hasPoleError(FunctionCall fc, string description) { + exists(Function functionWithPoleError | fc.getTarget() = functionWithPoleError | + functionWithPoleError = getMathVariants("atanh") and + ( + fc.getArgument(0).getValue().toFloat() = -1.0 + or + fc.getArgument(0).getValue().toFloat() = 1.0 + ) and + description = "argument is plus or minus 1" + or + functionWithPoleError = getMathVariants("log1p") and + fc.getArgument(0).getValue().toFloat() = -1 and + description = "argument is equal to negative one" + or + functionWithPoleError = getMathVariants("pow") and + fc.getArgument(0).getValue().toFloat() = 0.0 and + fc.getArgument(1).getValue().toFloat() < 0.0 and + description = "base is zero and exp is negative" + or + functionWithPoleError = getMathVariants("lgamma") and + fc.getArgument(0).getValue().toFloat() = 0 and + description = "argument is equal to zero" + or + functionWithPoleError = getMathVariants(["log", "log10", "log2"]) and + fc.getArgument(0).getValue().toFloat() = 0.0 and + description = "argument is equal to zero" + ) +} + +predicate unspecifiedValueCases(FunctionCall fc, string description) { + exists(Function functionWithUnspecifiedResultError | + fc.getTarget() = functionWithUnspecifiedResultError + | + functionWithUnspecifiedResultError = getMathVariants("frexp") and + ( + fc.getArgument(0) = any(InfinityMacro m).getAnInvocation().getExpr() or + fc.getArgument(0) = any(NanMacro m).getAnInvocation().getExpr() + ) and + description = "Arg is Nan or infinity and exp is unspecified as a result" + ) +} + +/** + * A macro which is representing infinity + */ +class InfinityMacro extends Macro { + InfinityMacro() { this.getName().toLowerCase().matches("infinity") } +} + +/** + * A macro which is representing nan + */ +class NanMacro extends Macro { + NanMacro() { this.getName().toLowerCase().matches("nan") } +} + +/** + * A macro which is representing INT_MIN or LONG_MIN or LLONG_MIN + */ +class MINMacro extends Macro { + MINMacro() { this.getName().toLowerCase().matches(["int_min", "long_min", "llong_min"]) } +} + /* * Domain cases not covered by this query: * - pow - x is finite and negative and y is finite and not an integer value. * - tgamma - negative integer can't be covered. * - lrint/llrint/lround/llround - no domain errors checked - * - fmod - no domain errors checked. * - remainder - no domain errors checked. * - remquo - no domain errors checked. * + * Pole cases not covered by this query: + * - lgamma - negative integer can't be covered. + * * Implementations may also define their own domain errors (as per the C99 standard), which are not * covered by this query. */ @@ -73,6 +151,16 @@ query predicate problems(FunctionCall fc, string message) { not isExcluded(fc, getQuery()) and exists(string description | hasDomainError(fc, description) and - message = "Domain error in call to " + fc.getTarget().getName() + ": " + description + "." + message = "Domain error in call to '" + fc.getTarget().getName() + "': " + description + "." + or + hasRangeError(fc, description) and + message = "Range error in call to '" + fc.getTarget().getName() + "': " + description + "." + or + hasPoleError(fc, description) and + message = "Pole error in call to '" + fc.getTarget().getName() + "': " + description + "." + or + unspecifiedValueCases(fc, description) and + message = + "Unspecified error in call to '" + fc.getTarget().getName() + "': " + description + "." ) } diff --git a/cpp/common/test/includes/standard-library/limits.h b/cpp/common/test/includes/standard-library/limits.h index 5317339525..f7d490c181 100644 --- a/cpp/common/test/includes/standard-library/limits.h +++ b/cpp/common/test/includes/standard-library/limits.h @@ -23,6 +23,8 @@ #define LLONG_MAX 9223372036854775807 #define ULLONG_MIN 0ULL #define ULLONG_MAX 0xffffffffffffffff +#define NAN (0.0f / 0.0f) +#define INFINITY 1e5000f namespace std { template class numeric_limits; diff --git a/cpp/common/test/includes/standard-library/math.h b/cpp/common/test/includes/standard-library/math.h index 563f6e7823..460c0a9c2f 100644 --- a/cpp/common/test/includes/standard-library/math.h +++ b/cpp/common/test/includes/standard-library/math.h @@ -1,5 +1,7 @@ #ifndef _GHLIBCPP_MATH #define _GHLIBCPP_MATH +int abs(int x); +long abs(long x); double acos(double x); float acosf(float x); long double acosl(long double x); @@ -15,9 +17,18 @@ long double acoshl(long double x); double atanh(double x); float atanhf(float x); long double atanhl(long double x); +double fmod(double x, double y); +float fmodf(float x, float y); +long double fmodl(long double x, long double y); +double frexp(double x, int *y); +float frexpf(float x, int *y); +long double frexpl(long double, int *); int ilogb(double x); int ilogbf(float x); int ilogbl(long double x); +double lgamma(double x); +float lgammaf(float x); +long double lgammal(long double x); double log(double x); float logf(float x); long double logl(long double x); diff --git a/cpp/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected b/cpp/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected index 3e99c4cd56..4bbdb307ff 100644 --- a/cpp/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected +++ b/cpp/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.expected @@ -1,18 +1,30 @@ -| test.cpp:4:3:4:6 | call to acos | Domain error in call to acos: the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | -| test.cpp:8:3:8:6 | call to acos | Domain error in call to acos: the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | -| test.cpp:9:3:9:6 | call to asin | Domain error in call to asin: the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | -| test.cpp:13:3:13:6 | call to asin | Domain error in call to asin: the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | -| test.cpp:14:3:14:7 | call to atanh | Domain error in call to atanh: the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | -| test.cpp:18:3:18:7 | call to atanh | Domain error in call to atanh: the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | -| test.cpp:19:3:19:7 | call to atan2 | Domain error in call to atan2: both arguments are equal to zero. | -| test.cpp:23:3:23:5 | call to pow | Domain error in call to pow: both arguments are equal to zero. | -| test.cpp:27:3:27:5 | call to pow | Domain error in call to pow: both arguments are less than zero. | -| test.cpp:33:3:33:7 | call to acosh | Domain error in call to acosh: argument is less than 1. | -| test.cpp:34:3:34:7 | call to ilogb | Domain error in call to ilogb: argument is equal to zero. | -| test.cpp:37:3:37:5 | call to log | Domain error in call to log: argument is negative. | -| test.cpp:40:3:40:7 | call to log10 | Domain error in call to log10: argument is negative. | -| test.cpp:43:3:43:6 | call to log2 | Domain error in call to log2: argument is negative. | -| test.cpp:46:3:46:6 | call to sqrt | Domain error in call to sqrt: argument is negative. | -| test.cpp:49:3:49:7 | call to log1p | Domain error in call to log1p: argument is less than 1. | -| test.cpp:52:3:52:6 | call to logb | Domain error in call to logb: argument is equal to zero. | -| test.cpp:55:3:55:8 | call to tgamma | Domain error in call to tgamma: argument is equal to zero. | +| test.cpp:5:3:5:6 | call to acos | Domain error in call to 'acos': the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | +| test.cpp:9:3:9:6 | call to acos | Domain error in call to 'acos': the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | +| test.cpp:10:3:10:6 | call to asin | Domain error in call to 'asin': the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | +| test.cpp:14:3:14:6 | call to asin | Domain error in call to 'asin': the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | +| test.cpp:15:3:15:7 | call to atanh | Domain error in call to 'atanh': the argument has a range -1.1...-1.1 which is outside the domain of this function (-1.0...1.0). | +| test.cpp:17:3:17:7 | call to atanh | Domain error in call to 'atanh': the argument has a range 1.1...1.1 which is outside the domain of this function (-1.0...1.0). | +| test.cpp:18:3:18:7 | call to atan2 | Domain error in call to 'atan2': both arguments are equal to zero. | +| test.cpp:22:3:22:5 | call to pow | Domain error in call to 'pow': both arguments are equal to zero. | +| test.cpp:26:3:26:5 | call to pow | Domain error in call to 'pow': both arguments are less than zero. | +| test.cpp:31:3:31:7 | call to acosh | Domain error in call to 'acosh': argument is less than 1. | +| test.cpp:32:3:32:7 | call to ilogb | Domain error in call to 'ilogb': argument is equal to zero. | +| test.cpp:35:3:35:5 | call to log | Domain error in call to 'log': argument is negative. | +| test.cpp:37:3:37:7 | call to log10 | Domain error in call to 'log10': argument is negative. | +| test.cpp:39:3:39:6 | call to log2 | Domain error in call to 'log2': argument is negative. | +| test.cpp:41:3:41:6 | call to sqrt | Domain error in call to 'sqrt': argument is negative. | +| test.cpp:44:3:44:7 | call to log1p | Domain error in call to 'log1p': argument is less than 1. | +| test.cpp:46:3:46:6 | call to logb | Domain error in call to 'logb': argument is equal to zero. | +| test.cpp:49:3:49:8 | call to tgamma | Domain error in call to 'tgamma': argument is equal to zero. | +| test.cpp:55:3:55:5 | call to abs | Range error in call to 'abs': argument is most negative number. | +| test.cpp:56:3:56:6 | call to fmod | Domain error in call to 'fmod': y is 0. | +| test.cpp:58:3:58:7 | call to frexp | Unspecified error in call to 'frexp': Arg is Nan or infinity and exp is unspecified as a result. | +| test.cpp:59:3:59:7 | call to frexp | Unspecified error in call to 'frexp': Arg is Nan or infinity and exp is unspecified as a result. | +| test.cpp:63:3:63:7 | call to atanh | Pole error in call to 'atanh': argument is plus or minus 1. | +| test.cpp:64:3:64:7 | call to atanh | Pole error in call to 'atanh': argument is plus or minus 1. | +| test.cpp:65:3:65:5 | call to log | Pole error in call to 'log': argument is equal to zero. | +| test.cpp:66:3:66:7 | call to log10 | Pole error in call to 'log10': argument is equal to zero. | +| test.cpp:67:3:67:6 | call to log2 | Pole error in call to 'log2': argument is equal to zero. | +| test.cpp:68:3:68:7 | call to log1p | Pole error in call to 'log1p': argument is equal to negative one. | +| test.cpp:70:3:70:5 | call to pow | Pole error in call to 'pow': base is zero and exp is negative. | +| test.cpp:71:3:71:8 | call to lgamma | Pole error in call to 'lgamma': argument is equal to zero. | diff --git a/cpp/common/test/rules/uncheckedrangedomainpoleerrors/test.cpp b/cpp/common/test/rules/uncheckedrangedomainpoleerrors/test.cpp index 63f53b8a41..d194702e83 100644 --- a/cpp/common/test/rules/uncheckedrangedomainpoleerrors/test.cpp +++ b/cpp/common/test/rules/uncheckedrangedomainpoleerrors/test.cpp @@ -1,6 +1,7 @@ +#include "limits.h" #include "math.h" -void test() { +void test_domain_errors() { acos(-1.1f); // NON_COMPLIANT acos(-1.0f); // COMPLIANT acos(0.0f); // COMPLIANT @@ -12,9 +13,7 @@ void test() { asin(1.0f); // COMPLIANT asin(1.1f); // NON_COMPLIANT atanh(-1.1f); // NON_COMPLIANT - atanh(-1.0f); // COMPLIANT atanh(0.0f); // COMPLIANT - atanh(1.0f); // COMPLIANT atanh(1.1f); // NON_COMPLIANT atan2(0.0f, 0.0f); // NON_COMPLIANT atan2(1.0f, 0.0f); // COMPLIANT @@ -26,7 +25,6 @@ void test() { pow(1.0f, 1.0f); // COMPLIANT pow(-1.0f, -1.0f); // NON_COMPLIANT pow(-1.0f, 0.0f); // COMPLIANT - pow(0.0f, -1.0f); // COMPLIANT pow(1.0f, -1.0f); // COMPLIANT pow(-1.0f, 1.0f); // COMPLIANT acosh(1.0f); // COMPLIANT @@ -35,19 +33,15 @@ void test() { ilogb(1.0f); // COMPLIANT ilogb(-1.0f); // COMPLIANT log(-1.0f); // NON_COMPLIANT - log(0.0f); // COMPLIANT log(1.0f); // COMPLIANT log10(-1.0f); // NON_COMPLIANT - log10(0.0f); // COMPLIANT log10(1.0f); // COMPLIANT log2(-1.0f); // NON_COMPLIANT - log2(0.0f); // COMPLIANT log2(1.0f); // COMPLIANT sqrt(-1.0f); // NON_COMPLIANT sqrt(0.0f); // COMPLIANT sqrt(1.0f); // COMPLIANT log1p(-2.0f); // NON_COMPLIANT - log1p(-1.0f); // COMPLIANT log1p(0.0f); // COMPLIANT logb(0.0f); // NON_COMPLIANT logb(1.0f); // COMPLIANT @@ -56,3 +50,24 @@ void test() { tgamma(1.0f); // COMPLIANT tgamma(-1.1f); // COMPLIANT } + +void fn_in_193_missing_domain_or_range_cases() { + abs(INT_MIN); // NON_COMPLIANT + fmod(1.0f, 0.0f); // NON_COMPLIANT + int *exp; + frexp(NAN, exp); // NON_COMPLIANT + frexp(INFINITY, exp); // NON_COMPLIANT +} + +void test_pole_errors() { + atanh(-1.0f); // NON_COMPLIANT + atanh(1.0f); // NON_COMPLIANT + log(0.0f); // NON_COMPLIANT + log10(0.0f); // NON_COMPLIANT + log2(0.0f); // NON_COMPLIANT + log1p(-1.0f); // NON_COMPLIANT + // logb(x) already covered in domain cases + pow(0.0f, -1.0f); // NON_COMPLIANT + lgamma(0.0f); // NON_COMPLIANT + lgamma(-1); // NON_COMPLIANT[FALSE_NEGATIVE] +} \ No newline at end of file