From 0e597471aff206460f02999d6ea9e1e3243ef945 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 7 Feb 2013 16:23:48 -0500 Subject: [PATCH 1/2] Use a nicely written autoconf macro to determine the sign of a type This beats our old implementation, which wouldn't work when cross-compiling --- Makefile.am | 2 ++ autogen.sh | 2 +- changes/signof_enum | 4 ++++ configure.ac | 28 ++++++----------------- m4/ax_check_sign.m4 | 54 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 changes/signof_enum create mode 100644 m4/ax_check_sign.m4 diff --git a/Makefile.am b/Makefile.am index 2854763d25..4639c22c41 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,6 +7,8 @@ # 1.9 means we require automake vesion 1.9 AUTOMAKE_OPTIONS = foreign 1.9 subdir-objects +ACLOCAL_AMFLAGS = -I m4 + noinst_LIBRARIES= EXTRA_DIST= noinst_HEADERS= diff --git a/autogen.sh b/autogen.sh index efa2251c24..8c43a9798a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -17,7 +17,7 @@ fi set -e # Run this to generate all the initial makefiles, etc. -aclocal && \ +aclocal -I m4 && \ autoheader && \ autoconf && \ automake --add-missing --copy diff --git a/changes/signof_enum b/changes/signof_enum new file mode 100644 index 0000000000..fc9b9eda29 --- /dev/null +++ b/changes/signof_enum @@ -0,0 +1,4 @@ + o Code simplifications and refactoring: + - Use Ville Laurikari's implementation of AX_CHECK_SIGN() to determine + the signs of types during autoconf. This is better than our old + approach, which didn't work when cross-compiling. diff --git a/configure.ac b/configure.ac index c27cbd2c85..e80e6f6121 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,7 @@ dnl See LICENSE for licensing information AC_INIT([tor],[0.2.4.10-alpha-dev]) AC_CONFIG_SRCDIR([src/or/main.c]) +AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS([orconfig.h]) @@ -957,8 +958,9 @@ AC_CHECK_TYPES([rlim_t], , , #endif ]) -AC_CACHE_CHECK([whether time_t is signed], tor_cv_time_t_signed, [ -AC_RUN_IFELSE([AC_LANG_SOURCE([ +AX_CHECK_SIGN([time_t], + [ AC_DEFINE(TIME_T_IS_SIGNED, 1, [Define if time_t is signed]) ], + [ : ], [ #ifdef HAVE_SYS_TYPES_H #include #endif @@ -968,32 +970,16 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([ #ifdef HAVE_TIME_H #include #endif -int main(int c, char**v) { if (((time_t)-1)<0) return 1; else return 0; }])], - tor_cv_time_t_signed=no, tor_cv_time_t_signed=yes, tor_cv_time_t_signed=cross) ]) -if test "$tor_cv_time_t_signed" = cross; then - AC_MSG_NOTICE([Cross compiling: assuming that time_t is signed.]) -fi - -if test "$tor_cv_time_t_signed" != no; then - AC_DEFINE([TIME_T_IS_SIGNED], 1, - [Define to 1 iff time_t is signed]) -fi - -AC_CACHE_CHECK([whether size_t is signed], tor_cv_size_t_signed, [ -AC_RUN_IFELSE([AC_LANG_SOURCE([ +AX_CHECK_SIGN([size_t], + [ tor_cv_size_t_signed=yes ], + [ tor_cv_size_t_signed=no ], [ #ifdef HAVE_SYS_TYPES_H #include #endif -int main(int c, char**v) { if (((size_t)-1)<0) return 1; else return 0; }])], - tor_cv_size_t_signed=no, tor_cv_size_t_signed=yes, tor_cv_size_t_signed=cross) ]) -if test "$tor_cv_size_t_signed" = cross; then - AC_MSG_NOTICE([Cross compiling: assuming that size_t is not signed.]) -fi - if test "$tor_cv_size_t_signed" = yes; then AC_MSG_ERROR([You have a signed size_t; that's grossly nonconformant.]) fi diff --git a/m4/ax_check_sign.m4 b/m4/ax_check_sign.m4 new file mode 100644 index 0000000000..104b17014c --- /dev/null +++ b/m4/ax_check_sign.m4 @@ -0,0 +1,54 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_sign.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_SIGN (TYPE, [ACTION-IF-SIGNED], [ACTION-IF-UNSIGNED], [INCLUDES]) +# +# DESCRIPTION +# +# Checks whether TYPE is signed or not. If no INCLUDES are specified, the +# default includes are used. If ACTION-IF-SIGNED is given, it is +# additional shell code to execute when the type is signed. If +# ACTION-IF-UNSIGNED is given, it is executed when the type is unsigned. +# +# This macro assumes that the type exists. Therefore the existence of the +# type should be checked before calling this macro. For example: +# +# AC_CHECK_HEADERS([wchar.h]) +# AC_CHECK_TYPE([wchar_t],,[ AC_MSG_ERROR([Type wchar_t not found.]) ]) +# AX_CHECK_SIGN([wchar_t], +# [ AC_DEFINE(WCHAR_T_SIGNED, 1, [Define if wchar_t is signed]) ], +# [ AC_DEFINE(WCHAR_T_UNSIGNED, 1, [Define if wchar_t is unsigned]) ], [ +# #ifdef HAVE_WCHAR_H +# #include +# #endif +# ]) +# +# LICENSE +# +# Copyright (c) 2008 Ville Laurikari +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AU_ALIAS([VL_CHECK_SIGN], [AX_CHECK_SIGN]) +AC_DEFUN([AX_CHECK_SIGN], [ + typename=`echo $1 | sed "s/@<:@^a-zA-Z0-9_@:>@/_/g"` + AC_CACHE_CHECK([whether $1 is signed], ax_cv_decl_${typename}_signed, [ + AC_TRY_COMPILE([$4], + [ int foo @<:@ 1 - 2 * !((($1) -1) < 0) @:>@ ], + [ eval "ax_cv_decl_${typename}_signed=\"yes\"" ], + [ eval "ax_cv_decl_${typename}_signed=\"no\"" ])]) + symbolname=`echo $1 | sed "s/@<:@^a-zA-Z0-9_@:>@/_/g" | tr "a-z" "A-Z"` + if eval "test \"\${ax_cv_decl_${typename}_signed}\" = \"yes\""; then + $2 + elif eval "test \"\${ax_cv_decl_${typename}_signed}\" = \"no\""; then + $3 + fi +])dnl From 41200b47709bcdaf6f3a66e8453b3d852bd8d2a6 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 7 Feb 2013 16:29:32 -0500 Subject: [PATCH 2/2] Have autoconf check whether enums are signed. Fixes bug 7727; fix on 0.2.4.10-alpha. --- changes/signof_enum | 3 +++ configure.ac | 6 ++++++ src/common/compat.h | 3 +-- src/win32/orconfig.h | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/changes/signof_enum b/changes/signof_enum index fc9b9eda29..ba4fb597d7 100644 --- a/changes/signof_enum +++ b/changes/signof_enum @@ -2,3 +2,6 @@ - Use Ville Laurikari's implementation of AX_CHECK_SIGN() to determine the signs of types during autoconf. This is better than our old approach, which didn't work when cross-compiling. + - Detect the sign of enum values, rather than assuming that MSC is the + only compiler where enum types are all signed. Fix for bug 7727; + bugfix on 0.2.4.10-alpha. diff --git a/configure.ac b/configure.ac index e80e6f6121..864477b8fc 100644 --- a/configure.ac +++ b/configure.ac @@ -984,6 +984,12 @@ if test "$tor_cv_size_t_signed" = yes; then AC_MSG_ERROR([You have a signed size_t; that's grossly nonconformant.]) fi +AX_CHECK_SIGN([enum always], + [ AC_DEFINE(ENUM_VALS_ARE_SIGNED, 1, [Define if enum is always signed]) ], + [ : ], [ + enum always { AAA, BBB, CCC }; +]) + AC_CHECK_SIZEOF(socklen_t, , [AC_INCLUDES_DEFAULT() #ifdef HAVE_SYS_SOCKET_H #include diff --git a/src/common/compat.h b/src/common/compat.h index d2944e6f48..fa071e5558 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -136,8 +136,7 @@ extern INLINE double U64_TO_DBL(uint64_t x) { #define DBL_TO_U64(x) ((uint64_t) (x)) #endif -#if defined(_MSC_VER) -/* XXXX024 we should instead have a more general check for "Is enum signed?"*/ +#ifdef ENUM_VALS_ARE_SIGNED #define ENUM_BF(t) unsigned #else /** Wrapper for having a bitfield of an enumerated type. Where possible, we diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h index 4312d9fbe5..f5d5cf4460 100644 --- a/src/win32/orconfig.h +++ b/src/win32/orconfig.h @@ -256,3 +256,4 @@ #define CURVE25519_ENABLED #define USE_CURVE25519_DONNA +#define ENUM_VALS_ARE_SIGNED 1