From 15f8838bb6239ebc16beb8472de0217a10de3d5e Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 20 Oct 2009 08:30:03 -0600 Subject: [PATCH] Fix AC_TYPE_UINT64_T on Tru64 with gcc 3.4.4. * lib/autoconf/types.m4 (_AC_TYPE_UNSIGNED_INT_BODY) (_AC_TYPE_INT_BODY): Avoid undefined behavior of attempting shift wider than type. * NEWS: Document this. Reported by Rainer Orth. Signed-off-by: Eric Blake --- ChangeLog | 9 +++++++++ NEWS | 4 ++++ lib/autoconf/types.m4 | 14 ++++++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 82dd475b..a2f56f73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-10-20 Eric Blake + + Fix AC_TYPE_UINT64_T on Tru64 with gcc 3.4.4. + * lib/autoconf/types.m4 (_AC_TYPE_UNSIGNED_INT_BODY) + (_AC_TYPE_INT_BODY): Avoid undefined behavior of attempting shift + wider than type. + * NEWS: Document this. + Reported by Rainer Orth. + 2009-10-17 Ralf Wildenhues Fix a couple of index entries in the manual. diff --git a/NEWS b/NEWS index f7384268..666cd4fb 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,10 @@ GNU Autoconf NEWS - User visible changes. made it fail with some Fortran compilers (regression introduced in 2.64). +** The AC_TYPE_UINT64_T and AC_TYPE_INT64_T macros have been fixed to no + longer mistakenly select a 32-bit type on some compilers (bug present + since macros were introduced in 2.59c). + ** The following documented autotest macros are new: AT_CHECK_EUNIT diff --git a/lib/autoconf/types.m4 b/lib/autoconf/types.m4 index a5379670..7a73fc29 100644 --- a/lib/autoconf/types.m4 +++ b/lib/autoconf/types.m4 @@ -629,17 +629,21 @@ m4_define([_AC_TYPE_INT_BODY], [ AS_LINENO_PUSH([$[]1]) AC_CACHE_CHECK([for int$[]2_t], [$[]3], [AS_VAR_SET([$[]3], [no]) + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. for ac_type in int$[]2_t 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [AC_INCLUDES_DEFAULT], - [0 < ($ac_type) (((($ac_type) 1 << ($[]2 - 2)) - 1) * 2 + 1)])], + [enum { N = $[]2 / 2 - 1 }; + 0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)])], [AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [AC_INCLUDES_DEFAULT], - [($ac_type) (((($ac_type) 1 << ($[]2 - 2)) - 1) * 2 + 1) - < ($ac_type) (((($ac_type) 1 << ($[]2 - 2)) - 1) * 2 + 2)])], + [enum { N = $[]2 / 2 - 1 }; + ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2)])], [], [AS_CASE([$ac_type], [int$[]2_t], [AS_VAR_SET([$[]3], [yes])], @@ -679,12 +683,14 @@ m4_define([_AC_TYPE_UNSIGNED_INT_BODY], [ AS_LINENO_PUSH([$[]1]) AC_CACHE_CHECK([for uint$[]2_t], $[]3, [AS_VAR_SET([$[]3], [no]) + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. for ac_type in uint$[]2_t 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [AC_INCLUDES_DEFAULT], - [($ac_type) -1 >> ($[]2 - 1) == 1])], + [(($ac_type) -1 >> ($[]2 / 2 - 1)) >> ($[]2 / 2 - 1) == 3])], [AS_CASE([$ac_type], [uint$[]2_t], [AS_VAR_SET([$[]3], [yes])], [AS_VAR_SET([$[]3], [$ac_type])])])