bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

build: strengthen the C++ standard flag test


From: Akim Demaille
Subject: build: strengthen the C++ standard flag test
Date: Mon, 17 Sep 2018 18:45:07 +0200

This is mostly a stub, it will require some improvements,
no doubts about it.

It’s based on work I did on vcsn.

commit c193a4c3291e95fd92d0274ef9e263772ffed2ae
Author: Akim Demaille <address@hidden>
Date:   Sun Sep 16 18:20:56 2018 +0200

    build: strengthen the C++ standard flag test
    
    On the CI, we have this spurious failure with clang 3.9 with
    -std=c++17:
    
        In file included from list.y:23:
        In file included from /usr/include/c++/4.8/iostream:39:
        In file included from /usr/include/c++/4.8/ostream:38:
        In file included from /usr/include/c++/4.8/ios:42:
        In file included from /usr/include/c++/4.8/bits/ios_base.h:41:
        In file included from /usr/include/c++/4.8/bits/locale_classes.h:40:
        In file included from /usr/include/c++/4.8/string:52:
        In file included from /usr/include/c++/4.8/bits/basic_string.h:2815:
        In file included from /usr/include/c++/4.8/ext/string_conversions.h:43:
        /usr/include/c++/4.8/cstdio:120:11: error: no member named 'gets' in 
the global namespace
          using ::gets;
                ~~^
    
    This shows that our test, based on gl_WARN_ADD, is a joke.  We have to
    really check for at least a bit of C++.
    
    * m4/ax_check_compile_flag.m4, m4/bison-cxx-std.m4: New.
    * configure.ac: Use them to make sure the compiler actually works.

diff --git a/configure.ac b/configure.ac
index f8faa2b7..a1c52b6d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,8 @@
 # better to avoid a typo in the 'configure --help' entry for the YACC
 # environment variable.
 AC_PREREQ([2.68])
-m4_pattern_forbid([^gl_[A-Z]])
+m4_pattern_forbid([^_?(gl_[A-Z]|BISON_)])
+m4_pattern_allow([^BISON_USE_NLS$])
 
 AC_INIT([GNU Bison],
         m4_esyscmd([build-aux/git-version-gen .tarball-version]),
@@ -52,18 +53,6 @@ AC_CONFIG_HEADERS([lib/config.h:lib/config.in.h])
 # Checks for the compiler.
 AC_PROG_CC_STDC
 AC_PROG_CXX
-AC_LANG_PUSH([C++])
-gl_WARN_ADD([-fno-exceptions], [NO_EXCEPTIONS_CXXFLAGS])
-gl_WARN_ADD([-std=c++98], [CXX98_CXXFLAGS])
-gl_WARN_ADD([-std=c++03], [CXX03_CXXFLAGS])
-gl_WARN_ADD([-std=c++11], [CXX11_CXXFLAGS])
-gl_WARN_ADD([-std=c++14], [CXX14_CXXFLAGS])
-gl_WARN_ADD([-std=c++17], [CXX17_CXXFLAGS])
-gl_WARN_ADD([-std=c++2a], [CXX2A_CXXFLAGS])
-AC_SUBST([STDCXX_FLAGS],
-["$CXX98_CXXFLAGS $CXX03_CXXFLAGS $CXX11_CXXFLAGS $CXX14_CXXFLAGS 
$CXX17_CXXFLAGS $CXX2A_CXXFLAGS "])
-AM_CONDITIONAL([ENABLE_CXX11], [test x"$CXX11_CXXFLAGS" != x])
-AC_LANG_POP([C++])
 
 # Gnulib (early checks).
 gl_EARLY
@@ -82,6 +71,19 @@ AC_CACHE_CHECK([whether pragma GCC diagnostic push works],
   [lv_cv_gcc_pragma_push_works=no])
   CFLAGS=$save_CFLAGS])
 
+AC_LANG_PUSH([C++])
+gl_WARN_ADD([-fno-exceptions], [NO_EXCEPTIONS_CXXFLAGS])
+gl_WARN_ADD([-std=c++98], [CXX98_CXXFLAGS])
+gl_WARN_ADD([-std=c++03], [CXX03_CXXFLAGS])
+BISON_CXX_COMPILE_STDCXX_11
+BISON_CXX_COMPILE_STDCXX_14
+BISON_CXX_COMPILE_STDCXX_17
+gl_WARN_ADD([-std=c++2a], [CXX2A_CXXFLAGS])
+AC_SUBST([STDCXX_FLAGS],
+["$CXX98_CXXFLAGS $CXX03_CXXFLAGS $CXX11_CXXFLAGS $CXX14_CXXFLAGS 
$CXX17_CXXFLAGS $CXX2A_CXXFLAGS "])
+AM_CONDITIONAL([ENABLE_CXX11], [test x"$CXX11_CXXFLAGS" != x])
+AC_LANG_POP([C++])
+
 AC_ARG_ENABLE([gcc-warnings],
 [  --enable-gcc-warnings   turn on lots of GCC warnings (not recommended).
                            Also, issue synclines from the examples/ to
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 00000000..71d4f365
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,70 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], 
[EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's compiler
+#   or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <address@hidden>
+#   Copyright (c) 2011 Maarten Bosmans <address@hidden>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  AC_COMPILE_IFELSE([m4_default([$5], [AC_LANG_PROGRAM()])],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], [$2], [$3])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/bison-cxx-std.m4 b/m4/bison-cxx-std.m4
new file mode 100644
index 00000000..f41216d4
--- /dev/null
+++ b/m4/bison-cxx-std.m4
@@ -0,0 +1,148 @@
+# bison-cxx-std.m4 serial 1
+
+# Copyright (C) 2018 Free Software Foundation, # Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+m4_define([_BISON_CXX_COMPILE_STDCXX_11_snippet],
+[#include <algorithm>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <string>
+#include <vector>
+
+  // C++11
+  template <typename T>
+  struct check
+  {
+    static_assert(sizeof(int) <= sizeof(T), "not big enough");
+  };
+
+  using right_angle_brackets = check<check<bool>>;
+
+  auto f = std::make_shared<std::string>("shared_ptr");
+
+  int a;
+  decltype(a) b;
+
+  typedef check<int> check_type;
+  check_type c;
+  check_type&& cr = static_cast<check_type&&>(c);
+
+  auto d = a;
+
+  // Some versions of libstdc++ do not support std::set::emplace.
+  void foo()
+  {
+    std::set<int> is;
+    is.emplace(42);
+  }
+
+  // Clang++ 3.5, for a while, was unable to process properly
+  // the for-loop because its variable, r, is a typedef...
+  // It failed as follows:
+  //
+  // error: unexpected ':' in nested name specifier; did you mean '::'?
+  //    for (auto r: std::set<int>{1, 2})
+  //               ^
+  //               ::
+  using r = std::set<int>;
+  void bar()
+  {
+    for (int r: std::set<int>{1, 2})
+      continue;
+  }
+])
+
+m4_define([_BISON_CXX_COMPILE_STDCXX_14_snippet],
+[  // C++14
+  void mismatch()
+  {
+    using ints = std::vector<int>;
+    auto v1 = ints{1, 2, 3};
+    auto v2 = ints{1, 2};
+    std::mismatch(std::begin(v1), std::end(v1),
+                  std::begin(v2), std::end(v2));
+  }
+])
+
+m4_define([_BISON_CXX_COMPILE_STDCXX_17_snippet],
+[  // C++17
+  namespace ns1::ns2::ns3 {}
+
+#include <optional>
+  auto opt_string = std::optional<std::string>{};
+  auto out = std::ostringstream{};
+])
+
+
+m4_define([_BISON_CXX_COMPILE_STDCXX_11_testbody],
+[AC_LANG_SOURCE([
+_BISON_CXX_COMPILE_STDCXX_11_snippet
+])])
+
+m4_define([_BISON_CXX_COMPILE_STDCXX_14_testbody],
+[AC_LANG_SOURCE([
+_BISON_CXX_COMPILE_STDCXX_11_snippet
+_BISON_CXX_COMPILE_STDCXX_14_snippet
+])])
+
+m4_define([_BISON_CXX_COMPILE_STDCXX_17_testbody],
+[AC_LANG_SOURCE([
+_BISON_CXX_COMPILE_STDCXX_11_snippet
+_BISON_CXX_COMPILE_STDCXX_14_snippet
+_BISON_CXX_COMPILE_STDCXX_17_snippet
+])])
+
+
+
+AC_DEFUN([BISON_CXX_COMPILE_STDCXX_11],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_LANG_PUSH([C++])
+for f in '-std=c++11' '-std=c++11 -stdlib=libc++'
+do
+  AX_CHECK_COMPILE_FLAG([$f], [CXXFLAGS="$CXXFLAGS $f" stdpass=true], [], [],
+                        [_BISON_CXX_COMPILE_STDCXX_11_testbody])
+  if "${stdpass-false}"; then
+    CXX11_CXXFLAGS=$f
+    break
+  fi
+done
+AC_LANG_POP([C++])
+])
+
+
+AC_DEFUN([BISON_CXX_COMPILE_STDCXX_14],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_LANG_PUSH([C++])
+for f in '-std=c++14' '-std=c++14 -stdlib=libc++'
+do
+  AX_CHECK_COMPILE_FLAG([$f], [CXXFLAGS="$CXXFLAGS $f" stdpass=true], [], [],
+                        [_BISON_CXX_COMPILE_STDCXX_14_testbody])
+  if "${stdpass-false}"; then
+    CXX14_CXXFLAGS=$f
+    break
+  fi
+done
+AC_LANG_POP([C++])
+])
+
+
+AC_DEFUN([BISON_CXX_COMPILE_STDCXX_17],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_LANG_PUSH([C++])
+for f in '-std=c++17' '-std=c++17 -stdlib=libc++' \
+         '-std=c++1z' '-std=c++1z -stdlib=libc++'
+do
+  AX_CHECK_COMPILE_FLAG([$f], [CXXFLAGS="$CXXFLAGS $f" stdpass=true], [], [],
+                        [_BISON_CXX_COMPILE_STDCXX_17_testbody])
+  if "${stdpass-false}"; then
+    CXX17_CXXFLAGS=$f
+    break
+  fi
+done
+AC_LANG_POP([C++])
+])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]