summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2013-09-19 18:57:41 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2013-09-19 18:57:41 (GMT)
commitbe3a33155025d6ef2d57533b60b96c888ab314a6 (patch)
tree2becf1264da71c35b6942b5858704f85cd8f189d /src
parent0653325f0d4a92164842bb30b797f130e44cbc68 (diff)
downloadhdf5-be3a33155025d6ef2d57533b60b96c888ab314a6.zip
hdf5-be3a33155025d6ef2d57533b60b96c888ab314a6.tar.gz
hdf5-be3a33155025d6ef2d57533b60b96c888ab314a6.tar.bz2
[svn-r24171] Purpose: Fix problem with gcc 4.8
Description: With optimization enabled, gcc 4.8 inserts garbage into the padding bytes of floating point types when assigning from a literal constant. This caused problems when H5detect.c scanned the bits in floating point types to determine their properties. Modified H5detect.c to scan for padding before further analyzing the type, and to ignore all information in the padding areas. Also removed code that temporarily disabled optimization. Tested: jam, koala, ostrich, platypus (h5committest)
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/H5detect.c215
-rw-r--r--src/Makefile.am1
-rw-r--r--src/Makefile.in24
4 files changed, 125 insertions, 122 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 8e7a3bf..718a41f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -773,13 +773,8 @@ INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR})
# Setup the H5Detect utility which generates H5Tinit with platform
# specific type checks inside
#-----------------------------------------------------------------------------
-IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
- SET (LOCAL_OPT_FLAG "-O0")
-ELSE (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
- SET (LOCAL_OPT_FLAG " ")
-ENDIF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
ADD_EXECUTABLE (H5detect ${HDF5_SRC_DIR}/H5detect.c)
-TARGET_C_PROPERTIES (H5detect ${LOCAL_OPT_FLAG} " ")
+TARGET_C_PROPERTIES (H5detect " " " ")
IF (MSVC)
TARGET_LINK_LIBRARIES (H5detect "ws2_32.lib")
ENDIF (MSVC)
diff --git a/src/H5detect.c b/src/H5detect.c
index caed569..be661ea 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -118,10 +118,12 @@ static volatile int nd_g = 0, na_g = 0;
static void print_results(int nd, detected_t *d, int na, malign_t *m);
static void iprint(detected_t *);
-static int byte_cmp(int, const void *, const void *);
-static int bit_cmp(int, int *, volatile void *, volatile void *);
+static int byte_cmp(int, const void *, const void *, const unsigned char *);
+static int bit_cmp(int, int *, volatile void *, volatile void *,
+ const unsigned char *);
static void fix_order(int, int, int *, const char **);
-static int imp_bit(int, int *, volatile void *, volatile void *);
+static int imp_bit(int, int *, volatile void *, volatile void *,
+ const unsigned char *);
static unsigned long find_bias(int, int, int *, void *);
static void precision (detected_t*);
static void print_header(void);
@@ -298,71 +300,88 @@ precision (detected_t *d)
*
*-------------------------------------------------------------------------
*/
-#define DETECT_F(TYPE,VAR,INFO) { \
- volatile TYPE _v1, _v2, _v3; \
- unsigned char _buf1[sizeof(TYPE)], _buf3[sizeof(TYPE)]; \
- int _i, _j, _last = (-1); \
- char *_mesg; \
- \
- HDmemset(&INFO, 0, sizeof(INFO)); \
- INFO.varname = #VAR; \
- INFO.size = sizeof(TYPE); \
- \
- /* Completely initialize temporary variables, in case the bits used in */ \
- /* the type take less space than the number of bits used to store the type */ \
- HDmemset(&_v3, 0, sizeof(TYPE)); \
- HDmemset(&_v2, 0, sizeof(TYPE)); \
- HDmemset(&_v1, 0, sizeof(TYPE)); \
- \
- /* Byte Order */ \
- for(_i = 0, _v1 = 0.0, _v2 = 1.0; _i < (int)sizeof(TYPE); _i++) { \
- _v3 = _v1; \
- _v1 += _v2; \
- _v2 /= 256.0; \
- HDmemcpy(_buf1, (const void *)&_v1, sizeof(TYPE)); \
- HDmemcpy(_buf3, (const void *)&_v3, sizeof(TYPE)); \
- _j = byte_cmp(sizeof(TYPE), &_buf3, &_buf1); \
- if(_j >= 0) { \
- INFO.perm[_i] = _j; \
- _last = _i; \
- } \
- } \
- fix_order(sizeof(TYPE), _last, INFO.perm, (const char**)&_mesg); \
+#define DETECT_F(TYPE,VAR,INFO) { \
+ volatile TYPE _v1, _v2, _v3; \
+ unsigned char _buf1[sizeof(TYPE)], _buf3[sizeof(TYPE)]; \
+ unsigned char _pad_mask[sizeof(TYPE)]; \
+ unsigned char _byte_mask; \
+ int _i, _j, _last = (-1); \
+ char *_mesg; \
\
- if(!HDstrcmp(_mesg, "VAX")) \
- INFO.is_vax = TRUE; \
- \
- /* Implicit mantissa bit */ \
- _v1 = 0.5; \
- _v2 = 1.0; \
- INFO.imp = imp_bit (sizeof(TYPE), INFO.perm, &_v1, &_v2); \
- \
- /* Sign bit */ \
- _v1 = 1.0; \
- _v2 = -1.0; \
- INFO.sign = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2); \
- \
- /* Mantissa */ \
- INFO.mpos = 0; \
- \
- _v1 = 1.0; \
- _v2 = 1.5; \
- INFO.msize = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2); \
- INFO.msize += 1 + (INFO.imp?0:1) - INFO.mpos; \
- \
- /* Exponent */ \
- INFO.epos = INFO.mpos + INFO.msize; \
- \
- INFO.esize = INFO.sign - INFO.epos; \
- \
- _v1 = 1.0; \
- INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \
- precision (&(INFO)); \
- ALIGNMENT(TYPE, INFO); \
- if(!HDstrcmp(INFO.varname, "FLOAT") || !HDstrcmp(INFO.varname, "DOUBLE") || \
- !HDstrcmp(INFO.varname, "LDOUBLE")) { \
- COMP_ALIGNMENT(TYPE,INFO.comp_align); \
- } \
+ HDmemset(&INFO, 0, sizeof(INFO)); \
+ INFO.varname = #VAR; \
+ INFO.size = sizeof(TYPE); \
+ \
+ /* Initialize padding mask */ \
+ HDmemset(_pad_mask, 0, sizeof(_pad_mask)); \
+ \
+ /* Padding bits. Set a variable to 4.0, then flip each bit and see if \
+ * the modified variable is equal ("==") to the original. Build a \
+ * padding bitmask to indicate which bits in the type are padding (i.e. \
+ * have no effect on the value and should be ignored by subsequent \
+ * steps). This is necessary because padding bits can change arbitrarily \
+ * and interfere with detection of the various properties below unless we \
+ * know to ignore them. */ \
+ _v1 = 4.0; \
+ HDmemcpy(_buf1, (const void *)&_v1, sizeof(TYPE)); \
+ for(_i = 0; _i < (int)sizeof(TYPE); _i++) \
+ for(_byte_mask = (unsigned char)1; _byte_mask; _byte_mask <<= 1) { \
+ _buf1[_i] ^= _byte_mask; \
+ HDmemcpy((void *)&_v2, (const void *)_buf1, sizeof(TYPE)); \
+ if(_v1 != _v2) \
+ _pad_mask[_i] |= _byte_mask; \
+ _buf1[_i] ^= _byte_mask; \
+ } /* enf for */ \
+ \
+ /* Byte Order */ \
+ for(_i = 0, _v1 = 0.0, _v2 = 1.0; _i < (int)sizeof(TYPE); _i++) { \
+ _v3 = _v1; \
+ _v1 += _v2; \
+ _v2 /= 256.0; \
+ HDmemcpy(_buf1, (const void *)&_v1, sizeof(TYPE)); \
+ HDmemcpy(_buf3, (const void *)&_v3, sizeof(TYPE)); \
+ _j = byte_cmp(sizeof(TYPE), _buf3, _buf1, _pad_mask); \
+ if(_j >= 0) { \
+ INFO.perm[_i] = _j; \
+ _last = _i; \
+ } \
+ } \
+ fix_order(sizeof(TYPE), _last, INFO.perm, (const char**)&_mesg); \
+ \
+ if(!HDstrcmp(_mesg, "VAX")) \
+ INFO.is_vax = TRUE; \
+ \
+ /* Implicit mantissa bit */ \
+ _v1 = 0.5; \
+ _v2 = 1.0; \
+ INFO.imp = imp_bit (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask); \
+ \
+ /* Sign bit */ \
+ _v1 = 1.0; \
+ _v2 = -1.0; \
+ INFO.sign = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask); \
+ \
+ /* Mantissa */ \
+ INFO.mpos = 0; \
+ \
+ _v1 = 1.0; \
+ _v2 = 1.5; \
+ INFO.msize = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask); \
+ INFO.msize += 1 + (INFO.imp?0:1) - INFO.mpos; \
+ \
+ /* Exponent */ \
+ INFO.epos = INFO.mpos + INFO.msize; \
+ \
+ INFO.esize = INFO.sign - INFO.epos; \
+ \
+ _v1 = 1.0; \
+ INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \
+ precision (&(INFO)); \
+ ALIGNMENT(TYPE, INFO); \
+ if(!HDstrcmp(INFO.varname, "FLOAT") || !HDstrcmp(INFO.varname, "DOUBLE") || \
+ !HDstrcmp(INFO.varname, "LDOUBLE")) { \
+ COMP_ALIGNMENT(TYPE,INFO.comp_align); \
+ } \
}
@@ -887,7 +906,8 @@ iprint(detected_t *d)
*
* Purpose: Compares two chunks of memory A and B and returns the
* byte index into those arrays of the first byte that
- * differs between A and B.
+ * differs between A and B. Ignores differences where the
+ * corresponding bit in pad_mask is set to 0.
*
* Return: Success: Index of differing byte.
*
@@ -902,13 +922,16 @@ iprint(detected_t *d)
*-------------------------------------------------------------------------
*/
static int
-byte_cmp(int n, const void *_a, const void *_b)
+byte_cmp(int n, const void *_a, const void *_b, const unsigned char *pad_mask)
{
- int i;
- const unsigned char *a = (const unsigned char *) _a;
- const unsigned char *b = (const unsigned char *) _b;
+ int i;
+ const unsigned char *a = (const unsigned char *) _a;
+ const unsigned char *b = (const unsigned char *) _b;
+
+ for(i = 0; i < n; i++)
+ if((a[i] & pad_mask[i]) != (b[i] & pad_mask[i]))
+ return i;
- for (i = 0; i < n; i++) if (a[i] != b[i]) return i;
return -1;
}
@@ -919,7 +942,8 @@ byte_cmp(int n, const void *_a, const void *_b)
* Purpose: Compares two bit vectors and returns the index for the
* first bit that differs between the two vectors. The
* size of the vector is NBYTES. PERM is a mapping from
- * actual order to little endian.
+ * actual order to little endian. Ignores differences where
+ * the corresponding bit in pad_mask is set to 0.
*
* Return: Success: Index of first differing bit.
*
@@ -934,22 +958,24 @@ byte_cmp(int n, const void *_a, const void *_b)
*-------------------------------------------------------------------------
*/
static int
-bit_cmp(int nbytes, int *perm, volatile void *_a, volatile void *_b)
+bit_cmp(int nbytes, int *perm, volatile void *_a, volatile void *_b,
+ const unsigned char *pad_mask)
{
- int i, j;
- volatile unsigned char *a = (volatile unsigned char *) _a;
- volatile unsigned char *b = (volatile unsigned char *) _b;
- unsigned char aa, bb;
+ int i, j;
+ volatile unsigned char *a = (volatile unsigned char *) _a;
+ volatile unsigned char *b = (volatile unsigned char *) _b;
+ unsigned char aa, bb;
for (i = 0; i < nbytes; i++) {
- HDassert(perm[i] < nbytes);
- if ((aa = a[perm[i]]) != (bb = b[perm[i]])) {
- for (j = 0; j < 8; j++, aa >>= 1, bb >>= 1) {
- if ((aa & 1) != (bb & 1)) return i * 8 + j;
- }
- fprintf(stderr, "INTERNAL ERROR");
- HDabort();
- }
+ HDassert(perm[i] < nbytes);
+ if ((aa = a[perm[i]] & pad_mask[perm[i]])
+ != (bb = b[perm[i]] & pad_mask[perm[i]])) {
+ for (j = 0; j < 8; j++, aa >>= 1, bb >>= 1) {
+ if ((aa & 1) != (bb & 1)) return i * 8 + j;
+ }
+ fprintf(stderr, "INTERNAL ERROR");
+ HDabort();
+ }
}
return -1;
}
@@ -1058,18 +1084,19 @@ fix_order(int n, int last, int *perm, const char **mesg)
*-------------------------------------------------------------------------
*/
static int
-imp_bit(int n, int *perm, volatile void *_a, volatile void *_b)
+imp_bit(int n, int *perm, volatile void *_a, volatile void *_b,
+ const unsigned char *pad_mask)
{
- volatile unsigned char *a = (volatile unsigned char *) _a;
- volatile unsigned char *b = (volatile unsigned char *) _b;
- int changed, major, minor;
- int msmb; /*most significant mantissa bit */
+ volatile unsigned char *a = (volatile unsigned char *) _a;
+ volatile unsigned char *b = (volatile unsigned char *) _b;
+ int changed, major, minor;
+ int msmb; /*most significant mantissa bit */
/*
* Look for the least significant bit that has changed between
- * A and B. This is the least significant bit of the exponent.
+ * A and B. This is the least significant bit of the exponent.
*/
- changed = bit_cmp(n, perm, a, b);
+ changed = bit_cmp(n, perm, a, b, pad_mask);
HDassert(changed >= 0);
/*
diff --git a/src/Makefile.am b/src/Makefile.am
index 2d7640e..f63a36e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,7 +27,6 @@ include $(top_srcdir)/config/lt_vers.am
# a long time to compile it with any optimization on. H5detect is used
# to generate H5Tinit.c once. So, optimization is not critical.
noinst_PROGRAMS = H5detect H5make_libsettings
-H5detect_CFLAGS = $(AM_CFLAGS) -g -O0
# Our main target, the HDF5 library
lib_LTLIBRARIES=libhdf5.la
diff --git a/src/Makefile.in b/src/Makefile.in
index f215b74..b31a9ae 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -182,11 +182,8 @@ libhdf5_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(libhdf5_la_LDFLAGS) $(LDFLAGS) -o $@
PROGRAMS = $(noinst_PROGRAMS)
H5detect_SOURCES = H5detect.c
-H5detect_OBJECTS = H5detect-H5detect.$(OBJEXT)
+H5detect_OBJECTS = H5detect.$(OBJEXT)
H5detect_LDADD = $(LDADD)
-H5detect_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(H5detect_CFLAGS) \
- $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
H5make_libsettings_SOURCES = H5make_libsettings.c
H5make_libsettings_OBJECTS = H5make_libsettings.$(OBJEXT)
H5make_libsettings_LDADD = $(LDADD)
@@ -524,7 +521,6 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
LT_VERS_INTERFACE = 6
LT_VERS_REVISION = 154
LT_VERS_AGE = 0
-H5detect_CFLAGS = $(AM_CFLAGS) -g -O0
# Our main target, the HDF5 library
lib_LTLIBRARIES = libhdf5.la
@@ -744,7 +740,7 @@ clean-noinstPROGRAMS:
rm -f $$list
H5detect$(EXEEXT): $(H5detect_OBJECTS) $(H5detect_DEPENDENCIES) $(EXTRA_H5detect_DEPENDENCIES)
@rm -f H5detect$(EXEEXT)
- $(AM_V_CCLD)$(H5detect_LINK) $(H5detect_OBJECTS) $(H5detect_LDADD) $(LIBS)
+ $(AM_V_CCLD)$(LINK) $(H5detect_OBJECTS) $(H5detect_LDADD) $(LIBS)
H5make_libsettings$(EXEEXT): $(H5make_libsettings_OBJECTS) $(H5make_libsettings_DEPENDENCIES) $(EXTRA_H5make_libsettings_DEPENDENCIES)
@rm -f H5make_libsettings$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(H5make_libsettings_OBJECTS) $(H5make_libsettings_LDADD) $(LIBS)
@@ -1013,7 +1009,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ztrans.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5checksum.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5dbg.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5detect-H5detect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5detect.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5lib_settings.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5make_libsettings.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5system.Plo@am__quote@
@@ -1041,20 +1037,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
-H5detect-H5detect.o: H5detect.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -MT H5detect-H5detect.o -MD -MP -MF $(DEPDIR)/H5detect-H5detect.Tpo -c -o H5detect-H5detect.o `test -f 'H5detect.c' || echo '$(srcdir)/'`H5detect.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='H5detect.c' object='H5detect-H5detect.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -c -o H5detect-H5detect.o `test -f 'H5detect.c' || echo '$(srcdir)/'`H5detect.c
-
-H5detect-H5detect.obj: H5detect.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -MT H5detect-H5detect.obj -MD -MP -MF $(DEPDIR)/H5detect-H5detect.Tpo -c -o H5detect-H5detect.obj `if test -f 'H5detect.c'; then $(CYGPATH_W) 'H5detect.c'; else $(CYGPATH_W) '$(srcdir)/H5detect.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='H5detect.c' object='H5detect-H5detect.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -c -o H5detect-H5detect.obj `if test -f 'H5detect.c'; then $(CYGPATH_W) 'H5detect.c'; else $(CYGPATH_W) '$(srcdir)/H5detect.c'; fi`
-
mostlyclean-libtool:
-rm -f *.lo