mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-25 06:20:06 +00:00
711a322a23
The test for obsolete typedefs in installed headers was implemented using grep, and could therefore get false positives on e.g. “ulong” in a comment. It was also scanning all of the headers included by our headers, and therefore testing headers we don’t control, e.g. Linux kernel headers. This patch splits the obsolete-typedef test from scripts/check-installed-headers.sh to a separate program, scripts/check-obsolete-constructs.py. Being implemented in Python, it is feasible to make it tokenize C accurately enough to avoid false positives on the contents of comments and strings. It also only examines $(headers) in each subdirectory--all the headers we install, but not any external dependencies of those headers. Headers whose installed name starts with finclude/ are ignored, on the assumption that they contain Fortran. It is also feasible to make the new test understand the difference between _defining_ the obsolete typedefs and _using_ the obsolete typedefs, which means posix/{bits,sys}/types.h no longer need to be exempted. This uncovered an actual bug in bits/types.h: __quad_t and __u_quad_t were being used to define __S64_TYPE, __U64_TYPE, __SQUAD_TYPE and __UQUAD_TYPE. These are changed to __int64_t and __uint64_t respectively. This is a safe change, despite the comments in bits/types.h claiming a difference between __quad_t and __int64_t, because those comments are incorrect. In all current ABIs, both __quad_t and __int64_t are ‘long’ when ‘long’ is a 64-bit type, and ‘long long’ when ‘long’ is a 32-bit type, and similarly for __u_quad_t and __uint64_t. (Changing the types to be what the comments say they are would be an ABI break, as it affects C++ name mangling.) This patch includes a minimal change to make the comments not completely wrong. sys/types.h was defining the legacy BSD u_intN_t typedefs using a construct that was not necessarily consistent with how the C99 uintN_t typedefs are defined, and is also too complicated for the new script to understand (it lexes C relatively accurately, but it does not attempt to expand preprocessor macros, nor does it do any actual parsing). This patch cuts all of that out and uses bits/types.h's __uintN_t typedefs to define u_intN_t instead. This is verified to not change the ABI on any supported architecture, via the c++-types test, which means u_intN_t and uintN_t were, in fact, consistent on all supported architectures. Reviewed-by: Carlos O'Donell <carlos@redhat.com> * scripts/check-obsolete-constructs.py: New test script. * scripts/check-installed-headers.sh: Remove tests for obsolete typedefs, superseded by check-obsolete-constructs.py. * Rules: Run scripts/check-obsolete-constructs.py over $(headers) as a special test. Update commentary. * posix/bits/types.h (__SQUAD_TYPE, __S64_TYPE): Define as __int64_t. (__UQUAD_TYPE, __U64_TYPE): Define as __uint64_t. Update commentary. * posix/sys/types.h (__u_intN_t): Remove. (u_int8_t): Typedef using __uint8_t. (u_int16_t): Typedef using __uint16_t. (u_int32_t): Typedef using __uint32_t. (u_int64_t): Typedef using __uint64_t.
152 lines
4.8 KiB
Bash
152 lines
4.8 KiB
Bash
#! /bin/sh
|
|
# Copyright (C) 2016-2019 Free Software Foundation, Inc.
|
|
# This file is part of the GNU C Library.
|
|
#
|
|
# The GNU C Library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
#
|
|
# The GNU C Library 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
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with the GNU C Library; if not, see
|
|
# <http://www.gnu.org/licenses/>.
|
|
|
|
# For each installed header, confirm that it's possible to compile a
|
|
# file that includes that header and does nothing else, in several
|
|
# different compilation modes.
|
|
|
|
# These compilation switches assume GCC or compatible, which is probably
|
|
# fine since we also assume that when _building_ glibc.
|
|
c_modes="-std=c89 -std=gnu89 -std=c11 -std=gnu11"
|
|
cxx_modes="-std=c++98 -std=gnu++98 -std=c++11 -std=gnu++11"
|
|
|
|
# An exhaustive test of feature selection macros would take far too long.
|
|
# These are probably the most commonly used three.
|
|
lib_modes="-D_DEFAULT_SOURCE=1 -D_GNU_SOURCE=1 -D_XOPEN_SOURCE=700"
|
|
|
|
if [ $# -lt 3 ]; then
|
|
echo "usage: $0 c|c++ \"compile command\" header header header..." >&2
|
|
exit 2
|
|
fi
|
|
case "$1" in
|
|
(c)
|
|
lang_modes="$c_modes"
|
|
cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.c)
|
|
;;
|
|
(c++)
|
|
lang_modes="$cxx_modes"
|
|
cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.cc)
|
|
;;
|
|
(*)
|
|
echo "usage: $0 c|c++ \"compile command\" header header header..." >&2
|
|
exit 2;;
|
|
esac
|
|
shift
|
|
cc_cmd="$1"
|
|
shift
|
|
trap "rm -f '$cih_test_c'" 0
|
|
|
|
failed=0
|
|
is_x86_64=unknown
|
|
is_x32=unknown
|
|
for header in "$@"; do
|
|
# Skip various headers for which this test gets a false failure.
|
|
case "$header" in
|
|
# bits/* are not meant to be included directly and usually #error
|
|
# out if you try it.
|
|
# regexp.h is a stub containing only an #error.
|
|
# Sun RPC's .x files are traditionally installed in
|
|
# $prefix/include/rpcsvc, but they are not C header files.
|
|
(bits/* | regexp.h | rpcsvc/*.x)
|
|
continue;;
|
|
|
|
# All extant versions of sys/elf.h contain nothing more than an
|
|
# exhortation (either a #warning or an #error) to use sys/procfs.h
|
|
# instead, plus an inclusion of that header.
|
|
(sys/elf.h)
|
|
continue;;
|
|
|
|
# Skip Fortran headers.
|
|
(finclude/*)
|
|
continue;;
|
|
|
|
# sys/sysctl.h is unsupported for x32.
|
|
(sys/sysctl.h)
|
|
case "$is_x32" in
|
|
(yes) continue;;
|
|
(no) ;;
|
|
(unknown)
|
|
cat >"$cih_test_c" <<EOF
|
|
#if defined __x86_64__ && defined __ILP32__
|
|
# error "is x32"
|
|
#endif
|
|
EOF
|
|
if $cc_cmd -fsyntax-only "$cih_test_c" > /dev/null 2>&1
|
|
then
|
|
is_x32=no
|
|
else
|
|
is_x32=yes
|
|
continue
|
|
fi
|
|
;;
|
|
esac
|
|
;;
|
|
|
|
# sys/vm86.h is "unsupported on x86-64" and errors out on that target.
|
|
(sys/vm86.h)
|
|
case "$is_x86_64" in
|
|
(yes) continue;;
|
|
(no) ;;
|
|
(unknown)
|
|
cat >"$cih_test_c" <<EOF
|
|
#if defined __x86_64__ && __x86_64__
|
|
#error "is x86-64"
|
|
#endif
|
|
EOF
|
|
if $cc_cmd -fsyntax-only "$cih_test_c" > /dev/null 2>&1
|
|
then
|
|
is_x86_64=no
|
|
else
|
|
is_x86_64=yes
|
|
continue
|
|
fi
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
echo :: "$header"
|
|
for lang_mode in "" $lang_modes; do
|
|
for lib_mode in "" $lib_modes; do
|
|
echo :::: $lang_mode $lib_mode
|
|
if [ -z "$lib_mode" ]; then
|
|
expanded_lib_mode='/* default library mode */'
|
|
else
|
|
expanded_lib_mode=$(echo : $lib_mode | \
|
|
sed 's/^: -D/#define /; s/=/ /')
|
|
fi
|
|
cat >"$cih_test_c" <<EOF
|
|
/* These macros may have been defined on the command line. They are
|
|
inappropriate for this test. */
|
|
#undef _LIBC
|
|
#undef _GNU_SOURCE
|
|
/* The library mode is selected here rather than on the command line to
|
|
ensure that this selection wins. */
|
|
$expanded_lib_mode
|
|
#include <$header>
|
|
int avoid_empty_translation_unit;
|
|
EOF
|
|
if $cc_cmd -fsyntax-only $lang_mode "$cih_test_c" 2>&1
|
|
then :
|
|
else failed=1
|
|
fi
|
|
done
|
|
done
|
|
done
|
|
exit $failed
|