From 143b4d3f64e0828a3b03dd9ed997dd5412c2b25a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 10 Aug 2018 19:36:16 +0200 Subject: [PATCH] Fix wrong behaviour of torad_coord() with gcc 8.1 -O2 (fixes #1084) torad_coord() of gie.c has this sequence: ``` if( cond ) axis = l->param + strlen ("axis="); n = strlen (axis); ``` When the if branch is evaluated, n is always zero even if on inspection axis is non empty The reason is that the struct ARG_list which is the type of l use a variable-length array for the param member struct ARG_list { paralist *next; char used; char param[1]; }; But this is not a proper way of declaring it, and gcc 8 has apparently optimizations to detect that l->param + 5 points out of the array, hence it optimizes strlen() to 0. Reported as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86914 According to https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html, the proper way of declaring such arrays is to use [0] --- src/pj_param.c | 2 +- src/projects.h | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pj_param.c b/src/pj_param.c index 6cee4d1fba..7ed0e37716 100644 --- a/src/pj_param.c +++ b/src/pj_param.c @@ -42,7 +42,7 @@ paralist *pj_mkparam_ws (char *str) { } /* Use calloc to automagically 0-terminate the copy */ - newitem = (paralist *) pj_calloc (1, sizeof(paralist) + len); + newitem = (paralist *) pj_calloc (1, sizeof(paralist) + len + 1); if (0==newitem) return 0; memmove(newitem->param, str, len); diff --git a/src/projects.h b/src/projects.h index 2dc073fa73..928985f65a 100644 --- a/src/projects.h +++ b/src/projects.h @@ -458,7 +458,12 @@ struct PJconsts { struct ARG_list { paralist *next; char used; - char param[1]; +#ifdef __GNUC__ + char param[0]; /* variable-length member */ + /* Safer to use [0] for gcc. See /~https://github.com/OSGeo/proj.4/pull/1087 */ +#else + char param[1]; /* variable-length member */ +#endif };