diff --git a/aclocal.m4 b/aclocal.m4 index cee63dfb..1ec6e7f8 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -73,3 +73,27 @@ void *foo(void) [Define to 1 if your compiler supports __attribute__(($1)) on functions])], [AC_MSG_RESULT([no])]) ]) + +dnl -------------------------------------------------------------------------- +dnl PA_FUNC_ATTRIBUTE_ERROR +dnl +dnl See if this compiler supports __attribute__((error("foo"))) +dnl The generic version of this doesn't work as it makes the compiler +dnl throw an error by design. +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_FUNC_ATTRIBUTE_ERROR, +[AC_MSG_CHECKING([if $CC supports the error function attribute]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#include +extern void __attribute__((error("message"))) barf(void); +void foo(void) +{ + if (0) + barf(); +} + ])], + [AC_MSG_RESULT([yes]) + AC_DEFINE(m4_toupper([HAVE_FUNC_ATTRIBUTE_ERROR]), 1, + [Define to 1 if your compiler supports __attribute__((error)) on functions])], + [AC_MSG_RESULT([no])]) +]) diff --git a/asm/parser.c b/asm/parser.c index 7b4cc5cb..bc8ba506 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -492,7 +492,7 @@ restart_parse: if (i == TOKEN_EOS) goto fail; - nasm_build_assert(P_none != 0); + nasm_build_assert(P_none == 0); memset(result->prefixes, P_none, sizeof(result->prefixes)); result->times = 1L; diff --git a/configure.ac b/configure.ac index fc03822f..3f148632 100644 --- a/configure.ac +++ b/configure.ac @@ -32,8 +32,6 @@ AH_TEMPLATE(WORDS_LITTLEENDIAN, [Define to 1 if your processor stores words with the least significant byte first (like Intel and VAX, unlike Motorola and SPARC).]) -PA_ADD_CFLAGS([-std=c99]) - dnl Force gcc and gcc-compatible compilers treat signed integers dnl as 2's complement PA_ADD_CFLAGS([-fwrapv]) @@ -73,6 +71,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS(inttypes.h) AC_CHECK_HEADERS(strings.h) AC_HEADER_STDBOOL +AC_CHECK_HEADERS(stdnoreturn.h) AC_CHECK_HEADERS(io.h) AC_CHECK_HEADERS(fcntl.h) AC_CHECK_HEADERS(unistd.h) @@ -145,6 +144,7 @@ PA_FUNC_ATTRIBUTE(alloc_size, (1)) PA_FUNC_ATTRIBUTE(format, [(printf,1,2)], int, [const char *, ...], ["%d",1]) PA_FUNC_ATTRIBUTE(const) PA_FUNC_ATTRIBUTE(pure) +PA_FUNC_ATTRIBUTE_ERROR dnl dnl support cchace diff --git a/include/compiler.h b/include/compiler.h index 2c4e6e3f..061b3441 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -77,6 +77,7 @@ # include "nasmint.h" #endif +#include #include #include #include @@ -208,7 +209,10 @@ char *strsep(char **, const char *); /* * How to tell the compiler that a function doesn't return */ -#ifdef HAVE_FUNC_ATTRIBUTE_NORETURN +#ifdef HAVE_STDNORETURN_H +# include +# define no_return noreturn void +#elif defined(HAVE_FUNC_ATTRIBUTE_NORETURN) # define no_return void __attribute__((noreturn)) #else # define no_return void diff --git a/include/nasmlib.h b/include/nasmlib.h index c772d1da..ea297b5d 100644 --- a/include/nasmlib.h +++ b/include/nasmlib.h @@ -175,7 +175,18 @@ no_return nasm_assert_failed(const char *, int, const char *); /* * NASM failure at build time if x != 0 */ -#define nasm_build_assert(x) (void)(sizeof(char[1-2*!!(x)])) +#ifdef static_assert +# define nasm_build_assert(x) static_assert(x, "assertion " #x " failed") +#elif defined(HAVE_FUNC_ATTRIBUTE_ERROR) +# define nasm_build_assert(x) \ + if (!(x)) { \ + extern void __attribute__((error("assertion " #x " failed"))) \ + fail(void); \ + fail(); \ + } +#else +# define nasm_build_assert(x) (void)(sizeof(char[1-2*!(x)])) +#endif /* * ANSI doesn't guarantee the presence of `stricmp' or