From 1a7dd2332df9f5e4d98f52d89d663e520993d54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Wed, 22 Jul 2020 17:37:45 +0200 Subject: [PATCH 01/16] added test for reading virtual datasets --- nc_test4/CMakeLists.txt | 2 +- nc_test4/tst_virtual_datasets.c | 85 +++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 nc_test4/tst_virtual_datasets.c diff --git a/nc_test4/CMakeLists.txt b/nc_test4/CMakeLists.txt index 5dd5a85ca3..3198de24c8 100644 --- a/nc_test4/CMakeLists.txt +++ b/nc_test4/CMakeLists.txt @@ -20,7 +20,7 @@ SET(NC4_TESTS tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_files6 tst_sync tst_h_strbug tst_h_refs tst_h_scalar tst_rename tst_rename2 tst_rename3 tst_h5_endians tst_atts_string_rewrite tst_put_vars_two_unlim_dim tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash tst_types tst_bug324 - tst_atts3 tst_put_vars tst_elatefill tst_udf tst_bug1442) + tst_atts3 tst_put_vars tst_elatefill tst_udf tst_bug1442 tst_virtual_datasets) # Note, renamegroup needs to be compiled before run_grp_rename diff --git a/nc_test4/tst_virtual_datasets.c b/nc_test4/tst_virtual_datasets.c new file mode 100644 index 0000000000..77349693f8 --- /dev/null +++ b/nc_test4/tst_virtual_datasets.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include "err_macros.h" + +#define FILE_NAME_A "tst_virtual_a.nc" +#define FILE_NAME_B "tst_virtual_b.nc" +#define VARIABLE_SIZE 5 +#define VARIABLE_NAME "v" + +static void +create_dataset_a() { + hsize_t dims[1] = {VARIABLE_SIZE}; + float data[VARIABLE_SIZE]; + for(size_t i = 0; i < VARIABLE_SIZE; ++i) { + data[i] = (float)i; + } + + hid_t file = H5Fcreate(FILE_NAME_A, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t space = H5Screate_simple(1, dims, NULL); + hid_t dset = H5Dcreate2(file, VARIABLE_NAME, H5T_IEEE_F32LE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + H5Dwrite(dset, H5T_IEEE_F32LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); + H5DSset_scale(dset, VARIABLE_NAME); + + H5Dclose(dset); + H5Sclose(space); + H5Fclose(file); +} + +static void +create_dataset_b() { + hsize_t dims[1] = {VARIABLE_SIZE}; + + hid_t file = H5Fcreate(FILE_NAME_B, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t src_space = H5Screate_simple(1, dims, NULL); + hid_t space = H5Screate_simple(1, dims, NULL); + + hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE); + H5Pset_virtual(dcpl, space, FILE_NAME_A, VARIABLE_NAME, src_space); + hid_t dset = H5Dcreate2(file, VARIABLE_NAME, H5T_IEEE_F32LE, space, H5P_DEFAULT, dcpl, H5P_DEFAULT); + + H5DSset_scale(dset, VARIABLE_NAME); + + H5Dclose(dset); + H5Sclose(space); + H5Fclose(file); +} + +int read_back_contents(const char* filename) { + int ncid, varid, ndims; + float data[VARIABLE_SIZE]; + + char var_name[NC_MAX_NAME+1]; + int dimids_var[1], var_type, natts; + + printf("\treading back %s.\n", filename); + + if (nc_open(filename, 0, &ncid)) ERR; + if (nc_inq_varid(ncid, VARIABLE_NAME, &varid)) ERR; + if (nc_inq_var(ncid, varid, var_name, &var_type, &ndims, dimids_var, &natts)) ERR; + if (nc_get_var_float(ncid, varid, data)) ERR; + printf("\t %s: ", var_name); + for (size_t i = 0; i < VARIABLE_SIZE; ++i) { + printf("%f, ", data[i]); + } + printf("\n"); + if (nc_close(ncid)) ERR; + SUMMARIZE_ERR; + return 0; +} + +int +main(int argc, char **argv) +{ + + printf("\n*** Testing reading of virtual datasets.\n"); + + create_dataset_a(); + create_dataset_b(); + + int status; + if((status = read_back_contents(FILE_NAME_A))) return status; + if((status = read_back_contents(FILE_NAME_B))) return status; +} From 89e656d7a5e879d75c44d905a78e1c505f75105e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Wed, 2 Sep 2020 16:11:43 +0200 Subject: [PATCH 02/16] tst_virtual_datasets: add missing hdf5 close calls --- nc_test4/tst_virtual_datasets.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nc_test4/tst_virtual_datasets.c b/nc_test4/tst_virtual_datasets.c index 77349693f8..c27455713e 100644 --- a/nc_test4/tst_virtual_datasets.c +++ b/nc_test4/tst_virtual_datasets.c @@ -43,7 +43,9 @@ create_dataset_b() { H5DSset_scale(dset, VARIABLE_NAME); H5Dclose(dset); + H5Pclose(dcpl); H5Sclose(space); + H5Sclose(src_space); H5Fclose(file); } From 4c27730ae346b2b1666938a19df0f4c753f2b2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Wed, 2 Sep 2020 16:13:23 +0200 Subject: [PATCH 03/16] hdf5: added unknown storage specification In case HDF5 adds more storage specifications, netcdf4 should be able to cope with them by default. Further specializations could be added nonetheless. --- include/netcdf.h | 10 ++++++---- libhdf5/hdf5open.c | 4 ++++ libsrc4/nc4internal.c | 4 +++- ncdump/ncdump.c | 5 ++++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/include/netcdf.h b/include/netcdf.h index 4395b30e82..630d1d21b8 100644 --- a/include/netcdf.h +++ b/include/netcdf.h @@ -293,11 +293,13 @@ NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits /** In HDF5 files you can set storage for each variable to be either * contiguous or chunked, with nc_def_var_chunking(). This define is - * used there. */ + * used there. Unknown storage is used for further extensions of HDF5 + * storage models, which should be handled transparently by netcdf */ /**@{*/ -#define NC_CHUNKED 0 -#define NC_CONTIGUOUS 1 -#define NC_COMPACT 2 +#define NC_CHUNKED 0 +#define NC_CONTIGUOUS 1 +#define NC_COMPACT 2 +#define NC_UNKNOWN_STORAGE 3 /**@}*/ /** In HDF5 files you can set check-summing for each variable. diff --git a/libhdf5/hdf5open.c b/libhdf5/hdf5open.c index 06b5adbae2..fd496a33cb 100644 --- a/libhdf5/hdf5open.c +++ b/libhdf5/hdf5open.c @@ -1140,6 +1140,10 @@ get_chunking_info(hid_t propid, NC_VAR_INFO_T *var) { var->storage = NC_COMPACT; } + else + { + var->storage = NC_UNKNOWN_STORAGE; + } return NC_NOERR; } diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index 9c9d7ec956..bc2346cc6b 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -1709,8 +1709,10 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count) strcat(storage_str, "contiguous"); else if (var->storage == NC_COMPACT) strcat(storage_str, "compact"); - else + else if (var->storage == NC_CHUNKED) strcat(storage_str, "chunked"); + else + strcat(storage_str, "unknown"); LOG((2, "%s VARIABLE - varid: %d name: %s ndims: %d " "dimids:%s storage: %s", tabs, var->hdr.id, var->hdr.name, var->ndims, diff --git a/ncdump/ncdump.c b/ncdump/ncdump.c index e7ac9acf82..b61dac26c8 100644 --- a/ncdump/ncdump.c +++ b/ncdump/ncdump.c @@ -988,7 +988,7 @@ pr_att_specials( } else if(contig == NC_COMPACT) { pr_att_name(ncid, varp->name, NC_ATT_STORAGE); printf(" = \"compact\" ;\n"); - } else { + } else if(contig == NC_CHUNKED) { size_t *chunkp; int i; pr_att_name(ncid, varp->name, NC_ATT_STORAGE); @@ -1002,6 +1002,9 @@ pr_att_specials( printf("%lu%s", (unsigned long)chunkp[i], i+1 < varp->ndims ? ", " : " ;\n"); } free(chunkp); + } else { + pr_att_name(ncid, varp->name, NC_ATT_STORAGE); + printf(" = \"unknown\" ;\n"); } /* _Filter (including deflate and shuffle) */ From 9f8897762d4d266f9dac3c2e3f22d79c5247a974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Wed, 2 Sep 2020 16:16:57 +0200 Subject: [PATCH 04/16] changed H5Pset_fclose_degree to H5F_CLOSE_WEAK It seems like it is part of the design of HDF5 virtual datasets that objects within a file remain opened while the files is aready "closed". Setting the fclose degree to SEMI would cause the library to bail out. This commit makes nc_test4/tst_virtual_dataset succeed. See also Unidata/netcdf-c#1799 --- libhdf5/hdf5open.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libhdf5/hdf5open.c b/libhdf5/hdf5open.c index fd496a33cb..a87def5969 100644 --- a/libhdf5/hdf5open.c +++ b/libhdf5/hdf5open.c @@ -756,12 +756,13 @@ nc4_open_file(const char *path, int mode, void* parameters, int ncid) #endif /* !USE_PARALLEL4 */ /* Need this access plist to control how HDF5 handles open objects - * on file close. (Setting H5F_CLOSE_SEMI will cause H5Fclose to - * fail if there are any open objects in the file). */ + * on file close. (Setting H5F_CLOSE_WEAK will cause H5Fclose not to + * fail if there are any open objects in the file. This may happen when virtual + * datasets are opened). */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) BAIL(NC_EHDFERR); - if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI) < 0) + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK) < 0) BAIL(NC_EHDFERR); #ifdef USE_PARALLEL4 From a3b753d764b73f3960bf92dfe93b1125c9775fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Wed, 2 Sep 2020 20:02:08 +0200 Subject: [PATCH 05/16] change H5F_CLOSE_SEMI -> H5F_CLOSE_WEAK for nc4_create_file as well The nc_sync test fails if the settings are different for file creation and opening. --- libhdf5/hdf5create.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libhdf5/hdf5create.c b/libhdf5/hdf5create.c index 27a99405c9..747ee8accc 100644 --- a/libhdf5/hdf5create.c +++ b/libhdf5/hdf5create.c @@ -121,11 +121,12 @@ nc4_create_file(const char *path, int cmode, size_t initialsz, } /* Need this access plist to control how HDF5 handles open objects - * on file close. Setting H5F_CLOSE_SEMI will cause H5Fclose to - * fail if there are any open objects in the file. */ + * on file close. (Setting H5F_CLOSE_WEAK will cause H5Fclose not to + * fail if there are any open objects in the file. This may happen when virtual + * datasets are opened). */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) BAIL(NC_EHDFERR); - if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK)) BAIL(NC_EHDFERR); #ifdef USE_PARALLEL4 From 4b8096549124ad8a835da556b971916d28833f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Wed, 2 Sep 2020 21:29:26 +0200 Subject: [PATCH 06/16] ange H5F_CLOSE_SEMI -> H5F_CLOSE_WEAK for netcdf related tests --- nc_perf/tst_attsperf.c | 2 +- nc_test4/tst_h_vl2.c | 2 +- nc_test4/tst_interops.c | 2 +- nc_test4/tst_interops5.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nc_perf/tst_attsperf.c b/nc_perf/tst_attsperf.c index 98f233f72f..26a2b48440 100644 --- a/nc_perf/tst_attsperf.c +++ b/nc_perf/tst_attsperf.c @@ -137,7 +137,7 @@ readfile_hdf5(char *file_name, long long *delta, int do_inq, int num_vars) /* Open and close the root group. */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; - if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) ERR; + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK)) ERR; if ((hdfid = H5Fopen(file_name, H5F_ACC_RDONLY, fapl_id)) < 0) ERR; if ((hdf_grpid = H5Gopen2(hdfid, "/", H5P_DEFAULT)) < 0) ERR; diff --git a/nc_test4/tst_h_vl2.c b/nc_test4/tst_h_vl2.c index 8f44e9a0f5..1f2b5cd3ef 100644 --- a/nc_test4/tst_h_vl2.c +++ b/nc_test4/tst_h_vl2.c @@ -36,7 +36,7 @@ main() /* Open the file and read the vlen data. */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; - if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) ERR; + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK)) ERR; if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR; if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, fapl_id)) < 0) ERR; diff --git a/nc_test4/tst_interops.c b/nc_test4/tst_interops.c index 64a0319472..74353d34be 100644 --- a/nc_test4/tst_interops.c +++ b/nc_test4/tst_interops.c @@ -390,7 +390,7 @@ main(int argc, char **argv) /* Open the file with HDF5 while netcdf still has it open. */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; /* Turn this off for*/ - if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) ERR; + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK)) ERR; if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, fapl_id)) < 0) ERR; if (H5Pclose(fapl_id) < 0) ERR; if (H5Fclose(fileid) < 0) ERR; diff --git a/nc_test4/tst_interops5.c b/nc_test4/tst_interops5.c index cb4dd0e623..bb22fd0a27 100644 --- a/nc_test4/tst_interops5.c +++ b/nc_test4/tst_interops5.c @@ -50,10 +50,10 @@ main(int argc, char **argv) yscaleDims[0] = ncolCur; if ((xdimSpaceId = H5Screate_simple(1, xscaleDims, NULL)) < 0) ERR; - /* With the SEMI close degree, the HDF5 file close will fail if + /* With the WEAK close degree, the HDF5 file close will not fail if * anything is left open. */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; - if (H5Pset_fclose_degree(fapl, H5F_CLOSE_SEMI)) ERR; + if (H5Pset_fclose_degree(fapl, H5F_CLOSE_WEAK)) ERR; /* Create file */ if((fileId = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, From 69fb44ec4bf220b8e099148d605172ee1f5c05c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Thu, 3 Sep 2020 17:51:46 +0200 Subject: [PATCH 07/16] added NC_VIRTUAL storage layout --- include/netcdf.h | 1 + libhdf5/hdf5open.c | 4 ++++ libsrc4/nc4internal.c | 2 ++ ncdump/ncdump.c | 3 +++ 4 files changed, 10 insertions(+) diff --git a/include/netcdf.h b/include/netcdf.h index 630d1d21b8..99bc0c2194 100644 --- a/include/netcdf.h +++ b/include/netcdf.h @@ -300,6 +300,7 @@ NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits #define NC_CONTIGUOUS 1 #define NC_COMPACT 2 #define NC_UNKNOWN_STORAGE 3 +#define NC_VIRTUAL 4 /**@}*/ /** In HDF5 files you can set check-summing for each variable. diff --git a/libhdf5/hdf5open.c b/libhdf5/hdf5open.c index a87def5969..22205fc158 100644 --- a/libhdf5/hdf5open.c +++ b/libhdf5/hdf5open.c @@ -1141,6 +1141,10 @@ get_chunking_info(hid_t propid, NC_VAR_INFO_T *var) { var->storage = NC_COMPACT; } + else if (layout == H5D_VIRTUAL) + { + var->storage = NC_VIRTUAL; + } else { var->storage = NC_UNKNOWN_STORAGE; diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index bc2346cc6b..968b2ab080 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -1711,6 +1711,8 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count) strcat(storage_str, "compact"); else if (var->storage == NC_CHUNKED) strcat(storage_str, "chunked"); + else if (var->storage == NC_VIRTUAL) + strcat(storage_str, "virtual"); else strcat(storage_str, "unknown"); LOG((2, "%s VARIABLE - varid: %d name: %s ndims: %d " diff --git a/ncdump/ncdump.c b/ncdump/ncdump.c index b61dac26c8..4b2231e3c9 100644 --- a/ncdump/ncdump.c +++ b/ncdump/ncdump.c @@ -1002,6 +1002,9 @@ pr_att_specials( printf("%lu%s", (unsigned long)chunkp[i], i+1 < varp->ndims ? ", " : " ;\n"); } free(chunkp); + } else if(contig == NC_VIRTUAL) { + pr_att_name(ncid, varp->name, NC_ATT_STORAGE); + printf(" = \"virtual\" ;\n"); } else { pr_att_name(ncid, varp->name, NC_ATT_STORAGE); printf(" = \"unknown\" ;\n"); From 8de6398b993e79809ed5b3111e25c77cf451e03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Mon, 14 Sep 2020 17:25:25 +0200 Subject: [PATCH 08/16] check if H5D_VIRTUAL exists in installed HDF5 library Older HDF5 libraries do not support virtual datasets but could otherwise be supported by netCDF4. This change removes the special case to handle HDF5 virtual datasets if the installed HDF5 version does not support virtual datasets. --- libhdf5/hdf5open.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libhdf5/hdf5open.c b/libhdf5/hdf5open.c index 22205fc158..c642a1c244 100644 --- a/libhdf5/hdf5open.c +++ b/libhdf5/hdf5open.c @@ -1141,10 +1141,12 @@ get_chunking_info(hid_t propid, NC_VAR_INFO_T *var) { var->storage = NC_COMPACT; } +#ifdef H5D_VIRTUAL else if (layout == H5D_VIRTUAL) { var->storage = NC_VIRTUAL; } +#endif else { var->storage = NC_UNKNOWN_STORAGE; From b6b9f2fd6fe2e4914b59a570bfb6b39e5d7f1b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=B6lling?= Date: Mon, 14 Sep 2020 18:06:34 +0200 Subject: [PATCH 09/16] enable test for virtual datasets only for HDF5 >= 1.10.0 --- nc_test4/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nc_test4/CMakeLists.txt b/nc_test4/CMakeLists.txt index 3198de24c8..b08d194f5f 100644 --- a/nc_test4/CMakeLists.txt +++ b/nc_test4/CMakeLists.txt @@ -20,7 +20,7 @@ SET(NC4_TESTS tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_files6 tst_sync tst_h_strbug tst_h_refs tst_h_scalar tst_rename tst_rename2 tst_rename3 tst_h5_endians tst_atts_string_rewrite tst_put_vars_two_unlim_dim tst_hdf5_file_compat tst_fill_attr_vanish tst_rehash tst_types tst_bug324 - tst_atts3 tst_put_vars tst_elatefill tst_udf tst_bug1442 tst_virtual_datasets) + tst_atts3 tst_put_vars tst_elatefill tst_udf tst_bug1442) # Note, renamegroup needs to be compiled before run_grp_rename @@ -44,6 +44,10 @@ ENDIF(ENABLE_FILTER_TESTING) ENDIF(BUILD_UTILITIES) +IF(${HDF5_VERSION} VERSION_GREATER "1.10.0") + SET(NC4_TESTS ${NC4_TESTS} tst_virtual_datasets) +ENDIF(${HDF5_VERSION} VERSION_GREATER "1.10.0") + ## # The shell script, run_empty_vlen_test.sh, # depends on the 'tst_empty_vlen_unlim' binary. From 802916a91407ea0a1ba619aaf7211e54babf9b01 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Tue, 13 Apr 2021 11:45:33 -0600 Subject: [PATCH 10/16] Addressing some uninitialized variables to see if there is an effect on compiler optimizations. Good practice to have these fixed in any event. --- nc_test/test_get.m4 | 9 ++++----- nc_test/test_read.m4 | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/nc_test/test_get.m4 b/nc_test/test_get.m4 index 19d9e043ce..ca83bb2b30 100644 --- a/nc_test/test_get.m4 +++ b/nc_test/test_get.m4 @@ -98,11 +98,11 @@ define(`TEST_NC_GET_VAR1',dnl int TestFunc(var1)_$1(VarArgs) { - int i, err, ncid, cdf_format; + int i=0, err=0, ncid=0, cdf_format=0; int nok = 0; /* count of valid comparisons */ - int canConvert; /* Both text or both numeric */ - IntType j, index[MAX_RANK]; - double expect; + int canConvert=0; /* Both text or both numeric */ + IntType j=0, index[MAX_RANK]; + double expect=0; $1 value[1]; err = FileOpen(testfile, NC_NOWRITE); @@ -1348,4 +1348,3 @@ TEST_NC_GET_ATT(ushort) TEST_NC_GET_ATT(uint) TEST_NC_GET_ATT(longlong) TEST_NC_GET_ATT(ulonglong) - diff --git a/nc_test/test_read.m4 b/nc_test/test_read.m4 index 41bc5b55e0..9b88d615d9 100644 --- a/nc_test/test_read.m4 +++ b/nc_test/test_read.m4 @@ -1031,14 +1031,14 @@ TestFunc(inq_vartype)(VarArgs) int TestFunc(get_var1)(VarArgs) { - int ncid; - int i; - int err; - double expect; + int ncid = 0; + int i = 0; + int err = 0; + double expect = 0; int nok = 0; /* count of valid comparisons */ - double buf[1]; /* (void *) buffer */ - double value[1]; - IntType j, index[MAX_RANK]; + double buf[1] = {0}; /* (void *) buffer */ + double value[1] = {0}; + IntType j = 0, index[MAX_RANK] = {0}; ifdef(`PNETCDF', `MPI_Datatype datatype;') err = FileOpen(testfile, NC_NOWRITE, &ncid); @@ -1124,16 +1124,16 @@ ifdef(`PNETCDF',`dnl int TestFunc(get_vara)(VarArgs) { - int ncid, d, i, k, err, nslabs; + int ncid = 0, d = 0, i = 0, k = 0, err = 0, nslabs = 0; int nok = 0; /* count of valid comparisons */ - IntType j, nels; - IntType start[MAX_RANK]; - IntType edge[MAX_RANK]; - IntType index[MAX_RANK]; - IntType mid[MAX_RANK]; + IntType j = 0, nels = 0; + IntType start[MAX_RANK]= {0}; + IntType edge[MAX_RANK] = {0}; + IntType index[MAX_RANK] = {0}; + IntType mid[MAX_RANK] = {0}; ifdef(`PNETCDF', `MPI_Datatype datatype;') - double buf[MAX_NELS]; /* (void *) buffer */ - double expect; + double buf[MAX_NELS] = {0}; /* (void *) buffer */ + double expect = 0; err = FileOpen(testfile, NC_NOWRITE, &ncid); IF (err != NC_NOERR) From b09461754f19179815be72bdedea90968860d3fd Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Wed, 16 Jun 2021 16:34:06 -0600 Subject: [PATCH 11/16] Turn verbose output on in nc_test. --- nc_test/nc_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nc_test/nc_test.c b/nc_test/nc_test.c index 74ac76e04c..5525b52dd2 100644 --- a/nc_test/nc_test.c +++ b/nc_test/nc_test.c @@ -98,7 +98,7 @@ main(int argc, char *argv[]) */ (void) signal(SIGFPE, SIG_IGN); - verbose = 0; + verbose = 1; max_nmpt = 8; /* If you uncomment the nc_set_log_level line, you will get a lot From 04512965748b767c38441323e13da43c11932642 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Fri, 9 Jul 2021 13:48:35 -0600 Subject: [PATCH 12/16] Added explicit initialization to address some potential issues raised by clang static analysis. --- nc_test/test_get.m4 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/nc_test/test_get.m4 b/nc_test/test_get.m4 index ca83bb2b30..50a2653ab0 100644 --- a/nc_test/test_get.m4 +++ b/nc_test/test_get.m4 @@ -253,6 +253,10 @@ TestFunc(var)_$1(VarArgs) double expect[MAX_NELS]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_NELS; j++) { + expect[j] = 0; + } + err = FileOpen(testfile, NC_NOWRITE); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); @@ -376,6 +380,10 @@ TestFunc(vara)_$1(VarArgs) double expect[MAX_NELS]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_NELS; j++) { + expect[j] = 0; + } + err = FileOpen(testfile, NC_NOWRITE); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); @@ -635,6 +643,10 @@ TestFunc(vars)_$1(VarArgs) double expect[MAX_NELS]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_NELS; j++) { + expect[j] = 0; + } + err = FileOpen(testfile, NC_NOWRITE); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); @@ -928,6 +940,10 @@ TestFunc(varm)_$1(VarArgs) double expect[MAX_NELS]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_NELS; j++) { + expect[j] = 0; + } + err = FileOpen(testfile, NC_NOWRITE); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); @@ -1221,6 +1237,10 @@ TestFunc(att)_$1(AttVarArgs) double expect[MAX_NELS]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_NELS; j++) { + expect[j] = 0; + } + err = FileOpen(testfile, NC_NOWRITE); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); From 30621b38d3dd85afefb35c4b50b2c1d6632e3c94 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Mon, 12 Jul 2021 16:40:27 -0600 Subject: [PATCH 13/16] Eliminate a lot of 'result of operation is undefined or garbage' errors reported by static analysis. These errors appeared to be false positives as there was logic that should prevent their occurance, but it's possible that optimization would result in these error states occuring. --- nc_test/test_get.m4 | 4 +- nc_test/test_put.m4 | 98 +++++++++++++++++++++++++++---------------- nc_test/test_read.m4 | 95 ++++++++++++++++++++++++++++------------- nc_test/test_write.m4 | 95 +++++++++++++++++++++++++++-------------- 4 files changed, 193 insertions(+), 99 deletions(-) diff --git a/nc_test/test_get.m4 b/nc_test/test_get.m4 index 50a2653ab0..e8bce40fe6 100644 --- a/nc_test/test_get.m4 +++ b/nc_test/test_get.m4 @@ -826,7 +826,7 @@ ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') IF (err != 0) error("error in toMixedBase"); nels = 1; for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j]-index[j]-1) / (IntType)stride[j]; + count[j] = 1 + (edge[j]-index[j]-1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); nels *= count[j]; index[j] += start[j]; } @@ -1123,7 +1123,7 @@ ifelse(`$1',`uchar',`ifdef(`PNETCDF',,``#'endif')') IF (err != 0) error("error in toMixedBase"); nels = 1; for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j]-index[j]-1) / (IntType)stride[j]; + count[j] = 1 + (edge[j]-index[j]-1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); nels *= count[j]; index[j] += start[j]; } diff --git a/nc_test/test_put.m4 b/nc_test/test_put.m4 index 5f7cb01710..90becf49a4 100644 --- a/nc_test/test_put.m4 +++ b/nc_test/test_put.m4 @@ -216,7 +216,7 @@ check_vars_$1(const char *filename, int numVars) error("var_name: %s, ", var_name[i]); error("var_type: %s, ", s_nc_type(var_type[i])); error("index:"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) error(" %d", index[d]); error(", expect: %g, ", expect); error("got: %g", (double) value); @@ -428,9 +428,9 @@ ifdef(`PNETCDF',`dnl ')dnl /* test NC_EINVALCOORDS */ - for (j = 0; j < var_rank[i]; j++) index[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) index[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ index[j] = var_shape[i][j]; /* out of boundary check */ err = PutVar1($1)(ncid, i, index, value); @@ -664,6 +664,13 @@ TestFunc(vara)_$1(VarArgs) IntType mid[MAX_RANK], index[MAX_RANK]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_RANK; j++) { + start[j] = 0; + edge[j] = 0; + mid[j] = 0; + index[j] = 0; + } + err = FileCreate(scratch, NC_CLOBBER); IF (err != NC_NOERR) { error("create: %s", APIFunc(strerror)(err)); @@ -707,7 +714,7 @@ TestFunc(vara)_$1(VarArgs) canConvert = (var_type[i] == NC_CHAR) CheckText($1); - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; } @@ -741,7 +748,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* first test when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVara($1)(ncid, i, start, edge, value); @@ -765,9 +772,9 @@ ifdef(`PNETCDF',`dnl } /* Check correct error returned when nothing to put, when edge[*]==0 */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVara($1)(ncid, i, start, edge, value); @@ -788,19 +795,19 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; /* Choose a random point dividing each dim into 2 parts */ /* Put 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } /* bits of k determine whether to put lower or upper part of dim */ for (k = 0; k < nslabs; k++) { nels = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -814,7 +821,7 @@ ifdef(`PNETCDF',`dnl for (allInExtRange = 1, j = 0; j < nels; j++) { err = toMixedBase(j, var_rank[i], edge, index); IF (err != 0) error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) index[d] += start[d]; value[j]= hash_$1(cdf_format,var_type[i], var_rank[i], index, NCT_ITYPE($1)); @@ -883,6 +890,17 @@ TestFunc(vars)_$1(VarArgs) PTRDType stride[MAX_RANK]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_RANK; j++) { + start[j] = 0; + edge[j] = 0; + mid[j] = 0; + index[j] = 0; + index2[j] = 0; + count[j] = 0; + sstride[j] = 1; + stride[j] = 1; + } + err = FileCreate(scratch, NC_CLOBBER); IF (err != NC_NOERR) { error("create: %s", APIFunc(strerror)(err)); @@ -926,7 +944,7 @@ TestFunc(vars)_$1(VarArgs) canConvert = (var_type[i] == NC_CHAR) CheckText($1); - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; @@ -944,7 +962,7 @@ ifdef(`PNETCDF',`dnl EXPECT_ERR(NC_EINVALCOORDS, err) } ELSE_NOK - + /* for non-scalar variables, argument count cannot be NULL */ err = PutVars($1)(ncid, i, start, NULL, NULL, value); if (!canConvert) { @@ -960,7 +978,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* first test when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; /* out of boundary check */ err = PutVars($1)(ncid, i, start, edge, stride, value); @@ -989,9 +1007,9 @@ ifdef(`PNETCDF',`dnl stride[j] = 1; } /* Check correct error returned even when nothing to put */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVars($1)(ncid, i, start, edge, stride, value); @@ -1012,12 +1030,12 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; /* Choose a random point dividing each dim into 2 parts */ /* Put 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } @@ -1025,7 +1043,7 @@ ifdef(`PNETCDF',`dnl /* choose random stride from 1 to edge */ for (k = 0; k < nslabs; k++) { nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1041,15 +1059,15 @@ ifdef(`PNETCDF',`dnl err = toMixedBase(m, var_rank[i], sstride, index); IF (err != 0) error("error in toMixedBase"); nels = 1; - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { + count[j] = (1 + (edge[j] - index[j] - 1)) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); nels *= count[j]; index[j] += start[j]; } /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } @@ -1058,7 +1076,7 @@ ifdef(`PNETCDF',`dnl for (allInExtRange = 1, j = 0; j < nels; j++) { err = toMixedBase(j, var_rank[i], count, index2); IF (err != 0) error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) index2[d] = index[d] + index2[d] * (IntType)stride[d]; value[j] = hash_$1(cdf_format,var_type[i], var_rank[i], index2, NCT_ITYPE($1)); @@ -1128,6 +1146,17 @@ TestFunc(varm)_$1(VarArgs) PTRDType stride[MAX_RANK], imap[MAX_RANK]; $1 value[MAX_NELS]; + for(j = 0; j < MAX_RANK; j++) { + start[j] = 0; + edge[j] = 0; + mid[j] = 0; + index[j] = 0; + index2[j] = 0; + count[j] = 0; + sstride[j] = 1; + stride[j] = 1; + } + err = FileCreate(scratch, NC_CLOBBER); IF (err != NC_NOERR) { error("create: %s", APIFunc(strerror)(err)); @@ -1171,7 +1200,7 @@ TestFunc(varm)_$1(VarArgs) canConvert = (var_type[i] == NC_CHAR) CheckText($1); - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; @@ -1191,7 +1220,7 @@ ifdef(`PNETCDF',`dnl EXPECT_ERR(NC_EINVALCOORDS, err) } ELSE_NOK - + /* for non-scalar variables, argument count cannot be NULL */ err = PutVarm($1)(ncid, i, start, NULL, NULL, NULL, value); if (!canConvert) { @@ -1207,7 +1236,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* first test when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; /* out of boundary check */ err = PutVarm($1)(ncid, i, start, edge, stride, imap, value); @@ -1236,9 +1265,9 @@ ifdef(`PNETCDF',`dnl stride[j] = 1; } /* Check correct error returned when nothing to put, i.e. edge[*]==0 */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i]&& j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVarm($1)(ncid, i, start, edge, stride, imap, value); @@ -1259,12 +1288,12 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; /* Choose a random point dividing each dim into 2 parts */ /* Put 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } @@ -1272,7 +1301,7 @@ ifdef(`PNETCDF',`dnl /* choose random stride from 1 to edge */ for (k = 0; k < nslabs; k++) { nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1288,7 +1317,7 @@ ifdef(`PNETCDF',`dnl err = toMixedBase(m, var_rank[i], sstride, index); IF (err != 0) error("error in toMixedBase"); nels = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; nels *= count[j]; index[j] += start[j]; @@ -1296,7 +1325,7 @@ ifdef(`PNETCDF',`dnl /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } @@ -1311,7 +1340,7 @@ ifdef(`PNETCDF',`dnl for (allInExtRange = 1, j = 0; j < nels; j++) { err = toMixedBase(j, var_rank[i], count, index2); IF (err != 0) error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) index2[d] = index[d] + index2[d] * (IntType)stride[d]; value[j] = hash_$1(cdf_format,var_type[i], var_rank[i], index2, NCT_ITYPE($1)); @@ -1533,4 +1562,3 @@ TEST_NC_PUT_ATT(ushort) TEST_NC_PUT_ATT(uint) TEST_NC_PUT_ATT(longlong) TEST_NC_PUT_ATT(ulonglong) - diff --git a/nc_test/test_read.m4 b/nc_test/test_read.m4 index 9b88d615d9..e4e9b21dae 100644 --- a/nc_test/test_read.m4 +++ b/nc_test/test_read.m4 @@ -1076,7 +1076,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* test NC_EINVALCOORDS */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] = var_shape[i][j]; err = GetVar1(ncid, i, index, buf, 1, datatype); IF (err != NC_EINVALCOORDS) @@ -1135,6 +1135,13 @@ TestFunc(get_vara)(VarArgs) double buf[MAX_NELS] = {0}; /* (void *) buffer */ double expect = 0; + for(j = 0; j < MAX_RANK; j++) { + start[j] = 0; + edge[j] = 0; + index[j] = 0; + mid[j] = 0; + } + err = FileOpen(testfile, NC_NOWRITE, &ncid); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); @@ -1159,7 +1166,7 @@ TestFunc(get_vara)(VarArgs) ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; } @@ -1184,7 +1191,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* test NC_EINVALCOORDS, first when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] = var_shape[i][j]; err = GetVara(ncid, i, index, edge, buf, 1, datatype); IF (err != NC_EINVALCOORDS) @@ -1201,9 +1208,9 @@ ifdef(`PNETCDF',`dnl /* Check non-scalars for correct error returned even when there is * nothing to get (edge[j]==0) */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = GetVara(ncid, i, start, edge, buf, 0, datatype); @@ -1217,7 +1224,7 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; err = GetVara(ncid, i, start, edge, buf, 1, datatype); IF (err != NC_NOERR) @@ -1227,14 +1234,14 @@ ifdef(`PNETCDF',`dnl /* Choose a random point dividing each dim into 2 parts */ /* get 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } /* bits of k determine whether to get lower or upper part of dim */ for (k = 0; k < nslabs; k++) { nels = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1257,7 +1264,7 @@ ifdef(`PNETCDF',`dnl IF (err) error("error in nc2dbl"); err = toMixedBase(j, var_rank[i], edge, index); IF (err != 0) error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) index[d] += start[d]; expect = hash(var_type[i], var_rank[i], index); if (inRange(expect,var_type[i])) { @@ -1316,6 +1323,17 @@ TestFunc(get_vars)(VarArgs) double expect; double got; + for (j = 0; j < MAX_RANK; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; + mid[j] = 1; + index[j] = 0; + index2[j] = 0; + count[j] = 0; + sstride[j] = 1; + } + err = FileOpen(testfile, NC_NOWRITE, &ncid); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); @@ -1340,10 +1358,15 @@ TestFunc(get_vars)(VarArgs) ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; + mid[j] = 1; + index[j] = 0; + index2[j] = 0; + count[j] = 0; + sstride[j] = 1; } ifdef(`PNETCDF',`dnl @@ -1366,7 +1389,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* test NC_EINVALCOORDS, first when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = var_shape[i][j]; err = GetVars(ncid, i, start, edge, stride, buf, 1, datatype); IF (err != NC_EINVALCOORDS) @@ -1388,9 +1411,9 @@ ifdef(`PNETCDF',`dnl } /* Check non-scalars for correct error returned even when there is * nothing to get (edge[j]==0) */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = GetVars(ncid, i, start, edge, stride, buf, 0, datatype); @@ -1404,7 +1427,7 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; err = GetVars(ncid, i, start, edge, stride, buf, 1, datatype); IF (err != NC_NOERR) @@ -1414,7 +1437,7 @@ ifdef(`PNETCDF',`dnl /* Choose a random point dividing each dim into 2 parts */ /* get 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } @@ -1423,7 +1446,7 @@ ifdef(`PNETCDF',`dnl n = 0; for (k = 0; k < nslabs; k++) { nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1439,15 +1462,15 @@ ifdef(`PNETCDF',`dnl err = toMixedBase(m, var_rank[i], sstride, index); IF (err != 0) error("error in toMixedBase"); nels = 1; - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); nels *= count[j]; index[j] += start[j]; } /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } @@ -1466,7 +1489,7 @@ ifdef(`PNETCDF',`dnl error("error in nc2dbl"); err = toMixedBase(j, var_rank[i], count, index2); IF (err != 0) error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) index2[d] = index[d] + index2[d] * (IntType)stride[d]; expect = hash(var_type[i], var_rank[i], index2); if (inRange(expect,var_type[i])) { @@ -1539,6 +1562,18 @@ TestFunc(get_varm)(VarArgs) double expect; double got; + for (j = 0; j < MAX_RANK; j++) { + start[j] = 0; + edge[j] = 1; + stride[j] = 1; + mid[j] = 1; + index[j] = 0; + count[j] = 0; + sstride[j] = 1; + imap[j] = 0; + imap2[j] = 0; + } + err = FileOpen(testfile, NC_NOWRITE, &ncid); IF (err != NC_NOERR) error("open: %s", APIFunc(strerror)(err)); @@ -1563,7 +1598,7 @@ TestFunc(get_varm)(VarArgs) ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; @@ -1590,7 +1625,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* test NC_EINVALCOORDS, first when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK ; j++) { start[j] = var_shape[i][j]; err = GetVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); IF (err != NC_EINVALCOORDS) @@ -1612,9 +1647,9 @@ ifdef(`PNETCDF',`dnl } /* Check non-scalars for correct error returned even when there is * nothing to get (edge[j]==0) */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = GetVarm(ncid, i, start, edge, stride, imap, buf, 0, datatype); @@ -1628,7 +1663,7 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; err = GetVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); IF (err != NC_NOERR) @@ -1646,7 +1681,7 @@ ifdef(`PNETCDF',`dnl /* Choose a random point dividing each dim into 2 parts */ /* get 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } @@ -1654,7 +1689,7 @@ ifdef(`PNETCDF',`dnl /* choose random stride from 1 to edge */ for (k = 0; k < nslabs; k++) { nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1674,15 +1709,15 @@ ifdef(`PNETCDF',`dnl err = toMixedBase(m, var_rank[i], sstride, index); IF (err != 0) error("error in toMixedBase"); nels = 1; - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); index[j] += start[j]; nels *= count[j]; } /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } diff --git a/nc_test/test_write.m4 b/nc_test/test_write.m4 index 6d011971bc..4ea4e52b54 100644 --- a/nc_test/test_write.m4 +++ b/nc_test/test_write.m4 @@ -892,9 +892,9 @@ ifdef(`PNETCDF',`dnl ')dnl /* test NC_EINVALCOORDS */ - for (j = 0; j < var_rank[i]; j++) index[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) index[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ index[j] = var_shape[i][j]; /* out of boundary check */ err = PutVar1(ncid, i, index, value, 1, datatype); @@ -951,9 +951,16 @@ TestFunc(put_vara)(VarArgs) IntType mid[MAX_RANK]; double buf[MAX_NELS]; /* (void *) buffer */ char *p; /* (void *) pointer */ - double value; + double value = 0; ifdef(`PNETCDF', `MPI_Datatype datatype;') + for(j = 0; j < MAX_RANK; j++ ) { + start[j] = 0; + edge[j] = 0; + index[j] = 0; + mid[j] = 0; + } + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); IF (err != NC_NOERR) { error("create: %s", APIFunc(strerror)(err)); @@ -993,7 +1000,7 @@ TestFunc(put_vara)(VarArgs) ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; } @@ -1021,7 +1028,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* first test when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVara(ncid, i, start, edge, buf, 1, datatype); @@ -1037,9 +1044,9 @@ ifdef(`PNETCDF',`dnl edge[j] = 1; } /* Check correct error returned when nothing to put, when edge[*]==0 */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == RECDIM) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVara(ncid, i, start, edge, buf, 0, datatype); @@ -1053,19 +1060,19 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; /* Choose a random point dividing each dim into 2 parts */ /* put 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } /* bits of k determine whether to put lower or upper part of dim */ for (k = 0; k < nslabs; k++) { nels = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1079,7 +1086,7 @@ ifdef(`PNETCDF',`dnl for (j = 0; j < nels; j++) { err = toMixedBase(j, var_rank[i], edge, index); IF (err != 0) error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) index[d] += start[d]; value = hash(var_type[i], var_rank[i], index); if (!inRange(value, var_type[i])) @@ -1135,6 +1142,17 @@ TestFunc(put_vars)(VarArgs) double value; ifdef(`PNETCDF', `MPI_Datatype datatype;') + for(j = 0; j < MAX_RANK; j++ ) { + start[j] = 0; + edge[j] = 0; + index[j] = 0; + mid[j] = 0; + index2[j] = 0; + count[j] = 0; + sstride[j] = 1; + stride[j] = 1; + } + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); IF (err != NC_NOERR) { error("create: %s", APIFunc(strerror)(err)); @@ -1174,7 +1192,7 @@ TestFunc(put_vars)(VarArgs) ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; @@ -1203,7 +1221,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* first test when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == 0) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVars(ncid, i, start, edge, stride, buf, 1, datatype); @@ -1225,9 +1243,9 @@ ifdef(`PNETCDF',`dnl stride[j] = 1; } /* Check correct error returned even when nothing to put */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == 0) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVars(ncid, i, start, edge, stride, buf, 0, datatype); @@ -1241,12 +1259,12 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; /* Choose a random point dividing each dim into 2 parts */ /* put 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } @@ -1254,7 +1272,7 @@ ifdef(`PNETCDF',`dnl /* choose random stride from 1 to edge */ for (k = 0; k < nslabs; k++) { nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1270,15 +1288,15 @@ ifdef(`PNETCDF',`dnl err = toMixedBase(m, var_rank[i], sstride, index); IF (err != 0) error("error in toMixedBase"); nels = 1; - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); nels *= count[j]; index[j] += start[j]; } /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } @@ -1288,7 +1306,7 @@ ifdef(`PNETCDF',`dnl for (j = 0; j < nels; j++) { err = toMixedBase(j, var_rank[i], count, index2); IF (err != 0) error("error in toMixedBase"); - for (d = 0; d < var_rank[i]; d++) + for (d = 0; d < var_rank[i] && d < MAX_RANK; d++) index2[d] = index[d] + index2[d] * (IntType)stride[d]; value = hash(var_type[i], var_rank[i], index2); if (!inRange(value, var_type[i])) @@ -1352,6 +1370,18 @@ TestFunc(put_varm)(VarArgs) double value; ifdef(`PNETCDF', `MPI_Datatype datatype;') + for(j = 0; j < MAX_RANK; j++ ) { + start[j] = 0; + edge[j] = 0; + index[j] = 0; + mid[j] = 0; + count[j] = 0; + sstride[j] = 1; + stride[j] = 1; + imap[j] = 0; + imap2[j] = 0; + } + err = FileCreate(scratch, NC_NOCLOBBER, &ncid); IF (err != NC_NOERR) { error("create: %s", APIFunc(strerror)(err)); @@ -1391,11 +1421,12 @@ TestFunc(put_varm)(VarArgs) ifdef(`PNETCDF', `datatype = nc_mpi_type(var_type[i]);') - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { start[j] = 0; edge[j] = 1; stride[j] = 1; imap[j] = 1; + mid[j] = 1; } ifdef(`PNETCDF',`dnl @@ -1421,7 +1452,7 @@ ifdef(`PNETCDF',`dnl ')dnl /* first test when edge[*] > 0 */ - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == 0) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVarm(ncid, i, start, edge, stride, imap, buf, 1, datatype); @@ -1443,9 +1474,9 @@ ifdef(`PNETCDF',`dnl stride[j] = 1; } /* Check correct error returned even when nothing to put */ - for (j = 0; j < var_rank[i]; j++) edge[j] = 0; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 0; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if (var_dimid[i][j] == 0) continue; /* skip record dim */ start[j] = var_shape[i][j]; err = PutVarm(ncid, i, start, edge, stride, imap, buf, 0, datatype); @@ -1459,7 +1490,7 @@ ifdef(`PNETCDF',`dnl ELSE_NOK start[j] = 0; } - for (j = 0; j < var_rank[i]; j++) edge[j] = 1; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) edge[j] = 1; if (var_rank[i] > 0) { int jj = var_rank[i] - 1; @@ -1484,7 +1515,7 @@ ifdef(`PNETCDF',`dnl /* Choose a random point dividing each dim into 2 parts */ /* put 2^rank (nslabs) slabs so defined */ nslabs = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { mid[j] = roll( var_shape[i][j] ); nslabs *= 2; } @@ -1492,7 +1523,7 @@ ifdef(`PNETCDF',`dnl /* choose random stride from 1 to edge */ for (k = 0; k < nslabs; k++) { nstarts = 1; - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { if ((k >> j) & 1) { start[j] = 0; edge[j] = mid[j]; @@ -1511,14 +1542,14 @@ ifdef(`PNETCDF',`dnl } else { err = toMixedBase(m, var_rank[i], sstride, index); IF (err != 0) error("error in toMixedBase"); - for (j = 0; j < var_rank[i]; j++) { - count[j] = 1 + (edge[j] - index[j] - 1) / (IntType)stride[j]; + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { + count[j] = 1 + (edge[j] - index[j] - 1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); index[j] += start[j]; } /* Random choice of forward or backward */ /* TODO if ( roll(2) ) { - for (j = 0; j < var_rank[i]; j++) { + for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { index[j] += (count[j] - 1) * (IntType)stride[j]; stride[j] = -stride[j]; } From 4aeafe2d3a7b2e85013e9ac3918968ca2b465fe3 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Tue, 13 Jul 2021 12:07:56 -0600 Subject: [PATCH 14/16] Fix an accidentally-introduced bug. --- nc_test/test_put.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nc_test/test_put.m4 b/nc_test/test_put.m4 index 90becf49a4..909b2f2bc6 100644 --- a/nc_test/test_put.m4 +++ b/nc_test/test_put.m4 @@ -1060,7 +1060,7 @@ ifdef(`PNETCDF',`dnl IF (err != 0) error("error in toMixedBase"); nels = 1; for (j = 0; j < var_rank[i] && j < MAX_RANK; j++) { - count[j] = (1 + (edge[j] - index[j] - 1)) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); + count[j] = 1 + (edge[j] - index[j] - 1) / ( (IntType)stride[j] == 0 ? 1 : (IntType)stride[j]); nels *= count[j]; index[j] += start[j]; } From a8001f03e1df8b0ed8ecad68c0c97b7ce4f54c42 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Tue, 27 Jul 2021 11:16:58 -0600 Subject: [PATCH 15/16] Added -fno-strict-aliasing to CFLAGS when the compiler supports it and autotools are in use. --- configure.ac | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/configure.ac b/configure.ac index 1283aa75ad..12f721271f 100644 --- a/configure.ac +++ b/configure.ac @@ -54,6 +54,25 @@ AC_CANONICAL_TARGET AC_CONFIG_HEADERS([config.h]) + +## +# Check to see if the compiler supports -fno-strict-aliasing and, if so, +# add that to the C compiler flags. This is in support of https://github.com/Unidata/netcdf-c/issues/1983. +## +SAVE_CFLAGS="${CFLAGS}" +AC_LANG_PUSH([C]) +CFLAGS="${CFLAGS} -fno-strict-aliasing" + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ + [int i = 0;]])], + [have_no_strict_aliasing=yes], + [have_no_strict_aliasing=no]) +AC_MSG_CHECKING([whether compiler supports -fno-strict-aliasing]) +AC_MSG_RESULT([$have_no_strict_aliasing]) +AC_LANG_POP([C]) +if test $have_no_strict_aliasing = no; then + CFLAGS=$SAVE_CFLAGS +fi ## # Some files need to exist in build directories # that do not correspond to their source directory, or From a89e259431ffb476116c9887952bc2a9ba78a804 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Tue, 27 Jul 2021 11:22:48 -0600 Subject: [PATCH 16/16] Added -fno-strict-aliasing to CFLAGS when the compiler supports it and cmake is in use. --- CMakeLists.txt | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb077d2d31..4555258140 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,11 +118,6 @@ MACRO(CHECK_C_LINKER_FLAG M_FLAG M_RESULT) SET(CMAKE_REQUIRED_FLAGS "${T_REQ_FLAG}") ENDMACRO() -# Enable 'dist and distcheck'. -# File adapted from http://ensc.de/cmake/FindMakeDist.cmake -FIND_PACKAGE(MakeDist) -# End 'enable dist and distcheck' - # Set the build type. IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE DEBUG CACHE STRING "Choose the type of build, options are: None, Debug, Release." @@ -199,6 +194,15 @@ ENDIF() OPTION(NC_FIND_SHARED_LIBS "Find dynamically-built versions of dependent libraries" ${BUILD_SHARED_LIBS}) +## +# Check to see if C compiler supports -fno-strict-aliasing, in support of +# https://github.com/Unidata/netcdf-c/issues/1983 +## +CHECK_C_COMPILER_FLAG(-fno-strict-aliasing CC_SUPPORTS_NO_STRICT_ALIASING) +IF(CC_SUPPORTS_NO_STRICT_ALIASING) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing") +ENDIF(CC_SUPPORTS_NO_STRICT_ALIASING) + ## # We've had a request to allow for non-versioned shared libraries. # This seems reasonable enough to accommodate. See @@ -861,7 +865,7 @@ int main() { }" HAVE_LIBCURL_766) IF (HAVE_LIBCURL_766) - # If libcurl version is >= 7.66, then can skip tests + # If libcurl version is >= 7.66, then can skip tests # for these symbols which were added in an earlier version set(HAVE_CURLOPT_USERNAME TRUE) set(HAVE_CURLOPT_PASSWORD TRUE) @@ -977,9 +981,9 @@ IF(MSVC) FILE(COPY ${netCDF_SOURCE_DIR}/libsrc/XGetopt.c DESTINATION ${netCDF_BINARY_DIR}/ncdump/) FILE(COPY ${netCDF_SOURCE_DIR}/libsrc/XGetopt.c - DESTINATION ${netCDF_BINARY_DIR}/nczarr_test/) + DESTINATION ${netCDF_BINARY_DIR}/nczarr_test/) FILE(COPY ${netCDF_SOURCE_DIR}/libsrc/XGetopt.c - DESTINATION ${netCDF_BINARY_DIR}/ncdap_test/) + DESTINATION ${netCDF_BINARY_DIR}/ncdap_test/) ENDIF() ENDIF() @@ -2122,9 +2126,6 @@ INSTALL(PROGRAMS ${netCDF_BINARY_DIR}/nc-config ## print_conf_summary() -# Enable Makedist files. -ADD_MAKEDIST() -ENABLE_MAKEDIST(README.md COPYRIGHT RELEASE_NOTES.md INSTALL INSTALL.cmake test_prog.c lib_flags.am cmake CMakeLists.txt COMPILE.cmake.txt config.h.cmake.in cmake_uninstall.cmake.in netcdf-config-version.cmake.in netcdf-config.cmake.in FixBundle.cmake.in nc-config.cmake.in configure configure.ac install-sh config.h.in config.sub CTestConfig.cmake.in) ##### # Configure and print the libnetcdf.settings file.