commit 623c1912051d4fccec3be22e98e53d9f680f6f8a Author: Zack Weinberg zackw@panix.com Date: Mon Mar 5 16:49:13 2012 -0800
Add autoconf probes for C++11 and method deletion; use the latter in crypt.h. --- configure.ac | 3 + m4/cxx_delete_method.m4 | 76 ++++++++++++++++++++++++++++++++ m4/cxxflags_stdcxx_11.m4 | 107 ++++++++++++++++++++++++++++++++++++++++++++++ m4/winsock.m4 | 10 ++-- src/crypt.h | 12 +++--- 5 files changed, 197 insertions(+), 11 deletions(-)
diff --git a/configure.ac b/configure.ac index ca76a7a..d491479 100644 --- a/configure.ac +++ b/configure.ac @@ -65,6 +65,9 @@ LIBS="$LIBS $ws32_LIBS"
AC_CHECK_HEADERS([execinfo.h],,, [AC_INCLUDES_DEFAULT()])
+AX_CXXFLAGS_STDCXX_11([ext]) +AX_CXX_DELETE_METHOD + ### Output ###
AC_CONFIG_FILES([Makefile]) diff --git a/m4/cxx_delete_method.m4 b/m4/cxx_delete_method.m4 new file mode 100644 index 0000000..2f7decf --- /dev/null +++ b/m4/cxx_delete_method.m4 @@ -0,0 +1,76 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_delete_method.m4 +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_DELETE_METHOD +# +# DESCRIPTION +# +# Check whether the C++11 '= delete' syntax, for suppressing undesired +# implicit methods, is supported. If it is, the macro DELETE_METHOD is +# defined to '= delete'; otherwise it is defined to nothing. Thus, you +# can write +# +# class foo { +# ... +# private: +# foo(foo const&) DELETE_METHOD; +# }; +# +# to delete the 'foo' copy constructor or fall back to the idiom of +# a private undefined method if the compiler doesn't support this. +# +# Does not test '= delete' on a template specialization. +# Does not ensure that the compiler is in C++11 mode. +# +# LICENSE +# +# Copyright (c) 2012 Zack Weinberg zackw@panix.com +# +# 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. + +AC_DEFUN([AX_CXX_DELETE_METHOD], [dnl + AC_LANG_ASSERT([C++]) + # This compilation should succeed... + AC_CACHE_CHECK(whether $CXX accepts method deletion, + ax_cv_cxx_delete_method_syntax, [ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + struct foo { + foo(double); + foo(int) = delete; + }; + extern void t(foo const&); + void tt(double n) { t(n); } + ]])], + [ax_cv_cxx_delete_method_syntax=yes], + [ax_cv_cxx_delete_method_syntax=no])]) + # ... and this one should fail. + AC_CACHE_CHECK(whether $CXX enforces method deletion, + ax_cv_cxx_delete_method_enforced, [ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + struct foo { + foo(double); + foo(int) = delete; + }; + extern void t(foo const&); + void tt(int n) { t(n); } + ]])], + [ax_cv_cxx_delete_method_enforced=no], + [ax_cv_cxx_delete_method_enforced=yes])]) + if test $ax_cv_cxx_delete_method_syntax = yes && + test $ax_cv_cxx_delete_method_enforced = yes + then + AC_DEFINE([DELETE_METHOD], [= delete], + [Define as `= delete' if your compiler supports C++11 method + deletion, as nothing otherwise.]) + else + AC_DEFINE([DELETE_METHOD], [], + [Define as `= delete' if your compiler supports C++11 method + deletion, as nothing otherwise.]) + fi +]) diff --git a/m4/cxxflags_stdcxx_11.m4 b/m4/cxxflags_stdcxx_11.m4 new file mode 100644 index 0000000..1c5c0f2 --- /dev/null +++ b/m4/cxxflags_stdcxx_11.m4 @@ -0,0 +1,107 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxxflags_stdcxx_11.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXXFLAGS_STDCXX_11([ext|noext]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXXFLAGS to enable support. +# Errors out if no mode that supports C++11 baseline syntax can be found. +# The argument, if specified, indicates whether you insist on an extended +# mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -std=c++11). +# If neither is specified, you get whatever works, with preference for an +# extended mode. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik bkoz@redhat.com +# Copyright (c) 2012 Zack Weinberg zackw@panix.com +# +# 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 8 + +m4_define([_AX_CXXFLAGS_STDCXX_11_testbody], [ + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c); +]) + +AC_DEFUN([AX_CXXFLAGS_STDCXX_11], [dnl + m4_if([$1], [], [], + [$1], [ext], [], + [$1], [noext], [], + [m4_fatal([invalid argument `$1' to AX_CXXFLAGS_STDCXX_11])])dnl + AC_LANG_ASSERT([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++11 features by default, + ax_cv_cxx_compile_cxx11, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXXFLAGS_STDCXX_11_testbody])], + [ax_cv_cxx_compile_cxx11=yes], + [ax_cv_cxx_compile_cxx11=no])]) + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + m4_if([$1], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++11 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXXFLAGS_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$1], [ext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=c++11 -std=c++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXXFLAGS_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) + fi +]) diff --git a/m4/winsock.m4 b/m4/winsock.m4 index a90cc50..fd3d8b5 100644 --- a/m4/winsock.m4 +++ b/m4/winsock.m4 @@ -47,10 +47,10 @@ AC_DEFUN([AX_LIB_WINSOCK2], ])
ws32_LIBS= - if test "x$ac_cv_search_ntohl" == "xno"; then - AC_MSG_ERROR([could not find ntohl]) - elif test "x$ac_cv_search_ntohl" != "xnone required"; then - ws32_LIBS="$ac_cv_search_ntohl" - fi + case "$ac_cv_search_ntohl" in + no) AC_MSG_ERROR([could not find ntohl]) ;; + "none required") ;; + *) ws32_LIBS="$ac_cv_search_ntohl" + esac AC_SUBST(ws32_LIBS) ]) diff --git a/src/crypt.h b/src/crypt.h index 062625e..e87de0a 100644 --- a/src/crypt.h +++ b/src/crypt.h @@ -25,8 +25,8 @@ struct encryptor
encryptor() {} private: - encryptor(const encryptor&); - encryptor& operator=(const encryptor&); + encryptor(const encryptor&) DELETE_METHOD; + encryptor& operator=(const encryptor&) DELETE_METHOD; };
struct decryptor @@ -55,8 +55,8 @@ struct decryptor
decryptor() {} private: - decryptor(const decryptor&); - decryptor& operator=(const decryptor&); + decryptor(const decryptor&) DELETE_METHOD; + decryptor& operator=(const decryptor&) DELETE_METHOD; };
/** Generate keying material from an initial key of some kind, a salt @@ -95,8 +95,8 @@ struct key_generator virtual ~key_generator(); key_generator() {} private: - key_generator(const decryptor&); - key_generator& operator=(const decryptor&); + key_generator(const key_generator&) DELETE_METHOD; + key_generator& operator=(const key_generator&) DELETE_METHOD; };
#endif
tor-commits@lists.torproject.org