aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Karney <charles@karney.com>2018-03-19 09:53:34 -0400
committerGitHub <noreply@github.com>2018-03-19 09:53:34 -0400
commita2c0a414f75af15a4b9e53d92adf91e8131fb5f2 (patch)
tree3953bbc413a1c5f05ac548dbaf27d5371e7ef97f
parentdb3e0ae30446498cec7e7f931d9be2ed65547691 (diff)
parent6978bd29ce1e6ced6cdc224dbbff9ed7fe3dcb05 (diff)
downloadPROJ-a2c0a414f75af15a4b9e53d92adf91e8131fb5f2.tar.gz
PROJ-a2c0a414f75af15a4b9e53d92adf91e8131fb5f2.zip
Merge pull request #868 from cffk/geod-1.49.3
Patch 1.49.3 for geodesic package. Closes #826, partially closes #843.
-rw-r--r--CMakeLists.txt12
-rw-r--r--configure.ac6
-rw-r--r--m4/ax_check_compile_flag.m474
-rw-r--r--src/geodesic.c45
-rw-r--r--src/geodesic.h2
-rw-r--r--src/geodtest.c3
6 files changed, 124 insertions, 18 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d1baef0..8a60b540 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,6 +33,18 @@ elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
-Wfloat-conversion ${CMAKE_C_FLAGS}")
endif()
+# Tell Intel compiler to do arithmetic accurately. This is needed to
+# stop the compiler from ignoring parentheses in expressions like
+# (a + b) + c and from simplifying 0.0 + x to x (which is wrong if
+# x = -0.0).
+if (CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ if (MSVC)
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fp:precise")
+ else ()
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprotect-parens -fsigned-zeros")
+ endif ()
+endif ()
+
#################################################################################
# PROJ4 CMake modules
#################################################################################
diff --git a/configure.ac b/configure.ac
index 898d8b3b..ee5fc507 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,12 @@ CFLAGS="$save_CFLAGS"
dnl We check for headers
AC_HEADER_STDC
+dnl Check flag for accurate arithmetic with Intel compiler. This is
+dnl needed to stop the compiler from ignoring parentheses in expressions
+dnl like (a + b) + c and from simplifying 0.0 + x to x (which is wrong if
+dnl x = -0.0).
+AX_CHECK_COMPILE_FLAG([-fprotect-parens -fsigned-zeros],
+ [CFLAGS="$CFLAGS -fprotect-parens -fsigned-zeros"],,[-Werror])
dnl Check for C99 math functions
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wall -Werror"
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 00000000..dcabb92a
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 5
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/src/geodesic.c b/src/geodesic.c
index 40dffbc1..91af23f9 100644
--- a/src/geodesic.c
+++ b/src/geodesic.c
@@ -193,12 +193,12 @@ static real AngNormalize(real x) {
real y = fmod(x, (real)(360));
#if defined(_MSC_VER) && _MSC_VER < 1900
/*
- Before version 14 (2015), Visual Studio had problems dealing
- with -0.0. Specifically
- VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
- sincosdx has a similar fix.
- python 2.7 on Windows 32-bit machines has the same problem.
- */
+ * Before version 14 (2015), Visual Studio had problems dealing
+ * with -0.0. Specifically
+ * VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
+ * sincosdx has a similar fix.
+ * python 2.7 on Windows 32-bit machines has the same problem.
+ */
if (x == 0) y = x;
#endif
return y <= -180 ? y + 360 : (y <= 180 ? y : y - 360);
@@ -239,7 +239,8 @@ static void sincosdx(real x, real* sinx, real* cosx) {
r = remquo(x, (real)(90), &q);
#else
r = fmod(x, (real)(360));
- q = (int)(floor(r / 90 + (real)(0.5)));
+ /* check for NaN */
+ q = r == r ? (int)(floor(r / 90 + (real)(0.5))) : 0;
r -= 90 * q;
#endif
/* now abs(r) <= 45 */
@@ -248,13 +249,13 @@ static void sincosdx(real x, real* sinx, real* cosx) {
s = sin(r); c = cos(r);
#if defined(_MSC_VER) && _MSC_VER < 1900
/*
- Before version 14 (2015), Visual Studio had problems dealing
- with -0.0. Specifically
- VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
- VC 12 and 64-bit compile: sin(-0.0) -> +0.0
- AngNormalize has a similar fix.
- python 2.7 on Windows 32-bit machines has the same problem.
- */
+ * Before version 14 (2015), Visual Studio had problems dealing
+ * with -0.0. Specifically
+ * VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0
+ * VC 12 and 64-bit compile: sin(-0.0) -> +0.0
+ * AngNormalize has a similar fix.
+ * python 2.7 on Windows 32-bit machines has the same problem.
+ */
if (x == 0) s = x;
#endif
switch ((unsigned)q & 3U) {
@@ -658,6 +659,14 @@ real geod_genposition(const struct geod_geodesicline* l,
S12 = l->c2 * atan2(salp12, calp12) + l->A4 * (B42 - l->B41);
}
+ /* In the pattern
+ *
+ * if ((outmask & GEOD_XX) && pYY)
+ * *pYY = YY;
+ *
+ * the second check "&& pYY" is redundant. It's there to make the CLang
+ * static analyzer happy.
+ */
if ((outmask & GEOD_LATITUDE) && plat2)
*plat2 = lat2;
if ((outmask & GEOD_LONGITUDE) && plon2)
@@ -1127,7 +1136,7 @@ real SinCosSeries(boolx sinp, real sinx, real cosx, const real c[], int n) {
real ar, y0, y1;
c += (n + sinp); /* Point to one beyond last element */
ar = 2 * (cosx - sinx) * (cosx + sinx); /* 2 * cos(2 * x) */
- y0 = (n & 1) ? *--c : 0; y1 = 0; /* accumulators for sum */
+ y0 = (n & 1) ? *--c : 0; y1 = 0; /* accumulators for sum */
/* Now n is even */
n /= 2;
while (n--) {
@@ -1894,7 +1903,9 @@ void geod_polygon_addedge(const struct geod_geodesic* g,
struct geod_polygon* p,
real azi, real s) {
if (p->num) { /* Do nothing is num is zero */
- real lat = 0, lon = 0, S12 = 0; /* Initialize S12 to stop Visual Studio warning */
+ /* Initialize S12 to stop Visual Studio warning. Initialization of lat and
+ * lon is to make CLang static analyzer happy. */
+ real lat = 0, lon = 0, S12 = 0;
geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
&lat, &lon, 0,
0, 0, 0, 0, p->polyline ? 0 : &S12);
@@ -2031,6 +2042,8 @@ unsigned geod_polygon_testedge(const struct geod_geodesic* g,
tempsum = p->A[0];
crossings = p->crossings;
{
+ /* Initialization of lat, lon, and S12 is to make CLang static analyzer
+ happy. */
real lat = 0, lon = 0, s12, S12 = 0;
geod_gendirect(g, p->lat, p->lon, azi, GEOD_LONG_UNROLL, s,
&lat, &lon, 0,
diff --git a/src/geodesic.h b/src/geodesic.h
index cd7c2b70..f9d612f3 100644
--- a/src/geodesic.h
+++ b/src/geodesic.h
@@ -132,7 +132,7 @@
* The patch level of the geodesic library. (This tracks the version of
* GeographicLib.)
**********************************************************************/
-#define GEODESIC_VERSION_PATCH 2
+#define GEODESIC_VERSION_PATCH 3
/**
* Pack the version components into a single integer. Users should not rely on
diff --git a/src/geodtest.c b/src/geodtest.c
index 8cc48134..1025ce08 100644
--- a/src/geodtest.c
+++ b/src/geodtest.c
@@ -616,7 +616,8 @@ static int GeodSolve73() {
&lat2, &lon2, &azi2);
result += assertEquals(lat2, 81.04623, 0.5e-5);
result += assertEquals(lon2, -170, 0.5e-5);
- result += assertEquals(azi2, 0, 0.5e-5);
+ result += azi2 == 0 ? 0 : 1;
+ result += 1/azi2 > 0 ? 0 : 1; /* Check that azi2 = +0.0 not -0.0 */
return result;
}