mirror of
https://github.com/netwide-assembler/nasm
synced 2026-08-26 16:23:04 -04:00
portability: speed and modernize autoconf; compiler.h improvements
- Add some features to autoconf that makes it cleaner and faster - Modernize some of the autoconf macros - Update compiler.h with some C23 features Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
parent
95cf51c306
commit
55dd65cddc
12 changed files with 173 additions and 57 deletions
|
|
@ -1895,7 +1895,7 @@ static const char no_file_name[] = "nasm"; /* What to print if no file name */
|
|||
/*
|
||||
* For fatal/critical/panic errors, kill this process.
|
||||
*/
|
||||
static fatal_func die_hard(errflags true_type, errflags severity)
|
||||
static_fatal_func die_hard(errflags true_type, errflags severity)
|
||||
{
|
||||
fflush(NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
dnl --------------------------------------------------------------------------
|
||||
dnl PA_ADD_CFLAGS(variable, flag [,actual_flag [,success [,failure]]]])
|
||||
dnl PA_ADD_CFLAGS(flag [,actual_flag [,success [,failure]]]])
|
||||
dnl
|
||||
dnl Attempt to add the given option to xFLAGS, if it doesn't break
|
||||
dnl compilation. If the option to be tested is different than the
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
dnl --------------------------------------------------------------------------
|
||||
dnl PA_ADD_FLAGS(flagvar, flags)
|
||||
dnl PA_ADD_FLAGS(variable, flag [,actual_flag [,success [,failure]]]])
|
||||
dnl
|
||||
dnl Add [flags] to the variable [flagvar] if and only if it is accepted
|
||||
dnl by all languages affected by [flagvar], if those languages have
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
dnl --------------------------------------------------------------------------
|
||||
dnl PA_ADD_HEADERS(headers...)
|
||||
dnl
|
||||
dnl Call AC_CHECK_HEADERS(), and add to ac_includes_default if found
|
||||
dnl Call AC_CHECK_HEADERS_ONCE(), and add to ac_includes_default if found
|
||||
dnl --------------------------------------------------------------------------
|
||||
AC_DEFUN([_PA_ADD_HEADER],
|
||||
[AC_CHECK_HEADERS([$1],[ac_includes_default="$ac_includes_default
|
||||
[AC_CHECK_HEADERS_ONCE([$1])
|
||||
AS_IF([test x$ac_ac_header_$1 = xyes],
|
||||
[ac_includes_default="$ac_includes_default
|
||||
#include <$1>"
|
||||
])
|
||||
])
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ AC_DEFUN([PA_COMMON_ATTRIBUTES],
|
|||
PA_FUNC_ATTRIBUTE(sentinel,,,[const char *, ...],["a","b",NULL],end_with_null)
|
||||
PA_FUNC_ATTRIBUTE(format,[printf,1,2],int,[const char *, ...],["%d",1])
|
||||
PA_FUNC_ATTRIBUTE(const)
|
||||
PA_FUNC_ATTRIBUTE(unsequenced)
|
||||
PA_FUNC_ATTRIBUTE(reproducible)
|
||||
PA_FUNC_ATTRIBUTE(pure)
|
||||
PA_FUNC_ATTRIBUTE(cold,,,,,unlikely_func)
|
||||
PA_FUNC_ATTRIBUTE(maybe_unused)
|
||||
PA_FUNC_ATTRIBUTE(unused)
|
||||
PA_FUNC_ATTRIBUTE_ERROR])
|
||||
|
|
|
|||
13
autoconf/m4/pa_find_flags.m4
Normal file
13
autoconf/m4/pa_find_flags.m4
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
dnl --------------------------------------------------------------------------
|
||||
dnl PA_FIND_FLAGS(flagvar, flags_list)
|
||||
dnl
|
||||
dnl Add the first set of flags in flags_list that is accepted by
|
||||
dnl by all languages affected by [flagvar], if those languages have
|
||||
dnl been previously seen in the script.
|
||||
dnl --------------------------------------------------------------------------
|
||||
AC_DEFUN([PA_FIND_FLAGS],
|
||||
[_pa_find_flags_done=no
|
||||
m4_foreach([_pa_find_flags_flag],[$2],
|
||||
[
|
||||
AS_IF([test x$_pa_find_flags_done != xyes],
|
||||
[PA_ADD_FLAGS([$1],_pa_find_flags_flag,,[_pa_find_flags_done=yes])])])])
|
||||
|
|
@ -10,8 +10,7 @@ AC_DEFUN([PA_FUNC_SNPRINTF],
|
|||
for pa_try_func_snprintf in snprintf _snprintf
|
||||
do
|
||||
AS_IF([test $pa_cv_func_snprintf = no],
|
||||
[AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
AC_INCLUDES_DEFAULT
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
const char *snprintf_test(int x);
|
||||
const char *snprintf_test(int x)
|
||||
{
|
||||
|
|
@ -20,12 +19,9 @@ const char *snprintf_test(int x)
|
|||
sz = $pa_try_func_snprintf(buf, sizeof buf, "Hello = %d", x);
|
||||
return (sz < sizeof buf) ? buf : NULL;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
]],[[
|
||||
puts(snprintf_test(33));
|
||||
return 0;
|
||||
}
|
||||
])],
|
||||
]])],
|
||||
[pa_cv_func_snprintf=$pa_try_func_snprintf])])
|
||||
done
|
||||
])
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@ AC_DEFUN([PA_FUNC_VSNPRINTF],
|
|||
for pa_try_func_vsnprintf in vsnprintf _vsnprintf
|
||||
do
|
||||
AS_IF([test $pa_cv_func_vsnprintf = no],
|
||||
[AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
AC_INCLUDES_DEFAULT
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
const char *vsnprintf_test(const char *fmt, va_list va);
|
||||
const char *vsnprintf_test(const char *fmt, va_list va)
|
||||
{
|
||||
static char buf[[256]];
|
||||
static char buf[256];
|
||||
size_t sz;
|
||||
sz = $pa_try_func_vsnprintf(buf, sizeof buf, fmt, va);
|
||||
return (sz < sizeof buf) ? buf : NULL;
|
||||
|
|
@ -30,13 +29,10 @@ const char *vsnprintf_caller(const char *fmt, ...)
|
|||
what = vsnprintf_test(fmt, va);
|
||||
va_end(va);
|
||||
return what;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
}]], [[
|
||||
puts(vsnprintf_caller("Hello = %d", 33));
|
||||
return 0;
|
||||
}
|
||||
])],
|
||||
]])],
|
||||
[pa_cv_func_vsnprintf=$pa_try_func_vsnprintf])])
|
||||
done
|
||||
])
|
||||
|
|
|
|||
|
|
@ -3,11 +3,20 @@ dnl PA_PROG_CC()
|
|||
dnl
|
||||
dnl Similar to AC_PROG_CC, but add a prototype for main() to
|
||||
dnl AC_INCLUDES_DEFAULT to avoid -Werror from breaking compilation.
|
||||
dnl (Very odd!)
|
||||
dnl
|
||||
dnl It can optionally take lists of CFLAGS to be added. For each argument,
|
||||
dnl only the *first* flag accepted is added.
|
||||
dnl
|
||||
dnl BUG: this expands AC_CHECK_HEADERS_ONCE() before the flags get
|
||||
dnl probed. Don't know yet how to fix that.
|
||||
dnl --------------------------------------------------------------------------
|
||||
AC_DEFUN([PA_PROG_CC],
|
||||
[AC_PROG_CC
|
||||
AS_IF([test x$ac_cv_prog != xno],
|
||||
[ac_includes_default="$ac_includes_default
|
||||
AC_DEFUN_ONCE([PA_PROG_CC],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
ac_includes_default="$ac_includes_default
|
||||
#ifndef __cplusplus
|
||||
extern int main(void);
|
||||
#endif"])])
|
||||
#endif"
|
||||
PA_FIND_FLAGS(CFLAGS,[$1])
|
||||
])
|
||||
|
|
|
|||
|
|
@ -67,6 +67,46 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef unsequenced_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_UNSEQUENCED
|
||||
# define unsequenced_func ATTRIBUTE(unsequenced)
|
||||
# else
|
||||
# define unsequenced_func
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef unsequenced_func_ptr
|
||||
# ifdef HAVE_FUNC_PTR_ATTRIBUTE_UNSEQUENCED
|
||||
# define unsequenced_func_ptr ATTRIBUTE(unsequenced)
|
||||
# else
|
||||
# define unsequenced_func_ptr
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef noreturn_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_NORETURN
|
||||
# define noreturn_func ATTRIBUTE(noreturn)
|
||||
# else
|
||||
# define noreturn_func
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef reproducible_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_REPRODUCIBLE
|
||||
# define reproducible_func ATTRIBUTE(reproducible)
|
||||
# else
|
||||
# define reproducible_func
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef reproducible_func_ptr
|
||||
# ifdef HAVE_FUNC_PTR_ATTRIBUTE_REPRODUCIBLE
|
||||
# define reproducible_func_ptr ATTRIBUTE(reproducible)
|
||||
# else
|
||||
# define reproducible_func_ptr
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef pure_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_PURE
|
||||
# define pure_func ATTRIBUTE(pure)
|
||||
|
|
@ -83,14 +123,6 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef noreturn_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_NORETURN
|
||||
# define noreturn_func ATTRIBUTE(noreturn)
|
||||
# else
|
||||
# define noreturn_func
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef unlikely_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_COLD
|
||||
# define unlikely_func ATTRIBUTE(cold)
|
||||
|
|
@ -107,6 +139,22 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef maybe_unused_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_MAYBE_UNUSED
|
||||
# define maybe_unused_func ATTRIBUTE(maybe_unused)
|
||||
# else
|
||||
# define maybe_unused_func
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef maybe_unused_func_ptr
|
||||
# ifdef HAVE_FUNC_PTR_ATTRIBUTE_MAYBE_UNUSED
|
||||
# define maybe_unused_func_ptr ATTRIBUTE(maybe_unused)
|
||||
# else
|
||||
# define maybe_unused_func_ptr
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef unused_func
|
||||
# ifdef HAVE_FUNC_ATTRIBUTE_UNUSED
|
||||
# define unused_func ATTRIBUTE(unused)
|
||||
|
|
|
|||
13
configure.ac
13
configure.ac
|
|
@ -18,12 +18,11 @@ dnl the best very slow and doesn't buy us a single thing at all.
|
|||
PA_CROSS_COMPILE
|
||||
|
||||
dnl Enable any available C extensions
|
||||
PA_PROG_CC
|
||||
PA_PROG_CC([[-std=c23],[-std=c17],[-std=c11],[-std=c99]])
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
PA_ADD_CPPFLAGS([-std=c23], [], [],
|
||||
[PA_ADD_CPPFLAGS([-std=c17], [], [],
|
||||
[PA_ADD_CPPFLAGS([-std=c11], [], [],
|
||||
[PA_ADD_CPPFLAGS([-std=c99])])])])
|
||||
dnl Some environments abuse __STRICT_ANSI__ to disable some
|
||||
dnl function declarations
|
||||
PA_ADD_CFLAGS([-U__STRICT_ANSI__])
|
||||
|
||||
dnl Options for debugging and profiling
|
||||
PA_OPTION_DEBUG
|
||||
|
|
@ -77,10 +76,6 @@ dnl Force clang to behave in a predictable manner, in order to make bugs
|
|||
dnl possible to track down. gcc appears to have this behavior by default.
|
||||
PA_ADD_CFLAGS([-ftrivial-auto-var-init=zero])
|
||||
|
||||
dnl Some environments abuse __STRICT_ANSI__ to disable some
|
||||
dnl function declarations
|
||||
PA_ADD_CFLAGS([-U__STRICT_ANSI__])
|
||||
|
||||
dnl Don't put things in common if we can avoid it. We don't want to
|
||||
dnl assume all compilers support common, and this will help find those
|
||||
dnl problems. This also works around an OSX linker problem.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 2007-2024 The NASM Authors - All Rights Reserved
|
||||
* Copyright 2007-2025 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
|
|
@ -187,18 +187,34 @@ size_t strlcpy(char *, const char *, size_t);
|
|||
char * pure_func strrchrnul(const char *, int);
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus /* C++ has false, true, bool as keywords */
|
||||
#if !defined(__cplusplus) || (__STDC_VERSION >= 202311L)
|
||||
/* C++ and C23 have bool, false, and true as proper keywords */
|
||||
# ifdef HAVE_STDBOOL_H
|
||||
/* If <stdbool.h> exists, include it explicitly to prevent it from
|
||||
begin included later, causing the "bool" macro to be defined. */
|
||||
# include <stdbool.h>
|
||||
# elif defined(HAVE__BOOL)
|
||||
# ifdef bool
|
||||
/* Force bool to be a typedef instead of a macro. What a "clever" hack
|
||||
this is... */
|
||||
typedef bool /* The macro definition of bool */
|
||||
# undef bool
|
||||
bool; /* No longer the macro definition */
|
||||
# endif
|
||||
# elif defined(HAVE___BOOL)
|
||||
typedef _Bool bool;
|
||||
# define false 0
|
||||
# define true 1
|
||||
# else
|
||||
/* This is sort of dangerous, since casts will behave different than
|
||||
casting to the standard boolean type. Always use !!, not (bool). */
|
||||
/* This is a bit dangerous, because casting to this ersatz bool
|
||||
will not produce the same result as the standard (bool) cast.
|
||||
Instead, use the bool() constructor-style macro defined below. */
|
||||
typedef enum bool { false, true } bool;
|
||||
# endif
|
||||
/* This amounts to a C++-style conversion cast to bool. This works
|
||||
because C ignores an argument-taking macro when used without an
|
||||
argument and because bool was redefined as a typedef if it previously
|
||||
was defined as a macro (see above.) */
|
||||
# define bool(x) ((bool)!!(x))
|
||||
#endif
|
||||
|
||||
/* Create a NULL pointer of the same type as the address of
|
||||
|
|
@ -311,13 +327,26 @@ static inline void *mempset(void *dst, int c, size_t n)
|
|||
* less likely to be taken.
|
||||
*/
|
||||
#if HAVE___BUILTIN_EXPECT
|
||||
# define likely(x) __builtin_expect(!!(x), 1)
|
||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
# define likely(x) __builtin_expect(bool(x), true)
|
||||
# define unlikely(x) __builtin_expect(bool(x), false)
|
||||
#else
|
||||
# define likely(x) (!!(x))
|
||||
# define unlikely(x) (!!(x))
|
||||
# define likely(x) bool(x)
|
||||
# define unlikely(x) bool(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Attributes
|
||||
*/
|
||||
|
||||
/* Standard [[...]] attribute testing macros */
|
||||
#if !defined(__has_c_attribute)
|
||||
# define __has_c_attribute(x) 0
|
||||
#endif
|
||||
#if !defined(__has_cpp_attribute)
|
||||
# define __has_cpp_attribute(x) 0
|
||||
#endif
|
||||
#define has_attribute(x) (__has_c_attribute(x) || __has_cpp_attribute(x))
|
||||
|
||||
#define safe_alloc never_null malloc_func
|
||||
#define safe_alloc_ptr never_null_ptr malloc_func_ptr
|
||||
|
||||
|
|
@ -331,20 +360,45 @@ static inline void *mempset(void *dst, int c, size_t n)
|
|||
/*
|
||||
* How to tell the compiler that a function doesn't return
|
||||
*/
|
||||
#ifdef HAVE_STDNORETURN_H
|
||||
#if has_attribute(noreturn)
|
||||
# define no_return [[noreturn]]
|
||||
#elif defined(HAVE_STDNORETURN_H)
|
||||
# include <stdnoreturn.h>
|
||||
# define no_return noreturn void
|
||||
# define no_return noreturn
|
||||
#elif defined(_MSC_VER)
|
||||
# define no_return __declspec(noreturn) void
|
||||
# define no_return __declspec(noreturn)
|
||||
#else
|
||||
# define no_return void noreturn_func
|
||||
# define no_return noreturn_func
|
||||
#endif
|
||||
|
||||
/* Function priority: pure < reproducible < unsequenced < const */
|
||||
|
||||
#ifndef HAVE_FUNC_ATTRIBUTE_REPRODUCIBLE
|
||||
# undef reproducible_func
|
||||
# define reproducible_func pure_func
|
||||
# undef reproducible_func_ptr
|
||||
# define reproducible_func_ptr pure_func_ptr
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FUNC_ATTRIBUTE_UNSEQUENCED
|
||||
# undef unsequenced_func
|
||||
# define unsequenced_func reproducible_func
|
||||
# undef unsequenced_func_ptr
|
||||
# define unsequenced_func_ptr reproducible_func_ptr
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FUNC_ATTRIBUTE_CONST
|
||||
# undef const_func
|
||||
# define const_func reproducible_func
|
||||
# undef const_func_ptr
|
||||
# define const_func_ptr reproducible_func_ptr
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A fatal function is both unlikely and no_return
|
||||
*/
|
||||
#define fatal_func no_return unlikely_func
|
||||
#define fatal_func_ptr no_return unlikely_func_ptr
|
||||
#define fatal_func no_return unlikely_func void
|
||||
#define static_fatal_func no_return unlikely_func static void
|
||||
|
||||
/*
|
||||
* How to tell the compiler that a function takes a printf-like string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue