mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
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.
This commit is contained in:
26
configure.ac
26
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,17 @@ 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
|
||||
BISON_CXX_COMPILE_STDCXX_2A
|
||||
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
|
||||
|
||||
70
m4/ax_check_compile_flag.m4
Normal file
70
m4/ax_check_compile_flag.m4
Normal file
@@ -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 <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# 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
|
||||
167
m4/bison-cxx-std.m4
Normal file
167
m4/bison-cxx-std.m4
Normal file
@@ -0,0 +1,167 @@
|
||||
# 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_2A_snippet],
|
||||
[ // C++2A
|
||||
])
|
||||
|
||||
|
||||
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
|
||||
])])
|
||||
|
||||
m4_define([_BISON_CXX_COMPILE_STDCXX_2A_testbody],
|
||||
[AC_LANG_SOURCE([
|
||||
_BISON_CXX_COMPILE_STDCXX_11_snippet
|
||||
_BISON_CXX_COMPILE_STDCXX_14_snippet
|
||||
_BISON_CXX_COMPILE_STDCXX_17_snippet
|
||||
_BISON_CXX_COMPILE_STDCXX_2A_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],
|
||||
[AC_SUBST([CXX11_CXXFLAGS], [$f]) break],
|
||||
[], [],
|
||||
[_BISON_CXX_COMPILE_STDCXX_11_testbody])
|
||||
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],
|
||||
[AC_SUBST([CXX14_CXXFLAGS], [$f]) break],
|
||||
[], [],
|
||||
[_BISON_CXX_COMPILE_STDCXX_14_testbody])
|
||||
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++'
|
||||
do
|
||||
AX_CHECK_COMPILE_FLAG([$f],
|
||||
[AC_SUBST([CXX17_CXXFLAGS], [$f]) break],
|
||||
[], [],
|
||||
[_BISON_CXX_COMPILE_STDCXX_17_testbody])
|
||||
done
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([BISON_CXX_COMPILE_STDCXX_2A],
|
||||
[AC_REQUIRE([AC_PROG_CXX])
|
||||
AC_LANG_PUSH([C++])
|
||||
for f in '-std=c++2a' '-std=c++2a -stdlib=libc++'
|
||||
do
|
||||
AX_CHECK_COMPILE_FLAG([$f],
|
||||
[AC_SUBST([CXX2A_CXXFLAGS], [$f]) break],
|
||||
[], [],
|
||||
[_BISON_CXX_COMPILE_STDCXX_2A_testbody])
|
||||
done
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
@@ -57,8 +57,11 @@ fi
|
||||
|
||||
# Requiring a specific C++ standard.
|
||||
: ${CXX98_CXXFLAGS='@CXX98_CXXFLAGS@'}
|
||||
: ${CXX03_CXXFLAGS='@CXX03_CXXFLAGS@'}
|
||||
: ${CXX11_CXXFLAGS='@CXX11_CXXFLAGS@'}
|
||||
: ${STDCXX_FLAGS='@STDCXX_FLAGS@'}
|
||||
: ${CXX14_CXXFLAGS='@CXX14_CXXFLAGS@'}
|
||||
: ${CXX17_CXXFLAGS='@CXX17_CXXFLAGS@'}
|
||||
: ${CXX2A_CXXFLAGS='@CXX2A_CXXFLAGS@'}
|
||||
|
||||
# Be sure that the C++ compiler is not broken because of gnulib. This
|
||||
# cannot be checked in configure (gnulib is not parameterized yet),
|
||||
|
||||
@@ -565,9 +565,15 @@ main (int argc, char const* argv[])
|
||||
|
||||
m4_define([AT_FOR_EACH_CXX],
|
||||
[[at_for_each_cxx_CXXFLAGS_save=$CXXFLAGS
|
||||
for at_cxx_std in "" $STDCXX_FLAGS
|
||||
for at_cxx_std in '' \
|
||||
${CXX98_CXXFLAGS:+"$CXX98_CXXFLAGS"} \
|
||||
${CXX03_CXXFLAGS:+"$CXX03_CXXFLAGS"} \
|
||||
${CXX11_CXXFLAGS:+"$CXX11_CXXFLAGS"} \
|
||||
${CXX14_CXXFLAGS:+"$CXX14_CXXFLAGS"} \
|
||||
${CXX17_CXXFLAGS:+"$CXX17_CXXFLAGS"} \
|
||||
${CXX2A_CXXFLAGS:+"$CXX2A_CXXFLAGS"}
|
||||
do
|
||||
]AS_ECHO(["Testing with C++ standard flags: '$at_cxx_std'"])[
|
||||
]AS_ECHO(["======== Testing with C++ standard flags: '$at_cxx_std'"])[
|
||||
CXXFLAGS="$at_for_each_cxx_CXXFLAGS_save $at_cxx_std"
|
||||
]$1[
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user