* [PATCH 0/2] gdb: Require a C++11 compiler
@ 2016-10-27 19:21 Pedro Alves
2016-10-27 19:21 ` [PATCH 2/2] gdb: Require C++11 Pedro Alves
` (3 more replies)
0 siblings, 4 replies; 22+ messages in thread
From: Pedro Alves @ 2016-10-27 19:21 UTC (permalink / raw)
To: gdb-patches
As previously discussed, this patch set makes GDB require a C++11
compiler.
You'll find the previous discussions referenced here:
https://sourceware.org/ml/gdb-patches/2016-10/msg00607.html
This is basically the same as I had sent here:
https://sourceware.org/ml/gdb-patches/2016-10/msg00336.html
The only difference is a single-line change that makes C++11 a
mandatory instead of enabling it iff supported.
Pedro Alves (2):
gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive
gdb: Require C++11
gdb/Makefile.in | 6 +-
gdb/acinclude.m4 | 2 +
gdb/ax_cxx_compile_stdcxx.m4 | 567 +++++++++++++++++++++++++
gdb/config.in | 3 +
gdb/configure | 981 ++++++++++++++++++++++++++++++++++++++++++-
gdb/configure.ac | 4 +
gdb/gdbserver/Makefile.in | 5 +-
gdb/gdbserver/acinclude.m4 | 2 +
gdb/gdbserver/config.in | 3 +
gdb/gdbserver/configure | 981 ++++++++++++++++++++++++++++++++++++++++++-
gdb/gdbserver/configure.ac | 4 +
11 files changed, 2552 insertions(+), 6 deletions(-)
create mode 100644 gdb/ax_cxx_compile_stdcxx.m4
--
2.5.5
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 2/2] gdb: Require C++11 2016-10-27 19:21 [PATCH 0/2] gdb: Require a C++11 compiler Pedro Alves @ 2016-10-27 19:21 ` Pedro Alves [not found] ` <20161028104718.540c10ed@ThinkPad> 2016-11-03 15:39 ` Yao Qi 2016-10-27 19:21 ` [PATCH 1/2] gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive Pedro Alves ` (2 subsequent siblings) 3 siblings, 2 replies; 22+ messages in thread From: Pedro Alves @ 2016-10-27 19:21 UTC (permalink / raw) To: gdb-patches Use AX_CXX_COMPILE_STDCXX to detect if the compiler supports C++11, and if -std=xxx switches are necessary to enable C++11. We need to tweak AX_CXX_COMPILE_STDCXX a bit though. Pristine upstream AX_CXX_COMPILE_STDCXX appends -std=gnu++11 to CXX directly. That doesn't work for us, because the top level Makefile passes CXX down to subdirs, and that overrides whatever gdb/Makefile may set CXX to. The result would be that a make invocation from the build/gdb/ directory would use "g++ -std=gnu++11" as expected, while a make invocation at the top level would not. So instead of having AX_CXX_COMPILE_STDCXX set CXX directly, tweak it to AC_SUBST a separate variable -- CXX_DIALECT -- and use '$(CXX) (CXX_DIALECT)' to compile/link. Confirmed that this enables C++11 starting with gcc 4.8, the first gcc release with full C++11 support. Also confirmed that configure errors out gracefully with older GCC releases: checking whether /opt/gcc-4.7/bin/g++ supports C++11 features by default... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=gnu++11... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=gnu++0x... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=c++11... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=c++0x... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with +std=c++11... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -h std=c++11... no configure: error: *** A compiler with support for C++11 language features is required. Makefile:9451: recipe for target 'configure-gdb' failed make[1]: *** [configure-gdb] Error 1 make[1]: Leaving directory '/home/pedro/brno/pedro/gdb/mygit/cxx-convertion/build-gcc-4.7' If we need to revert back to making C++03 optional, all that's necessary is to change the "mandatory" to "optional" in configure.ac and regenerate configure (both gdb and gdbserver). gdb/ChangeLog: yyyy-mm-dd Pedro Alves <palves@redhat.com> * Makefile.in (CXX_DIALECT): Get from configure. (COMPILE.pre, CC_LD): Append $(CXX_DIALECT). (FLAGS_TO_PASS): Pass CXX_DIALECT. * acinclude.m4: Include ax_cxx_compile_stdcxx.m4. * ax_cxx_compile_stdcxx.m4: Add FSF copyright header. Set and AC_SUBST CXX_DIALECT instead of changing CXX/CXXCPP. * configure.ac: Call AX_CXX_COMPILE_STDCXX. * config.in: Regenerate. * configure: Regenerate. gdb/gdbserver/ChangeLog: yyyy-mm-dd Pedro Alves <palves@redhat.com> * Makefile.in (CXX_DIALECT): Get from configure. (COMPILE.pre, CC_LD): Append $(CXX_DIALECT). * acinclude.m4: Include ../ax_cxx_compile_stdcxx.m4. * configure.ac: Call AX_CXX_COMPILE_STDCXX. * config.in: Regenerate. * configure: Regenerate. --- gdb/Makefile.in | 6 +- gdb/acinclude.m4 | 2 + gdb/ax_cxx_compile_stdcxx.m4 | 21 +- gdb/config.in | 3 + gdb/configure | 981 ++++++++++++++++++++++++++++++++++++++++++- gdb/configure.ac | 4 + gdb/gdbserver/Makefile.in | 5 +- gdb/gdbserver/acinclude.m4 | 2 + gdb/gdbserver/config.in | 3 + gdb/gdbserver/configure | 981 ++++++++++++++++++++++++++++++++++++++++++- gdb/gdbserver/configure.ac | 4 + 11 files changed, 1998 insertions(+), 14 deletions(-) diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 2c88434..d035d8e 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -86,6 +86,7 @@ CATALOGS = @CATALOGS@ # distribution will fix your include files up. CC=@CC@ CXX=@CXX@ +CXX_DIALECT= @CXX_DIALECT@ # Dependency tracking information. DEPMODE = @CCDEPMODE@ @@ -94,7 +95,7 @@ depcomp = $(SHELL) $(srcdir)/../depcomp # Note that these are overridden by GNU make-specific code below if # GNU make is used. The overrides implement dependency tracking. -COMPILE.pre = $(CXX) +COMPILE.pre = $(CXX) $(CXX_DIALECT) COMPILE.post = -c -o $@ COMPILE = $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post) POSTCOMPILE = @true @@ -125,7 +126,7 @@ MAKEHTMLFLAGS = # Set this up with gcc if you have gnu ld and the loader will print out # line numbers for undefined references. #CC_LD=g++ -static -CC_LD=$(CXX) +CC_LD=$(CXX) $(CXX_DIALECT) # Where is our "include" directory? Typically $(srcdir)/../include. # This is essentially the header file directory for the library @@ -742,6 +743,7 @@ FLAGS_TO_PASS = \ "CC=$(CC)" \ "CFLAGS=$(CFLAGS)" \ "CXX=$(CXX)" \ + "CXX_DIALECT=$(CXX_DIALECT)" \ "CXXFLAGS=$(CXXFLAGS)" \ "DLLTOOL=$(DLLTOOL)" \ "LDFLAGS=$(LDFLAGS)" \ diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 index 4b3f7fc..daf4a91 100644 --- a/gdb/acinclude.m4 +++ b/gdb/acinclude.m4 @@ -68,6 +68,8 @@ m4_include(libiberty.m4) dnl For GDB_AC_PTRACE. m4_include(ptrace.m4) +m4_include(ax_cxx_compile_stdcxx.m4) + ## ----------------------------------------- ## ## ANSIfy the C compiler whenever possible. ## ## From Franc,ois Pinard ## diff --git a/gdb/ax_cxx_compile_stdcxx.m4 b/gdb/ax_cxx_compile_stdcxx.m4 index 2c18e49..ffaeb6e 100644 --- a/gdb/ax_cxx_compile_stdcxx.m4 +++ b/gdb/ax_cxx_compile_stdcxx.m4 @@ -1,3 +1,12 @@ +# Copyright (c) 2016 Free Software Foundation, Inc. +# +# Originally based on the AX_CXX_COMPILE_STDCXX macro found at the url +# below. +# +# Local GDB customizations: +# +# - AC_SUBST CXX_DIALECT instead of changing CXX/CXXCPP. +# # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== @@ -58,6 +67,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl + CXX_DIALECT="" ac_success=no AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, @@ -81,10 +91,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi + CXX_DIALECT="$switch" ac_success=yes break fi @@ -107,10 +114,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi + CXX_DIALECT="$switch" ac_success=yes break fi @@ -131,6 +135,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) + AC_SUBST(CXX_DIALECT) ]) diff --git a/gdb/config.in b/gdb/config.in index 3790d10..9c841ba 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -84,6 +84,9 @@ /* Define to 1 if you have the <curses.h> header file. */ #undef HAVE_CURSES_H +/* define if the compiler supports basic C++11 syntax */ +#undef HAVE_CXX11 + /* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if you don't. */ #undef HAVE_DECL_ADDR_NO_RANDOMIZE diff --git a/gdb/configure b/gdb/configure index e2d853d..d744f73 100755 --- a/gdb/configure +++ b/gdb/configure @@ -732,6 +732,8 @@ MAKE CCDEPMODE DEPDIR am__leading_dot +CXX_DIALECT +HAVE_CXX11 INSTALL_STRIP_PROGRAM STRIP install_sh @@ -4951,6 +4953,984 @@ ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. + + ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + CXX_DIALECT="" + ac_success=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } +if test "${ax_cv_cxx_compile_cxx11+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx11=yes +else + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + if test x$ac_success = xno; then + for switch in -std=gnu++11 -std=gnu++0x; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if { as_var=$cachevar; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX_DIALECT="$switch" + ac_success=yes + break + fi + done + fi + + if test x$ac_success = xno; then + for switch in -std=c++11 -std=c++0x +std=c++11 "-h std=c++11"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if { as_var=$cachevar; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX_DIALECT="$switch" + ac_success=yes + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + + # Dependency checking. rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null @@ -14202,7 +15182,6 @@ _ACEOF - # Check whether --enable-werror was given. if test "${enable_werror+set}" = set; then : enableval=$enable_werror; case "${enableval}" in diff --git a/gdb/configure.ac b/gdb/configure.ac index e451e60..83c2707 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -38,6 +38,10 @@ AC_CONFIG_AUX_DIR(..) AC_CANONICAL_SYSTEM AC_ARG_PROGRAM +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. +AX_CXX_COMPILE_STDCXX(11, , mandatory) + # Dependency checking. ZW_CREATE_DEPDIR ZW_PROG_COMPILER_DEPENDENCIES([CC]) diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 0db5287..5ba559c 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -51,6 +51,7 @@ RANLIB = @RANLIB@ CC = @CC@ CXX = @CXX@ +CXX_DIALECT= @CXX_DIALECT@ AR = @AR@ AR_FLAGS = rc @@ -61,7 +62,7 @@ depcomp = $(SHELL) $(srcdir)/../depcomp # Note that these are overridden by GNU make-specific code below if # GNU make is used. The overrides implement dependency tracking. -COMPILE.pre = $(CXX) +COMPILE.pre = $(CXX) $(CXX_DIALECT) COMPILE.post = -c -o $@ COMPILE = $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post) POSTCOMPILE = @true @@ -80,7 +81,7 @@ VPATH = @srcdir@ # Set this up with gcc if you have gnu ld and the loader will print out # line numbers for undefinded refs. #CC_LD=g++ -static -CC_LD=$(CXX) +CC_LD=$(CXX) $(CXX_DIALECT) # Where is the "include" directory? Traditionally ../include or ./include INCLUDE_DIR = ${srcdir}/../../include diff --git a/gdb/gdbserver/acinclude.m4 b/gdb/gdbserver/acinclude.m4 index 8ec9188..c75d783 100644 --- a/gdb/gdbserver/acinclude.m4 +++ b/gdb/gdbserver/acinclude.m4 @@ -29,6 +29,8 @@ m4_include(../libiberty.m4) dnl For GDB_AC_PTRACE. m4_include(../ptrace.m4) +m4_include(../ax_cxx_compile_stdcxx.m4) + dnl Check for existence of a type $1 in libthread_db.h dnl Based on BFD_HAVE_SYS_PROCFS_TYPE in bfd/bfd.m4. diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in index 04072cf..b721ea8 100644 --- a/gdb/gdbserver/config.in +++ b/gdb/gdbserver/config.in @@ -18,6 +18,9 @@ /* Define to 1 if you have the <arpa/inet.h> header file. */ #undef HAVE_ARPA_INET_H +/* define if the compiler supports basic C++11 syntax */ +#undef HAVE_CXX11 + /* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if you don't. */ #undef HAVE_DECL_ADDR_NO_RANDOMIZE diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure index f112517..bbce742 100755 --- a/gdb/gdbserver/configure +++ b/gdb/gdbserver/configure @@ -615,6 +615,8 @@ DEPDIR am__leading_dot host_noncanonical target_noncanonical +CXX_DIALECT +HAVE_CXX11 RANLIB AR INSTALL_DATA @@ -4656,6 +4658,984 @@ ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. + + ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + CXX_DIALECT="" + ac_success=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } +if test "${ax_cv_cxx_compile_cxx11+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx11=yes +else + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + if test x$ac_success = xno; then + for switch in -std=gnu++11 -std=gnu++0x; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if { as_var=$cachevar; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX_DIALECT="$switch" + ac_success=yes + break + fi + done + fi + + if test x$ac_success = xno; then + for switch in -std=c++11 -std=c++0x +std=c++11 "-h std=c++11"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if { as_var=$cachevar; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX_DIALECT="$switch" + ac_success=yes + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : @@ -6236,7 +7216,6 @@ fi - # Check whether --enable-werror was given. if test "${enable_werror+set}" = set; then : enableval=$enable_werror; case "${enableval}" in diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac index 6d5907b..11d8c79 100644 --- a/gdb/gdbserver/configure.ac +++ b/gdb/gdbserver/configure.ac @@ -38,6 +38,10 @@ AC_PROG_RANLIB AC_ARG_PROGRAM +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. +AX_CXX_COMPILE_STDCXX(11, , mandatory) + AC_HEADER_STDC # Set the 'development' global. -- 2.5.5 ^ permalink raw reply [flat|nested] 22+ messages in thread
[parent not found: <20161028104718.540c10ed@ThinkPad>]
* Re: [PATCH 2/2] gdb: Require C++11 [not found] ` <20161028104718.540c10ed@ThinkPad> @ 2016-10-28 9:03 ` Pedro Alves 2016-10-28 10:44 ` Philipp Rudo 0 siblings, 1 reply; 22+ messages in thread From: Pedro Alves @ 2016-10-28 9:03 UTC (permalink / raw) To: Philipp Rudo; +Cc: gdb-patches On 10/28/2016 09:47 AM, Philipp Rudo wrote: > Without knowing much about autoconf. But you are repeating those > exact 280 lines a total of 6 times in this patch. Isn't there a nicer > way? Like moving it to a function? It would make the path significantly > shorter. Oh, you're looking at "configure", but that's a generated file that autoconf spits out. The source for that repeated code is ax_cxx_compile_stdcxx.m4 (the file added by patch #1), and that one does contain a single copy of that code. autoconf decides to expand the same code more than once because the ax_cxx_compile_stdcxx.m4 file has support for testing c++14 too, and that inlines the C++11 standards tests too: dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) Becasily, those AX_CXX_COMPILE_STDCXX_foo calls mean "inline body of test code" here. So the duplicated code is already factored out and maintained in a single place. (I didn't strip out the support for C++14 from that script, to minimize changes compared to the upstream copy.) Below's the same patch but without the autogenerated bits. From ffb94ceac7fc12d6147bc3280bd8cd7d30dda4e1 Mon Sep 17 00:00:00 2001 From: Pedro Alves <palves@redhat.com> Date: Thu, 13 Oct 2016 00:27:45 +0100 Subject: [PATCH] gdb: Require C++11 Use AX_CXX_COMPILE_STDCXX to detect if the compiler supports C++11, and if -std=xxx switches are necessary to enable C++11. We need to tweak AX_CXX_COMPILE_STDCXX a bit though. Pristine upstream AX_CXX_COMPILE_STDCXX appends -std=gnu++11 to CXX directly. That doesn't work for us, because the top level Makefile passes CXX down to subdirs, and that overrides whatever gdb/Makefile may set CXX to. The result would be that a make invocation from the build/gdb/ directory would use "g++ -std=gnu++11" as expected, while a make invocation at the top level would not. So instead of having AX_CXX_COMPILE_STDCXX set CXX directly, tweak it to AC_SUBST a separate variable -- CXX_DIALECT -- and use '$(CXX) (CXX_DIALECT)' to compile/link. Confirmed that this enables C++11 starting with gcc 4.8, the first gcc release with full C++11 support. Also confirmed that configure errors out gracefully with older GCC releases: checking whether /opt/gcc-4.7/bin/g++ supports C++11 features by default... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=gnu++11... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=gnu++0x... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=c++11... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -std=c++0x... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with +std=c++11... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 features with -h std=c++11... no configure: error: *** A compiler with support for C++11 language features is required. Makefile:9451: recipe for target 'configure-gdb' failed make[1]: *** [configure-gdb] Error 1 make[1]: Leaving directory '/home/pedro/brno/pedro/gdb/mygit/cxx-convertion/build-gcc-4.7' If we need to revert back to making C++03 optional, all that's necessary is to change the "mandatory" to "optional" in configure.ac and regenerate configure (both gdb and gdbserver). gdb/ChangeLog: yyyy-mm-dd Pedro Alves <palves@redhat.com> * Makefile.in (CXX_DIALECT): Get from configure. (COMPILE.pre, CC_LD): Append $(CXX_DIALECT). (FLAGS_TO_PASS): Pass CXX_DIALECT. * acinclude.m4: Include ax_cxx_compile_stdcxx.m4. * ax_cxx_compile_stdcxx.m4: Add FSF copyright header. Set and AC_SUBST CXX_DIALECT instead of changing CXX/CXXCPP. * configure.ac: Call AX_CXX_COMPILE_STDCXX. * config.in: Regenerate. * configure: Regenerate. gdb/gdbserver/ChangeLog: yyyy-mm-dd Pedro Alves <palves@redhat.com> * Makefile.in (CXX_DIALECT): Get from configure. (COMPILE.pre, CC_LD): Append $(CXX_DIALECT). * acinclude.m4: Include ../ax_cxx_compile_stdcxx.m4. * configure.ac: Call AX_CXX_COMPILE_STDCXX. * config.in: Regenerate. * configure: Regenerate. --- gdb/Makefile.in | 6 +- gdb/acinclude.m4 | 2 + gdb/ax_cxx_compile_stdcxx.m4 | 21 +- gdb/config.in | 3 + gdb/configure | 981 ++++++++++++++++++++++++++++++++++++++++++- gdb/configure.ac | 4 + gdb/gdbserver/Makefile.in | 5 +- gdb/gdbserver/acinclude.m4 | 2 + gdb/gdbserver/config.in | 3 + gdb/gdbserver/configure | 981 ++++++++++++++++++++++++++++++++++++++++++- gdb/gdbserver/configure.ac | 4 + 11 files changed, 1998 insertions(+), 14 deletions(-) diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 2c88434..d035d8e 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -86,6 +86,7 @@ CATALOGS = @CATALOGS@ # distribution will fix your include files up. CC=@CC@ CXX=@CXX@ +CXX_DIALECT= @CXX_DIALECT@ # Dependency tracking information. DEPMODE = @CCDEPMODE@ @@ -94,7 +95,7 @@ depcomp = $(SHELL) $(srcdir)/../depcomp # Note that these are overridden by GNU make-specific code below if # GNU make is used. The overrides implement dependency tracking. -COMPILE.pre = $(CXX) +COMPILE.pre = $(CXX) $(CXX_DIALECT) COMPILE.post = -c -o $@ COMPILE = $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post) POSTCOMPILE = @true @@ -125,7 +126,7 @@ MAKEHTMLFLAGS = # Set this up with gcc if you have gnu ld and the loader will print out # line numbers for undefined references. #CC_LD=g++ -static -CC_LD=$(CXX) +CC_LD=$(CXX) $(CXX_DIALECT) # Where is our "include" directory? Typically $(srcdir)/../include. # This is essentially the header file directory for the library @@ -742,6 +743,7 @@ FLAGS_TO_PASS = \ "CC=$(CC)" \ "CFLAGS=$(CFLAGS)" \ "CXX=$(CXX)" \ + "CXX_DIALECT=$(CXX_DIALECT)" \ "CXXFLAGS=$(CXXFLAGS)" \ "DLLTOOL=$(DLLTOOL)" \ "LDFLAGS=$(LDFLAGS)" \ diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 index 4b3f7fc..daf4a91 100644 --- a/gdb/acinclude.m4 +++ b/gdb/acinclude.m4 @@ -68,6 +68,8 @@ m4_include(libiberty.m4) dnl For GDB_AC_PTRACE. m4_include(ptrace.m4) +m4_include(ax_cxx_compile_stdcxx.m4) + ## ----------------------------------------- ## ## ANSIfy the C compiler whenever possible. ## ## From Franc,ois Pinard ## diff --git a/gdb/ax_cxx_compile_stdcxx.m4 b/gdb/ax_cxx_compile_stdcxx.m4 index 2c18e49..ffaeb6e 100644 --- a/gdb/ax_cxx_compile_stdcxx.m4 +++ b/gdb/ax_cxx_compile_stdcxx.m4 @@ -1,3 +1,12 @@ +# Copyright (c) 2016 Free Software Foundation, Inc. +# +# Originally based on the AX_CXX_COMPILE_STDCXX macro found at the url +# below. +# +# Local GDB customizations: +# +# - AC_SUBST CXX_DIALECT instead of changing CXX/CXXCPP. +# # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== @@ -58,6 +67,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl + CXX_DIALECT="" ac_success=no AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, @@ -81,10 +91,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi + CXX_DIALECT="$switch" ac_success=yes break fi @@ -107,10 +114,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi + CXX_DIALECT="$switch" ac_success=yes break fi @@ -131,6 +135,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) + AC_SUBST(CXX_DIALECT) ]) diff --git a/gdb/configure.ac b/gdb/configure.ac index e451e60..83c2707 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -38,6 +38,10 @@ AC_CONFIG_AUX_DIR(..) AC_CANONICAL_SYSTEM AC_ARG_PROGRAM +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. +AX_CXX_COMPILE_STDCXX(11, , mandatory) + # Dependency checking. ZW_CREATE_DEPDIR ZW_PROG_COMPILER_DEPENDENCIES([CC]) diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 0db5287..5ba559c 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -51,6 +51,7 @@ RANLIB = @RANLIB@ CC = @CC@ CXX = @CXX@ +CXX_DIALECT= @CXX_DIALECT@ AR = @AR@ AR_FLAGS = rc @@ -61,7 +62,7 @@ depcomp = $(SHELL) $(srcdir)/../depcomp # Note that these are overridden by GNU make-specific code below if # GNU make is used. The overrides implement dependency tracking. -COMPILE.pre = $(CXX) +COMPILE.pre = $(CXX) $(CXX_DIALECT) COMPILE.post = -c -o $@ COMPILE = $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post) POSTCOMPILE = @true @@ -80,7 +81,7 @@ VPATH = @srcdir@ # Set this up with gcc if you have gnu ld and the loader will print out # line numbers for undefinded refs. #CC_LD=g++ -static -CC_LD=$(CXX) +CC_LD=$(CXX) $(CXX_DIALECT) # Where is the "include" directory? Traditionally ../include or ./include INCLUDE_DIR = ${srcdir}/../../include diff --git a/gdb/gdbserver/acinclude.m4 b/gdb/gdbserver/acinclude.m4 index 8ec9188..c75d783 100644 --- a/gdb/gdbserver/acinclude.m4 +++ b/gdb/gdbserver/acinclude.m4 @@ -29,6 +29,8 @@ m4_include(../libiberty.m4) dnl For GDB_AC_PTRACE. m4_include(../ptrace.m4) +m4_include(../ax_cxx_compile_stdcxx.m4) + dnl Check for existence of a type $1 in libthread_db.h dnl Based on BFD_HAVE_SYS_PROCFS_TYPE in bfd/bfd.m4. diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac index 6d5907b..11d8c79 100644 --- a/gdb/gdbserver/configure.ac +++ b/gdb/gdbserver/configure.ac @@ -38,6 +38,10 @@ AC_PROG_RANLIB AC_ARG_PROGRAM +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. +AX_CXX_COMPILE_STDCXX(11, , mandatory) + AC_HEADER_STDC # Set the 'development' global. -- 2.5.5 ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] gdb: Require C++11 2016-10-28 9:03 ` Pedro Alves @ 2016-10-28 10:44 ` Philipp Rudo 0 siblings, 0 replies; 22+ messages in thread From: Philipp Rudo @ 2016-10-28 10:44 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches Hi Pedro sorry, my bad. Should have seen its generated code... Without it your patch looks much nicer ;) Phil On Fri, 28 Oct 2016 10:03:13 +0100 Pedro Alves <palves@redhat.com> wrote: > On 10/28/2016 09:47 AM, Philipp Rudo wrote: > > > Without knowing much about autoconf. But you are repeating those > > exact 280 lines a total of 6 times in this patch. Isn't there a > > nicer way? Like moving it to a function? It would make the path > > significantly shorter. > > Oh, you're looking at "configure", but that's a generated file that > autoconf spits out. The source for that repeated code is > ax_cxx_compile_stdcxx.m4 (the file added by patch #1), and that one > does contain a single copy of that code. autoconf decides to > expand the same code more than once because the > ax_cxx_compile_stdcxx.m4 file has support for testing c++14 too, and > that inlines the C++11 standards tests too: > > dnl Test body for checking C++11 support > > m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], > _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 > ) > > > dnl Test body for checking C++14 support > > m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], > _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 > _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 > ) > > Becasily, those AX_CXX_COMPILE_STDCXX_foo calls mean > "inline body of test code" here. So the duplicated > code is already factored out and maintained in a single place. > > (I didn't strip out the support for C++14 from that > script, to minimize changes compared to the upstream > copy.) > > Below's the same patch but without the autogenerated bits. > > From ffb94ceac7fc12d6147bc3280bd8cd7d30dda4e1 Mon Sep 17 00:00:00 2001 > From: Pedro Alves <palves@redhat.com> > Date: Thu, 13 Oct 2016 00:27:45 +0100 > Subject: [PATCH] gdb: Require C++11 > > Use AX_CXX_COMPILE_STDCXX to detect if the compiler supports C++11, > and if -std=xxx switches are necessary to enable C++11. > > We need to tweak AX_CXX_COMPILE_STDCXX a bit though. Pristine > upstream AX_CXX_COMPILE_STDCXX appends -std=gnu++11 to CXX directly. > That doesn't work for us, because the top level Makefile passes CXX > down to subdirs, and that overrides whatever gdb/Makefile may set CXX > to. The result would be that a make invocation from the build/gdb/ > directory would use "g++ -std=gnu++11" as expected, while a make > invocation at the top level would not. > > So instead of having AX_CXX_COMPILE_STDCXX set CXX directly, tweak it > to AC_SUBST a separate variable -- CXX_DIALECT -- and use '$(CXX) > (CXX_DIALECT)' to compile/link. > > Confirmed that this enables C++11 starting with gcc 4.8, the first gcc > release with full C++11 support. > > Also confirmed that configure errors out gracefully with older GCC > releases: > > checking whether /opt/gcc-4.7/bin/g++ supports C++11 features by > default... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 > features with -std=gnu++11... no checking > whether /opt/gcc-4.7/bin/g++ supports C++11 features with > -std=gnu++0x... no checking whether /opt/gcc-4.7/bin/g++ supports > C++11 features with -std=c++11... no checking > whether /opt/gcc-4.7/bin/g++ supports C++11 features with > -std=c++0x... no checking whether /opt/gcc-4.7/bin/g++ supports C++11 > features with +std=c++11... no checking whether /opt/gcc-4.7/bin/g++ > supports C++11 features with -h std=c++11... no configure: error: *** > A compiler with support for C++11 language features is required. > Makefile:9451: recipe for target 'configure-gdb' failed make[1]: *** > [configure-gdb] Error 1 make[1]: Leaving directory > '/home/pedro/brno/pedro/gdb/mygit/cxx-convertion/build-gcc-4.7' > > If we need to revert back to making C++03 optional, all that's > necessary is to change the "mandatory" to "optional" in configure.ac > and regenerate configure (both gdb and gdbserver). > > gdb/ChangeLog: > yyyy-mm-dd Pedro Alves <palves@redhat.com> > > * Makefile.in (CXX_DIALECT): Get from configure. > (COMPILE.pre, CC_LD): Append $(CXX_DIALECT). > (FLAGS_TO_PASS): Pass CXX_DIALECT. > * acinclude.m4: Include ax_cxx_compile_stdcxx.m4. > * ax_cxx_compile_stdcxx.m4: Add FSF copyright header. Set and > AC_SUBST CXX_DIALECT instead of changing CXX/CXXCPP. > * configure.ac: Call AX_CXX_COMPILE_STDCXX. > * config.in: Regenerate. > * configure: Regenerate. > > gdb/gdbserver/ChangeLog: > yyyy-mm-dd Pedro Alves <palves@redhat.com> > > * Makefile.in (CXX_DIALECT): Get from configure. > (COMPILE.pre, CC_LD): Append $(CXX_DIALECT). > * acinclude.m4: Include ../ax_cxx_compile_stdcxx.m4. > * configure.ac: Call AX_CXX_COMPILE_STDCXX. > * config.in: Regenerate. > * configure: Regenerate. > --- > gdb/Makefile.in | 6 +- > gdb/acinclude.m4 | 2 + > gdb/ax_cxx_compile_stdcxx.m4 | 21 +- > gdb/config.in | 3 + > gdb/configure | 981 > ++++++++++++++++++++++++++++++++++++++++++- > gdb/configure.ac | 4 + gdb/gdbserver/Makefile.in | > 5 +- gdb/gdbserver/acinclude.m4 | 2 + > gdb/gdbserver/config.in | 3 + > gdb/gdbserver/configure | 981 > ++++++++++++++++++++++++++++++++++++++++++- > gdb/gdbserver/configure.ac | 4 + 11 files changed, 1998 > insertions(+), 14 deletions(-) > > diff --git a/gdb/Makefile.in b/gdb/Makefile.in > index 2c88434..d035d8e 100644 > --- a/gdb/Makefile.in > +++ b/gdb/Makefile.in > @@ -86,6 +86,7 @@ CATALOGS = @CATALOGS@ > # distribution will fix your include files up. > CC=@CC@ > CXX=@CXX@ > +CXX_DIALECT= @CXX_DIALECT@ > > # Dependency tracking information. > DEPMODE = @CCDEPMODE@ > @@ -94,7 +95,7 @@ depcomp = $(SHELL) $(srcdir)/../depcomp > > # Note that these are overridden by GNU make-specific code below if > # GNU make is used. The overrides implement dependency tracking. > -COMPILE.pre = $(CXX) > +COMPILE.pre = $(CXX) $(CXX_DIALECT) > COMPILE.post = -c -o $@ > COMPILE = $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post) > POSTCOMPILE = @true > @@ -125,7 +126,7 @@ MAKEHTMLFLAGS = > # Set this up with gcc if you have gnu ld and the loader will print > out # line numbers for undefined references. > #CC_LD=g++ -static > -CC_LD=$(CXX) > +CC_LD=$(CXX) $(CXX_DIALECT) > > # Where is our "include" directory? Typically $(srcdir)/../include. > # This is essentially the header file directory for the library > @@ -742,6 +743,7 @@ FLAGS_TO_PASS = \ > "CC=$(CC)" \ > "CFLAGS=$(CFLAGS)" \ > "CXX=$(CXX)" \ > + "CXX_DIALECT=$(CXX_DIALECT)" \ > "CXXFLAGS=$(CXXFLAGS)" \ > "DLLTOOL=$(DLLTOOL)" \ > "LDFLAGS=$(LDFLAGS)" \ > diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 > index 4b3f7fc..daf4a91 100644 > --- a/gdb/acinclude.m4 > +++ b/gdb/acinclude.m4 > @@ -68,6 +68,8 @@ m4_include(libiberty.m4) > dnl For GDB_AC_PTRACE. > m4_include(ptrace.m4) > > +m4_include(ax_cxx_compile_stdcxx.m4) > + > ## ----------------------------------------- ## > ## ANSIfy the C compiler whenever possible. ## > ## From Franc,ois Pinard ## > diff --git a/gdb/ax_cxx_compile_stdcxx.m4 > b/gdb/ax_cxx_compile_stdcxx.m4 index 2c18e49..ffaeb6e 100644 > --- a/gdb/ax_cxx_compile_stdcxx.m4 > +++ b/gdb/ax_cxx_compile_stdcxx.m4 > @@ -1,3 +1,12 @@ > +# Copyright (c) 2016 Free Software Foundation, Inc. > +# > +# Originally based on the AX_CXX_COMPILE_STDCXX macro found at the > url +# below. > +# > +# Local GDB customizations: > +# > +# - AC_SUBST CXX_DIALECT instead of changing CXX/CXXCPP. > +# > # > =========================================================================== > # > http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html > # > =========================================================================== > @@ -58,6 +67,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], > [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid > third argument `$3' to AX_CXX_COMPILE_STDCXX])]) > AC_LANG_PUSH([C++])dnl > + CXX_DIALECT="" > ac_success=no > AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, > ax_cv_cxx_compile_cxx$1, > @@ -81,10 +91,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl > [eval $cachevar=no]) > CXX="$ac_save_CXX"]) > if eval test x\$$cachevar = xyes; then > - CXX="$CXX $switch" > - if test -n "$CXXCPP" ; then > - CXXCPP="$CXXCPP $switch" > - fi > + CXX_DIALECT="$switch" > ac_success=yes > break > fi > @@ -107,10 +114,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl > [eval $cachevar=no]) > CXX="$ac_save_CXX"]) > if eval test x\$$cachevar = xyes; then > - CXX="$CXX $switch" > - if test -n "$CXXCPP" ; then > - CXXCPP="$CXXCPP $switch" > - fi > + CXX_DIALECT="$switch" > ac_success=yes > break > fi > @@ -131,6 +135,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl > [define if the compiler supports basic C++$1 syntax]) > fi > AC_SUBST(HAVE_CXX$1) > + AC_SUBST(CXX_DIALECT) > ]) > > > diff --git a/gdb/configure.ac b/gdb/configure.ac > index e451e60..83c2707 100644 > --- a/gdb/configure.ac > +++ b/gdb/configure.ac > @@ -38,6 +38,10 @@ AC_CONFIG_AUX_DIR(..) > AC_CANONICAL_SYSTEM > AC_ARG_PROGRAM > > +# We require a C++11 compiler. Check if one is available, and if > +# necessary, set CXX_DIALECT to some -std=xxx switch. > +AX_CXX_COMPILE_STDCXX(11, , mandatory) > + > # Dependency checking. > ZW_CREATE_DEPDIR > ZW_PROG_COMPILER_DEPENDENCIES([CC]) > diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in > index 0db5287..5ba559c 100644 > --- a/gdb/gdbserver/Makefile.in > +++ b/gdb/gdbserver/Makefile.in > @@ -51,6 +51,7 @@ RANLIB = @RANLIB@ > > CC = @CC@ > CXX = @CXX@ > +CXX_DIALECT= @CXX_DIALECT@ > AR = @AR@ > AR_FLAGS = rc > > @@ -61,7 +62,7 @@ depcomp = $(SHELL) $(srcdir)/../depcomp > > # Note that these are overridden by GNU make-specific code below if > # GNU make is used. The overrides implement dependency tracking. > -COMPILE.pre = $(CXX) > +COMPILE.pre = $(CXX) $(CXX_DIALECT) > COMPILE.post = -c -o $@ > COMPILE = $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post) > POSTCOMPILE = @true > @@ -80,7 +81,7 @@ VPATH = @srcdir@ > # Set this up with gcc if you have gnu ld and the loader will print > out # line numbers for undefinded refs. > #CC_LD=g++ -static > -CC_LD=$(CXX) > +CC_LD=$(CXX) $(CXX_DIALECT) > > # Where is the "include" directory? Traditionally ../include > or ./include INCLUDE_DIR = ${srcdir}/../../include > diff --git a/gdb/gdbserver/acinclude.m4 b/gdb/gdbserver/acinclude.m4 > index 8ec9188..c75d783 100644 > --- a/gdb/gdbserver/acinclude.m4 > +++ b/gdb/gdbserver/acinclude.m4 > @@ -29,6 +29,8 @@ m4_include(../libiberty.m4) > dnl For GDB_AC_PTRACE. > m4_include(../ptrace.m4) > > +m4_include(../ax_cxx_compile_stdcxx.m4) > + > dnl Check for existence of a type $1 in libthread_db.h > dnl Based on BFD_HAVE_SYS_PROCFS_TYPE in bfd/bfd.m4. > > diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac > index 6d5907b..11d8c79 100644 > --- a/gdb/gdbserver/configure.ac > +++ b/gdb/gdbserver/configure.ac > @@ -38,6 +38,10 @@ AC_PROG_RANLIB > > AC_ARG_PROGRAM > > +# We require a C++11 compiler. Check if one is available, and if > +# necessary, set CXX_DIALECT to some -std=xxx switch. > +AX_CXX_COMPILE_STDCXX(11, , mandatory) > + > AC_HEADER_STDC > > # Set the 'development' global. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] gdb: Require C++11 2016-10-27 19:21 ` [PATCH 2/2] gdb: Require C++11 Pedro Alves [not found] ` <20161028104718.540c10ed@ThinkPad> @ 2016-11-03 15:39 ` Yao Qi 2016-11-03 15:58 ` Pedro Alves 1 sibling, 1 reply; 22+ messages in thread From: Yao Qi @ 2016-11-03 15:39 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches Pedro Alves <palves@redhat.com> writes: Hi Pedro, > to. The result would be that a make invocation from the build/gdb/ > directory would use "g++ -std=gnu++11" as expected, while a make > invocation at the top level would not. This happens to break the build if bison is not new enough (bison 2.6.4), See details in the patch below, -- Yao (齐尧) From 9a1e3fb73cc1003eef75b895c6035857494f8ee8 Mon Sep 17 00:00:00 2001 From: Yao Qi <yao.qi@linaro.org> Date: Thu, 3 Nov 2016 15:33:13 +0000 Subject: [PATCH] Replace YY_NULL with YY_NULLPTR in LANG-exp.c As we require c++11, GDB fails to build if bison is not new enough. I see the following error on the system (fedora 19) that bison is 2.6.4, g++ -std=gnu++11 .... \ -c -o ada-exp.o -MT ada-exp.o -MMD -MP -MF .deps/ada-exp.Tpo 'if test -f ada-exp.c; then echo ada-exp.c; else echo ../../binutils-gdb/gdb/ada-exp.c; fi` In file included from ../../binutils-gdb/gdb/ada-exp.y:731:0: ada-lex.c:113:0: error: "YY_NULL" redefined [-Werror] #define YY_NULL 0 ^ ada-exp.c:158:0: note: this is the location of the previous definition # define YY_NULL nullptr ^ cc1plus: all warnings being treated as errors make: *** [ada-exp.o] Error 1 Both ada-exp.c and ada-lex.c has macro YY_NULL, like this, $ cat 1.c # ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULL nullptr # else # define YY_NULL 0 # endif # endif #define YY_NULL 0 as we can see, YY_NULL is defined differently (nullptr vs 0) $ g++ -std=c++11 -Wall 1.c -c 1.c:9:0: warning: "YY_NULL" redefined #define YY_NULL 0 ^ 1.c:3:0: note: this is the location of the previous definition # define YY_NULL nullptr ^ $ g++ -Wall 1.c -c bison renames YY_NULL to YY_NULLPTR in 2013 Nov, https://lists.gnu.org/archive/html/bison-patches/2013-11/msg00002.html and bison released later than 2013 Nov have this patch. Bison 3.0.2, released on 2013 Dec, is OK. The fix is to replace YY_NULL with YY_NULLPTR via sed. With old bison, YY_NULL becomes YY_NULLPTR; with new bison, YY_NULLPTR becomes YY_NULLPTRPTR, gdb: 2016-11-03 Yao Qi <yao.qi@linaro.org> * Makefile.in (.y.c): Replace YY_NULL with YY_NULLPTR. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index d035d8e..6db63c7 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1894,6 +1894,7 @@ po/$(PACKAGE).pot: force -e 's/\([ \t;,(]\)free\([ \t]*[&(),]\)/\1xfree\2/g' \ -e 's/\([ \t;,(]\)free$$/\1xfree/g' \ -e '/^#line.*y.tab.c/d' \ + -e 's/YY_NULL/YY_NULLPTR/g' \ < $@.tmp > $@ rm -f $@.tmp .l.c: ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] gdb: Require C++11 2016-11-03 15:39 ` Yao Qi @ 2016-11-03 15:58 ` Pedro Alves 2016-11-03 16:11 ` Yao Qi 0 siblings, 1 reply; 22+ messages in thread From: Pedro Alves @ 2016-11-03 15:58 UTC (permalink / raw) To: Yao Qi; +Cc: gdb-patches Hi Yao, > gdb: > > 2016-11-03 Yao Qi <yao.qi@linaro.org> > > * Makefile.in (.y.c): Replace YY_NULL with YY_NULLPTR. LGTM. Thanks for fixing this. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] gdb: Require C++11 2016-11-03 15:58 ` Pedro Alves @ 2016-11-03 16:11 ` Yao Qi 0 siblings, 0 replies; 22+ messages in thread From: Yao Qi @ 2016-11-03 16:11 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On Thu, Nov 3, 2016 at 3:58 PM, Pedro Alves <palves@redhat.com> wrote: > Hi Yao, > >> gdb: >> >> 2016-11-03 Yao Qi <yao.qi@linaro.org> >> >> * Makefile.in (.y.c): Replace YY_NULL with YY_NULLPTR. > > LGTM. Thanks for fixing this. > Patch is pushed in. -- Yao (齐尧) ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/2] gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive 2016-10-27 19:21 [PATCH 0/2] gdb: Require a C++11 compiler Pedro Alves 2016-10-27 19:21 ` [PATCH 2/2] gdb: Require C++11 Pedro Alves @ 2016-10-27 19:21 ` Pedro Alves 2016-10-28 12:07 ` [PATCH 0/2] gdb: Require a C++11 compiler Yao Qi 2016-11-01 11:00 ` [PATCH 0/2] gdb: Require a C++11 compiler Richard Earnshaw (lists) 3 siblings, 0 replies; 22+ messages in thread From: Pedro Alves @ 2016-10-27 19:21 UTC (permalink / raw) To: gdb-patches This macro throws C++11 code at the compiler in order to check whether it supports C++11. final/override, rvalue references, static_assert, decltype, auto, constexpr, etc., and adds -std=gnu++11 to CXX if necessary. Nothing uses the macro yet. Simply adding it as separate preliminary step because we'll need local changes. gdb/ChangeLog yyyy-mm-dd Pedro Alves <palves@redhat.com> * ax_cxx_compile_stdcxx.m4: New file. --- gdb/ax_cxx_compile_stdcxx.m4 | 562 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 562 insertions(+) create mode 100644 gdb/ax_cxx_compile_stdcxx.m4 diff --git a/gdb/ax_cxx_compile_stdcxx.m4 b/gdb/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 0000000..2c18e49 --- /dev/null +++ b/gdb/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,562 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second 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. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> +# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> +# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> +# Copyright (c) 2015 Paul Norman <penorman@mac.com> +# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> +# +# 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 4 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same<int, decltype(f(x))>::value, ""); + static_assert(is_same<int&, decltype(g(x))>::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) -- 2.5.5 ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-10-27 19:21 [PATCH 0/2] gdb: Require a C++11 compiler Pedro Alves 2016-10-27 19:21 ` [PATCH 2/2] gdb: Require C++11 Pedro Alves 2016-10-27 19:21 ` [PATCH 1/2] gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive Pedro Alves @ 2016-10-28 12:07 ` Yao Qi 2016-10-28 15:08 ` Pedro Alves 2016-11-01 11:00 ` [PATCH 0/2] gdb: Require a C++11 compiler Richard Earnshaw (lists) 3 siblings, 1 reply; 22+ messages in thread From: Yao Qi @ 2016-10-28 12:07 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On Thu, Oct 27, 2016 at 8:21 PM, Pedro Alves <palves@redhat.com> wrote: > As previously discussed, this patch set makes GDB require a C++11 > compiler. > > You'll find the previous discussions referenced here: > https://sourceware.org/ml/gdb-patches/2016-10/msg00607.html > > This is basically the same as I had sent here: > https://sourceware.org/ml/gdb-patches/2016-10/msg00336.html > > The only difference is a single-line change that makes C++11 a > mandatory instead of enabling it iff supported. > This series is good to me. -- Yao (齐尧) ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-10-28 12:07 ` [PATCH 0/2] gdb: Require a C++11 compiler Yao Qi @ 2016-10-28 15:08 ` Pedro Alves 2016-10-28 17:17 ` [PATCH] gdb/NEWS: Mention C++11 requirement Pedro Alves 0 siblings, 1 reply; 22+ messages in thread From: Pedro Alves @ 2016-10-28 15:08 UTC (permalink / raw) To: Yao Qi; +Cc: gdb-patches On 10/28/2016 01:07 PM, Yao Qi wrote: > On Thu, Oct 27, 2016 at 8:21 PM, Pedro Alves <palves@redhat.com> wrote: >> As previously discussed, this patch set makes GDB require a C++11 >> compiler. >> >> You'll find the previous discussions referenced here: >> https://sourceware.org/ml/gdb-patches/2016-10/msg00607.html >> >> This is basically the same as I had sent here: >> https://sourceware.org/ml/gdb-patches/2016-10/msg00336.html >> >> The only difference is a single-line change that makes C++11 a >> mandatory instead of enabling it iff supported. >> > > This series is good to me. Thanks! I've pushed it in now. I'll send a NEWS change soon. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] gdb/NEWS: Mention C++11 requirement 2016-10-28 15:08 ` Pedro Alves @ 2016-10-28 17:17 ` Pedro Alves 2016-10-29 6:13 ` Eli Zaretskii 0 siblings, 1 reply; 22+ messages in thread From: Pedro Alves @ 2016-10-28 17:17 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gdb-patches On 10/28/2016 04:08 PM, Pedro Alves wrote: > On 10/28/2016 01:07 PM, Yao Qi wrote: >> This series is good to me. > > Thanks! I've pushed it in now. I'll send a NEWS change soon. Maybe this is sufficient? From 858a5212f0c3dee3fa369aa67d0d650a761343c2 Mon Sep 17 00:00:00 2001 From: Pedro Alves <palves@redhat.com> Date: Fri, 28 Oct 2016 18:10:35 +0100 Subject: [PATCH] gdb/NEWS: Mention C++11 requirement gdb/ChangeLog: 2016-10-28 Pedro Alves <palves@redhat.com> * NEWS: Adjust to mention C++11 requirement. --- gdb/NEWS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gdb/NEWS b/gdb/NEWS index 4a61438..5ccb74c 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,7 +3,9 @@ *** Changes since GDB 7.12 -* GDB and GDBserver now require building with a C++ compiler. +* GDB and GDBserver now require building with a C++11 compiler. + + For example, GCC 4.8 or later. It is no longer possible to build GDB or GDBserver with a C compiler. The --disable-build-with-cxx configure option has been -- 2.5.5 ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] gdb/NEWS: Mention C++11 requirement 2016-10-28 17:17 ` [PATCH] gdb/NEWS: Mention C++11 requirement Pedro Alves @ 2016-10-29 6:13 ` Eli Zaretskii 2016-10-29 15:18 ` Pedro Alves 0 siblings, 1 reply; 22+ messages in thread From: Eli Zaretskii @ 2016-10-29 6:13 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches > Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org> > From: Pedro Alves <palves@redhat.com> > Date: Fri, 28 Oct 2016 18:17:44 +0100 > > On 10/28/2016 04:08 PM, Pedro Alves wrote: > > On 10/28/2016 01:07 PM, Yao Qi wrote: > > >> This series is good to me. > > > > Thanks! I've pushed it in now. I'll send a NEWS change soon. > > Maybe this is sufficient? Fine with me. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] gdb/NEWS: Mention C++11 requirement 2016-10-29 6:13 ` Eli Zaretskii @ 2016-10-29 15:18 ` Pedro Alves 2016-10-29 15:29 ` Eli Zaretskii 0 siblings, 1 reply; 22+ messages in thread From: Pedro Alves @ 2016-10-29 15:18 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gdb-patches On 10/29/2016 07:13 AM, Eli Zaretskii wrote: >> Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org> >> From: Pedro Alves <palves@redhat.com> >> Date: Fri, 28 Oct 2016 18:17:44 +0100 >> >> On 10/28/2016 04:08 PM, Pedro Alves wrote: >>> On 10/28/2016 01:07 PM, Yao Qi wrote: >> >>>> This series is good to me. >>> >>> Thanks! I've pushed it in now. I'll send a NEWS change soon. >> >> Maybe this is sufficient? > > Fine with me. > Thanks I've pushed it in. Reading the text back, I wonder if this would sound clearer/more natural: -* GDB and GDBserver now require building with a C++11 compiler. +* Building GDB and GDBserver now requires a C++11 compiler. I realized that what I had written originally may be ambiguous with saying that we require building inferiors/debuggees with C++11. Reading the paragraph below clears it up, but ... Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] gdb/NEWS: Mention C++11 requirement 2016-10-29 15:18 ` Pedro Alves @ 2016-10-29 15:29 ` Eli Zaretskii 2016-10-29 15:35 ` Pedro Alves 0 siblings, 1 reply; 22+ messages in thread From: Eli Zaretskii @ 2016-10-29 15:29 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches > Cc: gdb-patches@sourceware.org > From: Pedro Alves <palves@redhat.com> > Date: Sat, 29 Oct 2016 16:18:50 +0100 > > Reading the text back, I wonder if this would sound > clearer/more natural: > > -* GDB and GDBserver now require building with a C++11 compiler. > +* Building GDB and GDBserver now requires a C++11 compiler. The latter is better, indeed. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] gdb/NEWS: Mention C++11 requirement 2016-10-29 15:29 ` Eli Zaretskii @ 2016-10-29 15:35 ` Pedro Alves 0 siblings, 0 replies; 22+ messages in thread From: Pedro Alves @ 2016-10-29 15:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gdb-patches On 10/29/2016 04:29 PM, Eli Zaretskii wrote: >> Cc: gdb-patches@sourceware.org >> From: Pedro Alves <palves@redhat.com> >> Date: Sat, 29 Oct 2016 16:18:50 +0100 >> >> Reading the text back, I wonder if this would sound >> clearer/more natural: >> >> -* GDB and GDBserver now require building with a C++11 compiler. >> +* Building GDB and GDBserver now requires a C++11 compiler. > > The latter is better, indeed. > Alright, pushed this in then. From e6485aafde098bf182b46cb187d8fd049f309e29 Mon Sep 17 00:00:00 2001 From: Pedro Alves <palves@redhat.com> Date: Sat, 29 Oct 2016 16:30:34 +0100 Subject: [PATCH] gdb/NEWS: Clarify C++ requirement gdb/ChangeLog: 2016-10-29 Pedro Alves <palves@redhat.com> * NEWS: Clarify C++ requirement. --- gdb/ChangeLog | 4 ++++ gdb/NEWS | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b4a6e23..c38c65c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,9 @@ 2016-10-29 Pedro Alves <palves@redhat.com> + * NEWS: Clarify C++ requirement. + +2016-10-29 Pedro Alves <palves@redhat.com> + * NEWS: Adjust to mention C++11 requirement. 2016-10-29 Eli Zaretskii <eliz@gnu.org> diff --git a/gdb/NEWS b/gdb/NEWS index afb817f..a6b1282 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,7 +3,7 @@ *** Changes since GDB 7.12 -* GDB and GDBserver now require building with a C++11 compiler. +* Building GDB and GDBserver now requires a C++11 compiler. For example, GCC 4.8 or later. -- 2.5.5 ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-10-27 19:21 [PATCH 0/2] gdb: Require a C++11 compiler Pedro Alves ` (2 preceding siblings ...) 2016-10-28 12:07 ` [PATCH 0/2] gdb: Require a C++11 compiler Yao Qi @ 2016-11-01 11:00 ` Richard Earnshaw (lists) 2016-11-01 16:53 ` Pedro Alves 3 siblings, 1 reply; 22+ messages in thread From: Richard Earnshaw (lists) @ 2016-11-01 11:00 UTC (permalink / raw) To: Pedro Alves, gdb-patches On 27/10/16 20:21, Pedro Alves wrote: > As previously discussed, this patch set makes GDB require a C++11 > compiler. > > You'll find the previous discussions referenced here: > https://sourceware.org/ml/gdb-patches/2016-10/msg00607.html > > This is basically the same as I had sent here: > https://sourceware.org/ml/gdb-patches/2016-10/msg00336.html > > The only difference is a single-line change that makes C++11 a > mandatory instead of enabling it iff supported. > > Pedro Alves (2): > gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive > gdb: Require C++11 > > gdb/Makefile.in | 6 +- > gdb/acinclude.m4 | 2 + > gdb/ax_cxx_compile_stdcxx.m4 | 567 +++++++++++++++++++++++++ > gdb/config.in | 3 + > gdb/configure | 981 ++++++++++++++++++++++++++++++++++++++++++- > gdb/configure.ac | 4 + > gdb/gdbserver/Makefile.in | 5 +- > gdb/gdbserver/acinclude.m4 | 2 + > gdb/gdbserver/config.in | 3 + > gdb/gdbserver/configure | 981 ++++++++++++++++++++++++++++++++++++++++++- > gdb/gdbserver/configure.ac | 4 + > 11 files changed, 2552 insertions(+), 6 deletions(-) > create mode 100644 gdb/ax_cxx_compile_stdcxx.m4 > Sorry, I have to say I think this is too soon (having just found out the hard way) :-( ). Half of the machines I use are still running RHE5 and this change means I can no-longer use the system compiler for building GDB. A change that requires use of a non-standard compiler significantly complicates the process of building (and worse, productizing) GDB builds as now you have to mess with either forcing static linking or worse, forcing uses to mess with non-standard LD_LIBRARY paths at run time. R. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-11-01 11:00 ` [PATCH 0/2] gdb: Require a C++11 compiler Richard Earnshaw (lists) @ 2016-11-01 16:53 ` Pedro Alves 2016-11-02 14:51 ` Richard Earnshaw (lists) 2016-11-04 13:31 ` Maciej W. Rozycki 0 siblings, 2 replies; 22+ messages in thread From: Pedro Alves @ 2016-11-01 16:53 UTC (permalink / raw) To: Richard Earnshaw (lists), gdb-patches Hi Richard, On 11/01/2016 11:00 AM, Richard Earnshaw (lists) wrote: > Sorry, I have to say I think this is too soon (having just found out the > hard way) :-( ). Sorry for causing you trouble. :-( > Half of the machines I use are still running RHE5 and this change means > I can no-longer use the system compiler for building GDB. A change that > requires use of a non-standard compiler significantly complicates the > process of building (and worse, productizing) GDB builds as now you have Fortunately, there are gcc 4.8 packages for RHEL5 in DTS2: https://www.redhat.com/en/about/press-releases/red-hat-releases-red-hat-developer-toolset-2-0-with-update-to-gcc http://developers.redhat.com/blog/2013/09/12/rh-dts2-ga/ Hopefully the number of users that want new gdb but can't install that will be limited. > to mess with either forcing static linking or worse, forcing uses to > mess with non-standard LD_LIBRARY paths at run time. Note that just like gcc, gdb builds with -static-libstdc++ -static-libgcc. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-11-01 16:53 ` Pedro Alves @ 2016-11-02 14:51 ` Richard Earnshaw (lists) 2016-11-02 15:58 ` Pedro Alves 2016-11-04 13:31 ` Maciej W. Rozycki 1 sibling, 1 reply; 22+ messages in thread From: Richard Earnshaw (lists) @ 2016-11-02 14:51 UTC (permalink / raw) To: Pedro Alves, gdb-patches On 01/11/16 16:53, Pedro Alves wrote: > Hi Richard, > > On 11/01/2016 11:00 AM, Richard Earnshaw (lists) wrote: > >> Sorry, I have to say I think this is too soon (having just found out the >> hard way) :-( ). > > Sorry for causing you trouble. :-( > >> Half of the machines I use are still running RHE5 and this change means >> I can no-longer use the system compiler for building GDB. A change that >> requires use of a non-standard compiler significantly complicates the >> process of building (and worse, productizing) GDB builds as now you have > > Fortunately, there are gcc 4.8 packages for RHEL5 in DTS2: > Which are not installed on any of our machines and, frankly, I wouldn't want to take a wager on persuading our IT admins to do that. :-( It's certainly unlikely to happen in short order. It turns out that gcc on RHEL6 isn't new enough either. So now its all the machines I have access to, not just some of them. > https://www.redhat.com/en/about/press-releases/red-hat-releases-red-hat-developer-toolset-2-0-with-update-to-gcc > http://developers.redhat.com/blog/2013/09/12/rh-dts2-ga/ > > Hopefully the number of users that want new gdb but can't install that > will be limited. > >> to mess with either forcing static linking or worse, forcing uses to >> mess with non-standard LD_LIBRARY paths at run time. > > Note that just like gcc, gdb builds with -static-libstdc++ -static-libgcc. > That would help, if I could find a usable compiler... R. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-11-02 14:51 ` Richard Earnshaw (lists) @ 2016-11-02 15:58 ` Pedro Alves 0 siblings, 0 replies; 22+ messages in thread From: Pedro Alves @ 2016-11-02 15:58 UTC (permalink / raw) To: Richard Earnshaw (lists), gdb-patches On 11/02/2016 02:51 PM, Richard Earnshaw (lists) wrote: > On 01/11/16 16:53, Pedro Alves wrote: >> Hi Richard, >> >> On 11/01/2016 11:00 AM, Richard Earnshaw (lists) wrote: >> >>> Sorry, I have to say I think this is too soon (having just found out the >>> hard way) :-( ). >> >> Sorry for causing you trouble. :-( >> >>> Half of the machines I use are still running RHE5 and this change means >>> I can no-longer use the system compiler for building GDB. A change that >>> requires use of a non-standard compiler significantly complicates the >>> process of building (and worse, productizing) GDB builds as now you have >> >> Fortunately, there are gcc 4.8 packages for RHEL5 in DTS2: >> > > Which are not installed on any of our machines and, frankly, I wouldn't > want to take a wager on persuading our IT admins to do that. :-( It's > certainly unlikely to happen in short order. I don't want to sound presumptuous, but I can't imagine why they'd refuse to install a RH-validated package on a RH system, package which was made exactly for purposes like the one at hand. C++11 is only becoming more common and a dependency of many upstream projects. clang/llvm just recently started requiring gcc 4.8 too (for full C++11 support), for example. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-11-01 16:53 ` Pedro Alves 2016-11-02 14:51 ` Richard Earnshaw (lists) @ 2016-11-04 13:31 ` Maciej W. Rozycki 2016-11-04 14:46 ` Pedro Alves 1 sibling, 1 reply; 22+ messages in thread From: Maciej W. Rozycki @ 2016-11-04 13:31 UTC (permalink / raw) To: Pedro Alves; +Cc: Richard Earnshaw (lists), gdb-patches On Tue, 1 Nov 2016, Pedro Alves wrote: > > to mess with either forcing static linking or worse, forcing uses to > > mess with non-standard LD_LIBRARY paths at run time. > > Note that just like gcc, gdb builds with -static-libstdc++ -static-libgcc. Are you sure? All my recent cross-built `gdbserver' executables failed to run without a pain of getting `libstdc++.so' in the right place on the target. Or do you mean GDB proper only? I didn't even realise there was intention to use static `libstdc++' and/or `libgcc' libraries. Also I've not been particularly happy with the project moving over to C++ let alone C++11, however I have just decided I couldn't afford the effort to go through all the discussion, which always takes time pinched from other commitments. Being a CPU target maintainer only and with my rusty 1995-vintage C++ programming skills -- making it difficult to me to assess what the advantages of modern C++ dialects might be -- I didn't want to stand in the way of core developers if they think a move to C++ will make their job easier, improving code quality and reducing maintenance burden. FWIW, Maciej ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] gdb: Require a C++11 compiler 2016-11-04 13:31 ` Maciej W. Rozycki @ 2016-11-04 14:46 ` Pedro Alves 0 siblings, 0 replies; 22+ messages in thread From: Pedro Alves @ 2016-11-04 14:46 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: Richard Earnshaw (lists), gdb-patches On 11/04/2016 01:31 PM, Maciej W. Rozycki wrote: > On Tue, 1 Nov 2016, Pedro Alves wrote: > >>> to mess with either forcing static linking or worse, forcing uses to >>> mess with non-standard LD_LIBRARY paths at run time. >> >> Note that just like gcc, gdb builds with -static-libstdc++ -static-libgcc. > > Are you sure? All my recent cross-built `gdbserver' executables failed > to run without a pain of getting `libstdc++.so' in the right place on the > target. Or do you mean GDB proper only? I didn't even realise there was > intention to use static `libstdc++' and/or `libgcc' libraries. Hmm. I do see it on my builds. $ rm gdbserver && make gdbserver 2>&1 | grep static ... -Wformat-nonliteral -Werror -DGDBSERVER -static-libstdc++ -static-libgcc ... I guess the the difference is that I'm looking at a native build, which means that gdb/gdbserver/configure is run as a subdir of the gdb configure which in turn is a subdir of the top level configure. It's the top level configure that adds the -static-*: ... # Check whether -static-libstdc++ -static-libgcc is supported. ... But if you cross-build gdbserver, you'll be running gdbserver's configure directly, bypassing the top level, and thus miss that. Maybe we should move that bit of configure code to an .m4 file under src/config/, and then the different subdirs could include use of it as they saw fit. Maybe even make it optional under a configure --whatever option. Maybe distros would prefer disabling that. (Or make gdbserver be the toplevel subdir, but even though desirable, that's obviously a much larger change...) > Also I've not been particularly happy with the project moving over to C++ > let alone C++11, however I have just decided I couldn't afford the effort > to go through all the discussion, which always takes time pinched from > other commitments. Being a CPU target maintainer only and with my rusty > 1995-vintage C++ programming skills -- making it difficult to me to assess > what the advantages of modern C++ dialects might be -- I didn't want to > stand in the way of core developers if they think a move to C++ will make > their job easier, improving code quality and reducing maintenance burden. > Thanks for understanding. Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] Enable C++11 starting with gcc 4.8 (was: Re: [PATCH 1/3] Introduce gdb::unique_ptr) @ 2016-10-13 0:38 Pedro Alves 2016-10-13 0:45 ` [PATCH 1/2] gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive Pedro Alves 0 siblings, 1 reply; 22+ messages in thread From: Pedro Alves @ 2016-10-13 0:38 UTC (permalink / raw) To: Metzger, Markus T, Eli Zaretskii Cc: brobecker, gdb-patches, Jan Kratochvil (jan.kratochvil@redhat.com), Simon Marchi On 10/12/2016 11:28 AM, Pedro Alves wrote: > On 10/12/2016 09:11 AM, Metzger, Markus T wrote: > >> A simple and pragmatic solution would be a patch to add -std=c++11 >> to GDB's compiler options. Pedro already mentioned it but I'm afraid it >> got lost. > > Looks like it, yes. As I've explained, we can't do it on src/gdb/ > alone, because the CXX make variable is passed down from the top level, > which would override whatever we set in gdb/'s configure/Makefile. > > I want to give it a try, though. It just requires time and getting > the patch into gcc and merged back. I don't think that should hold > back the proposed series (or pieces of it). > > I wasn't originally meaning to unconditionally add -std=c++11 though, > but instead to only add it if the compiler supports it, in order > to conservatively still support C++03-only compilers. OK, I spend a few hours tonight working on this. I was thinking ahead that we'll like have other C++ libraries in the top level that we'd be using (code shared with gcc, and also gdbserver moving to top level, maybe parts split to libraries, etc.). And I was mistakenly under the impression that all subdirs would have to be built with the same C++ dialect, given the C++11 ABI change. I.e., use the same dialect throughout to avoid ABI conflicts. So I first wrote a patch that had the top level configure source a file in each subdir that would tell the top level the minimum and maximum C++ dialect versions each subdir supported, and then the top level could compute the dialect to set CXX to. But, https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html explains how mixing dialects is not really a problem. So I was over complicating. However, the issue with CXX being passed by the top level overriding whatever gdb's configure/Makefile decide to set CXX to is real though. But I solved it in a different way, all within gdb/ Instead of having configure append -std=xxx to CXX, simply set a separate CXX_DIALECT variable, and tweak the Makefile to use "$CXX CXX_DIALECT" to compile/link. In order to detect whether the compiler supports C++11 (i.e., if we're using gcc 4.8 or later, or a clang that supports C++11, etc.), I'm reusing a macro from the GNU Autoconf Archive, at: http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html To recap: > Conceptually, the gdb::unique_ptr patch (this thread) does: > > #if HAVE_STD_UNIQUE_PTR > > // just use it > > #else > > // write replacement > > #endif > > The replacement is fully functional. > > If I push the patch in now, HAVE_STD_UNIQUE_PTR will only be true > when compiling GDB with GCC >= 6.x, because G++ 6.1 targets G++14 > by default, which is a superset of C++11. The replacement > works with all other GCCs. It'd be possible to make > HAVE_STD_UNIQUE_PTR be true with GCC >= 4.x too, but nobody wrote > that patch yet. So I wrote that patch now. IOW, the idea is that gdb::unique_ptr maps to C++11 std::unique_ptr iff C++11 is available and to a replacement otherwise. The C++03 replacement works just as well, however the C++11 version catches more bugs at compile time. Full C++11 support is available starting with gcc 4.8, however only gcc 6.1 switched to default to C++11 (C++14, actually). So for gcc 4.8 till gcc 6.1, we need to explicitly pass -std=gnu++11 to the compiler. That's what the patch I wrote tonight does. I'll send it as reply to this email. Two patches actually. > But if we agree to go full-on C++11, then I'll be more than > happy to make gdb's configure error out on non-C++11 compilers. The patches add this to configure: AX_CXX_COMPILE_STDCXX(11, , optional) "optional" means that not having a C++11 compiler is OK. IOW, "try to enable C++11 iff possible". If we decide to _require_ C++11 (i.e., drop support for C++03-only), then it's a simple matter of changing that to: AX_CXX_COMPILE_STDCXX(11, , mandatory) Thanks, Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/2] gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive 2016-10-13 0:38 [PATCH] Enable C++11 starting with gcc 4.8 (was: Re: [PATCH 1/3] Introduce gdb::unique_ptr) Pedro Alves @ 2016-10-13 0:45 ` Pedro Alves 0 siblings, 0 replies; 22+ messages in thread From: Pedro Alves @ 2016-10-13 0:45 UTC (permalink / raw) To: gdb-patches This macro throws C++11 code at the compiler in order to check whether it supports C++11. final/override, rvalue references, static_assert, decltype, auto, constexpr, etc., and adds -std=gnu++11 to CXX if necessary. Nothing uses the macro yet. Simply adding it as separate preliminary step because we'll need local changes. gdb/ChangeLog yyyy-mm-dd Pedro Alves <palves@redhat.com> * ax_cxx_compile_stdcxx.m4: New file. --- gdb/ax_cxx_compile_stdcxx.m4 | 562 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 562 insertions(+) create mode 100644 gdb/ax_cxx_compile_stdcxx.m4 diff --git a/gdb/ax_cxx_compile_stdcxx.m4 b/gdb/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 0000000..2c18e49 --- /dev/null +++ b/gdb/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,562 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second 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. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> +# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> +# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> +# Copyright (c) 2015 Paul Norman <penorman@mac.com> +# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> +# +# 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 4 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same<int, decltype(f(x))>::value, ""); + static_assert(is_same<int&, decltype(g(x))>::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) -- 2.5.5 ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2016-11-04 14:46 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-27 19:21 [PATCH 0/2] gdb: Require a C++11 compiler Pedro Alves
2016-10-27 19:21 ` [PATCH 2/2] gdb: Require C++11 Pedro Alves
[not found] ` <20161028104718.540c10ed@ThinkPad>
2016-10-28 9:03 ` Pedro Alves
2016-10-28 10:44 ` Philipp Rudo
2016-11-03 15:39 ` Yao Qi
2016-11-03 15:58 ` Pedro Alves
2016-11-03 16:11 ` Yao Qi
2016-10-27 19:21 ` [PATCH 1/2] gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive Pedro Alves
2016-10-28 12:07 ` [PATCH 0/2] gdb: Require a C++11 compiler Yao Qi
2016-10-28 15:08 ` Pedro Alves
2016-10-28 17:17 ` [PATCH] gdb/NEWS: Mention C++11 requirement Pedro Alves
2016-10-29 6:13 ` Eli Zaretskii
2016-10-29 15:18 ` Pedro Alves
2016-10-29 15:29 ` Eli Zaretskii
2016-10-29 15:35 ` Pedro Alves
2016-11-01 11:00 ` [PATCH 0/2] gdb: Require a C++11 compiler Richard Earnshaw (lists)
2016-11-01 16:53 ` Pedro Alves
2016-11-02 14:51 ` Richard Earnshaw (lists)
2016-11-02 15:58 ` Pedro Alves
2016-11-04 13:31 ` Maciej W. Rozycki
2016-11-04 14:46 ` Pedro Alves
-- strict thread matches above, loose matches on Subject: below --
2016-10-13 0:38 [PATCH] Enable C++11 starting with gcc 4.8 (was: Re: [PATCH 1/3] Introduce gdb::unique_ptr) Pedro Alves
2016-10-13 0:45 ` [PATCH 1/2] gdb: Import AX_CXX_COMPILE_STDCXX from the GNU Autoconf Archive Pedro Alves
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox