>From 9dbfe1f9c9d4435e4216c1391028a92c29f5d299 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 26 Apr 2017 23:25:11 +0200 Subject: [PATCH] noreturn: New module. * lib/noreturn.h: New file. * modules/noreturn: New file. * tests/test-noreturn.c: New file. * modules/noreturn-tests: New file. * tests/test-noreturn-c++.cc: New file. * modules/noreturn-c++-tests: New file. --- ChangeLog | 10 +++++ lib/noreturn.h | 101 +++++++++++++++++++++++++++++++++++++++++++++ modules/noreturn | 20 +++++++++ modules/noreturn-c++-tests | 17 ++++++++ modules/noreturn-tests | 11 +++++ tests/test-noreturn-c++.cc | 60 +++++++++++++++++++++++++++ tests/test-noreturn.c | 68 ++++++++++++++++++++++++++++++ 7 files changed, 287 insertions(+) create mode 100644 lib/noreturn.h create mode 100644 modules/noreturn create mode 100644 modules/noreturn-c++-tests create mode 100644 modules/noreturn-tests create mode 100644 tests/test-noreturn-c++.cc create mode 100644 tests/test-noreturn.c diff --git a/ChangeLog b/ChangeLog index 27cfacb..03a2c54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,16 @@ are the creation times. (nap): Update. +2017-04-26 Bruno Haible + + noreturn: New module. + * lib/noreturn.h: New file. + * modules/noreturn: New file. + * tests/test-noreturn.c: New file. + * modules/noreturn-tests: New file. + * tests/test-noreturn-c++.cc: New file. + * modules/noreturn-c++-tests: New file. + 2017-04-23 Bruno Haible nap.h: Fix logic. diff --git a/lib/noreturn.h b/lib/noreturn.h new file mode 100644 index 0000000..bd11ffd --- /dev/null +++ b/lib/noreturn.h @@ -0,0 +1,101 @@ +/* Macros for declaring functions as non-returning. + + Copyright (C) 2017 Free Software Foundation, Inc. + + 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 . */ + +/* Written by Paul Eggert and Bruno Haible. */ + +#ifndef _NORETURN_H +#define _NORETURN_H 1 + +/* A "non-returning" function is a function which cannot return normally. + It can transfer control only through longjmp(), throw (in C++), or similar + mechanisms. + + This file defines two macros _GL_NORETURN_FUNC and _GL_NORETURN_FUNCPTR, + that declare a function to be non-returning. + _GL_NORETURN_FUNC is for use in function declarations and function + definitions. + _GL_NORETURN_FUNCPTR is for use on function pointers. + */ + +/* This file is based on the following compiler dependent language features: + - '_Noreturn' - standardized by ISO C11, available in C only (not in C++), + and not applicable to pointers. + - '[[noreturn]]' - standardized by ISO C++11, available in C++ only, + and not applicable to pointers. + - '__attribute__((__noreturn__))' - available in GCC and clang only, + both in C and C++. + - '__declspec(noreturn)' - available in MSVC only, + both in C and C++, not applicable to pointers. + */ + +/* Declares that a function is nonreturning. + Use in C only code: + _GL_NORETURN_FUNC extern void func (void); + extern _GL_NORETURN_FUNC void func (void); + extern void _GL_NORETURN_FUNC func (void); + Use in C++ only code for a function with C linkage: + extern "C" { _GL_NORETURN_FUNC void func (void); } + Use in C++ only code for a function with C++ linkage: + _GL_NORETURN_FUNC extern void func (void); + Use in C & C++ code for a function with C linkage: + #ifdef __cplusplus + extern "C" { + #endif + _GL_NORETURN_FUNC void func (void); + #ifdef __cplusplus + } + #endif + Use in C & C++ code for a function with current language linkage: + _GL_NORETURN_FUNC extern void func (void); + */ +#if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__)) \ + || (0x5110 <= __SUNPRO_C) + /* For compatibility with _GL_NORETURN_FUNCPTR on clang, use + __attribute__((__noreturn__)), not _Noreturn. */ +# define _GL_NORETURN_FUNC __attribute__ ((__noreturn__)) +#elif 1200 <= _MSC_VER + /* Use MSVC specific syntax. */ +# define _GL_NORETURN_FUNC __declspec (noreturn) +#elif defined __cplusplus + /* Use ISO C++11 syntax when the compiler supports it. */ +# if (__cplusplus >= 201103 && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ + || (_MSC_VER >= 1900) +# define _GL_NORETURN_FUNC [[noreturn]] +# else +# define _GL_NORETURN_FUNC /* empty */ +# endif +#else + /* Use ISO C11 syntax when the compiler supports it. */ +# if __STDC_VERSION__ >= 201112 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) +# define _GL_NORETURN_FUNC _Noreturn +# else +# define _GL_NORETURN_FUNC /* empty */ +# endif +#endif + +/* Declares that a function is nonreturning. + Use in types and declarations that involve function pointers: + _GL_NORETURN_FUNCPTR void (*funcptr) (void); + */ +#if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__)) \ + || (0x5110 <= __SUNPRO_C) +# define _GL_NORETURN_FUNCPTR __attribute__ ((__noreturn__)) +#else +# define _GL_NORETURN_FUNCPTR /* empty */ +#endif + +#endif /* _NORETURN_H */ diff --git a/modules/noreturn b/modules/noreturn new file mode 100644 index 0000000..388ee0c --- /dev/null +++ b/modules/noreturn @@ -0,0 +1,20 @@ +Description: +Macros for declaring functions as non-returning. + +Files: +lib/noreturn.h + +Depends-on: + +configure.ac: + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +Bruno Haible diff --git a/modules/noreturn-c++-tests b/modules/noreturn-c++-tests new file mode 100644 index 0000000..e8a3466 --- /dev/null +++ b/modules/noreturn-c++-tests @@ -0,0 +1,17 @@ +Files: +tests/test-noreturn-c++.cc + +Status: +c++-test + +Depends-on: +ansi-c++-opt + +configure.ac: + +Makefile.am: +if ANSICXX +TESTS += test-noreturn-c++ +check_PROGRAMS += test-noreturn-c++ +test_noreturn_c___SOURCES = test-noreturn-c++.cc +endif diff --git a/modules/noreturn-tests b/modules/noreturn-tests new file mode 100644 index 0000000..61ec22b --- /dev/null +++ b/modules/noreturn-tests @@ -0,0 +1,11 @@ +Files: +tests/test-noreturn.c + +Depends-on: +noreturn-c++-tests + +configure.ac: + +Makefile.am: +TESTS += test-noreturn +check_PROGRAMS += test-noreturn diff --git a/tests/test-noreturn-c++.cc b/tests/test-noreturn-c++.cc new file mode 100644 index 0000000..d576b66 --- /dev/null +++ b/tests/test-noreturn-c++.cc @@ -0,0 +1,60 @@ +/* Test of macros for declaring functions as non-returning. + Copyright (C) 2017 Free Software Foundation, Inc. + + 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 . */ + +/* Written by Bruno Haible , 2017. */ + +#include + +#include + +/* Test _GL_NORETURN_FUNC on function declarations. */ + +extern "C" { _GL_NORETURN_FUNC void func1_c (void); } +_GL_NORETURN_FUNC extern void func1_cxx (void); + +/* Test _GL_NORETURN_FUNC on function definitions. */ + +_GL_NORETURN_FUNC void funcd_cxx (void) +{ + for (;;) + ; +} + +/* Test _GL_NORETURN_FUNCPTR. */ + +_GL_NORETURN_FUNCPTR void (*func1_c_ptr) (void) = func1_c; +_GL_NORETURN_FUNCPTR void (*func1_cxx_ptr) (void) = func1_cxx; +_GL_NORETURN_FUNCPTR void (*funcd_cxx_ptr) (void) = funcd_cxx; + +/* These could also be defined in a separate compilation unit. */ + +void func1_c (void) +{ + for (;;) + ; +} + +void func1_cxx (void) +{ + for (;;) + ; +} + + +int +main () +{ +} diff --git a/tests/test-noreturn.c b/tests/test-noreturn.c new file mode 100644 index 0000000..e7c162a --- /dev/null +++ b/tests/test-noreturn.c @@ -0,0 +1,68 @@ +/* Test of macros for declaring functions as non-returning. + Copyright (C) 2017 Free Software Foundation, Inc. + + 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 . */ + +/* Written by Bruno Haible , 2017. */ + +#include + +#include + +/* Test _GL_NORETURN_FUNC on function declarations. */ + +_GL_NORETURN_FUNC extern void func1 (void); +extern _GL_NORETURN_FUNC void func2 (void); +extern void _GL_NORETURN_FUNC func3 (void); + +/* Test _GL_NORETURN_FUNC on function definitions. */ + +_GL_NORETURN_FUNC void funcd (void) +{ + for (;;) + ; +} + +/* Test _GL_NORETURN_FUNCPTR. */ + +_GL_NORETURN_FUNCPTR void (*func1_ptr) (void) = func1; +_GL_NORETURN_FUNCPTR void (*func2_ptr) (void) = func2; +_GL_NORETURN_FUNCPTR void (*func3_ptr) (void) = func3; +_GL_NORETURN_FUNCPTR void (*funcd_ptr) (void) = funcd; + +/* These could also be defined in a separate compilation unit. */ + +void func1 (void) +{ + for (;;) + ; +} + +void func2 (void) +{ + for (;;) + ; +} + +void func3 (void) +{ + for (;;) + ; +} + + +int +main () +{ +} -- 2.7.4