Skip to content

Commit 4e59c63

Browse files
author
Kim Barrett
committed
8367282: FORBID_C_FUNCTION needs exception spec consistent with library declaration
Reviewed-by: dholmes, mbaesken
1 parent 850f904 commit 4e59c63

File tree

4 files changed

+64
-42
lines changed

4 files changed

+64
-42
lines changed

src/hotspot/os/posix/forbiddenFunctions_posix.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,28 @@
3737
#endif
3838

3939
// If needed, add os::strndup and use that instead.
40-
FORBID_C_FUNCTION(char* strndup(const char*, size_t), "don't use");
40+
FORBID_C_FUNCTION(char* strndup(const char*, size_t), noexcept, "don't use");
4141

4242
// These are unimplementable for Windows, and they aren't useful for a
4343
// POSIX implementation of NMT either.
4444
// https://stackoverflow.com/questions/62962839/stdaligned-alloc-missing-from-visual-studio-2019
45-
FORBID_C_FUNCTION(int posix_memalign(void**, size_t, size_t), "don't use");
46-
FORBID_C_FUNCTION(void* aligned_alloc(size_t, size_t), "don't use");
45+
FORBID_C_FUNCTION(int posix_memalign(void**, size_t, size_t), noexcept, "don't use");
46+
FORBID_C_FUNCTION(void* aligned_alloc(size_t, size_t), noexcept, "don't use");
4747

4848
// realpath with a null second argument mallocs a string for the result.
4949
// With a non-null second argument, there is a risk of buffer overrun.
5050
PRAGMA_DIAG_PUSH
5151
FORBIDDEN_FUNCTION_IGNORE_CLANG_FORTIFY_WARNING
52-
FORBID_C_FUNCTION(char* realpath(const char*, char*), "use os::realpath");
52+
FORBID_C_FUNCTION(char* realpath(const char*, char*), noexcept, "use os::realpath");
5353
PRAGMA_DIAG_POP
5454

5555
// Returns a malloc'ed string.
56-
FORBID_C_FUNCTION(char* get_current_dir_name(), "use os::get_current_directory");
56+
FORBID_C_FUNCTION(char* get_current_dir_name(), noexcept, "use os::get_current_directory");
5757

5858
// Problematic API that should never be used.
59-
FORBID_C_FUNCTION(char* getwd(char*), "use os::get_current_directory");
59+
FORBID_C_FUNCTION(char* getwd(char*), noexcept, "use os::get_current_directory");
6060

6161
// BSD utility that is subtly different from realloc.
62-
FORBID_C_FUNCTION(void* reallocf(void*, size_t), "use os::realloc");
62+
FORBID_C_FUNCTION(void* reallocf(void*, size_t), /* not noexcept */, "use os::realloc");
6363

6464
#endif // OS_POSIX_FORBIDDENFUNCTIONS_POSIX_HPP

src/hotspot/os/windows/forbiddenFunctions_windows.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929

3030
#include <stddef.h> // for size_t
3131

32+
// NOTE: The Windows C standard library doesn't declare functions "noexcept".
33+
3234
// _fullpath with a null first argument mallocs a string for the result.
33-
FORBID_IMPORTED_C_FUNCTION(char* _fullpath(char*, const char*, size_t), "use os::realpath");
35+
FORBID_IMPORTED_C_FUNCTION(char* _fullpath(char*, const char*, size_t), /* not noexcept */, "use os::realpath");
3436

3537
// _snprintf does NOT null terminate if the output would exceed the buffer size.
36-
FORBID_C_FUNCTION(int _snprintf(char*, size_t, const char*, ...), "use os::snprintf");
38+
FORBID_C_FUNCTION(int _snprintf(char*, size_t, const char*, ...), /* not noexcept */, "use os::snprintf");
3739

3840
#endif // OS_WINDOWS_FORBIDDENFUNCTIONS_WINDOWS_HPP

src/hotspot/share/utilities/compilerWarnings.hpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,26 @@
8686
// Support warnings for use of certain C functions, except where explicitly
8787
// permitted.
8888

89-
// FORBID_C_FUNCTION(Signature, Alternative)
89+
// FORBID_C_FUNCTION(Signature, Noexcept, Alternative)
9090
// - Signature: the function that should not normally be used.
91+
// - Noexcept: either the token `noexcept` or nothing. See below.
9192
// - Alternative: a string literal that may be used in a warning about a use,
9293
// often suggesting an alternative.
9394
// Declares the C-linkage function designated by Signature to be deprecated,
9495
// using the `deprecated` attribute with Alternative as an argument.
9596
//
97+
// The Noexcept argument is used to deal with differences among the standard
98+
// libraries of various platforms. For example, the C standard library on
99+
// Linux declares many functions `noexcept`. Windows and BSD C standard
100+
// libraries don't include exception specifications at all. This matters
101+
// because some compilers reject (some) differences between declarations that
102+
// differ in the exception specification. clang complains if the first
103+
// declaration is not noexcept while some later declaration is, but not the
104+
// reverse. gcc doesn't seem to care. (Maybe that's a gcc bug?) So if the
105+
// forbidding declaration differs from the platform's library then we may get
106+
// errors building with clang (but not gcc), depending on the difference and
107+
// the include order.
108+
//
96109
// The variants with IMPORTED in the name are to deal with Windows
97110
// requirements, using FORBIDDEN_FUNCTION_IMPORT_SPEC. See the Visual
98111
// Studio definition of that macro for more details. The default has
@@ -102,8 +115,21 @@
102115
// FORBID_NORETURN_C_FUNCTION deals with a clang issue. See the clang
103116
// definition of FORBIDDEN_FUNCTION_NORETURN_ATTRIBUTE for more
104117
// details. The default expands to `[[noreturn]]`.
105-
#define FORBID_C_FUNCTION(Signature, Alternative) \
106-
extern "C" { [[deprecated(Alternative)]] Signature; }
118+
#define FORBID_C_FUNCTION(Signature, Noexcept, Alternative) \
119+
extern "C" { \
120+
[[deprecated(Alternative)]] \
121+
Signature \
122+
/* 2-step pasting to avoid expansion of FFCN => nothing. */ \
123+
PASTE_TOKENS( \
124+
FORBIDDEN_FUNCTION_, \
125+
PASTE_TOKENS(COND_NOEXCEPT_, Noexcept)) \
126+
; \
127+
}
128+
129+
// Both Linux and AIX C libraries declare functions noexcept.
130+
// Neither BSD nor Windows C libraries declare functions noexcept.
131+
#define FORBIDDEN_FUNCTION_COND_NOEXCEPT_noexcept NOT_WINDOWS(NOT_BSD(noexcept))
132+
#define FORBIDDEN_FUNCTION_COND_NOEXCEPT_
107133

108134
#ifndef FORBIDDEN_FUNCTION_IMPORT_SPEC
109135
#define FORBIDDEN_FUNCTION_IMPORT_SPEC
@@ -117,14 +143,14 @@
117143
#define FORBIDDEN_FUNCTION_IGNORE_CLANG_FORTIFY_WARNING
118144
#endif
119145

120-
#define FORBID_IMPORTED_C_FUNCTION(Signature, Alternative) \
121-
FORBID_C_FUNCTION(FORBIDDEN_FUNCTION_IMPORT_SPEC Signature, Alternative)
146+
#define FORBID_IMPORTED_C_FUNCTION(Signature, Noexcept, Alternative) \
147+
FORBID_C_FUNCTION(FORBIDDEN_FUNCTION_IMPORT_SPEC Signature, Noexcept, Alternative)
122148

123-
#define FORBID_NORETURN_C_FUNCTION(Signature, Alternative) \
124-
FORBID_C_FUNCTION(FORBIDDEN_FUNCTION_NORETURN_ATTRIBUTE Signature, Alternative)
149+
#define FORBID_NORETURN_C_FUNCTION(Signature, Noexcept, Alternative) \
150+
FORBID_C_FUNCTION(FORBIDDEN_FUNCTION_NORETURN_ATTRIBUTE Signature, Noexcept, Alternative)
125151

126-
#define FORBID_IMPORTED_NORETURN_C_FUNCTION(Signature, Alternative) \
127-
FORBID_NORETURN_C_FUNCTION(FORBIDDEN_FUNCTION_IMPORT_SPEC Signature, Alternative)
152+
#define FORBID_IMPORTED_NORETURN_C_FUNCTION(Signature, Noexcept, Alternative) \
153+
FORBID_NORETURN_C_FUNCTION(FORBIDDEN_FUNCTION_IMPORT_SPEC Signature, Noexcept, Alternative)
128154

129155
// A BEGIN/END_ALLOW_FORBIDDEN_FUNCTIONS pair establishes a scope in which the
130156
// deprecation warnings used to forbid the use of certain functions are

src/hotspot/share/utilities/forbiddenFunctions.hpp

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,6 @@
3838
#include <stdlib.h>
3939
#endif
4040

41-
// Workaround for noexcept functions in glibc when using clang.
42-
// clang errors if declaration without exception specification preceeds
43-
// noexcept declaration, but not the other way around.
44-
#ifdef __clang__
45-
#include <stdio.h>
46-
#include <string.h>
47-
#include <wchar.h>
48-
#endif
49-
5041
#ifdef _WINDOWS
5142
#include "forbiddenFunctions_windows.hpp"
5243
#else
@@ -58,32 +49,35 @@
5849
// or have security concerns, either with preferred alternatives, or to be
5950
// avoided entirely.
6051

61-
FORBID_IMPORTED_NORETURN_C_FUNCTION(void exit(int), "use os::exit")
62-
FORBID_IMPORTED_NORETURN_C_FUNCTION(void _Exit(int), "use os::exit")
52+
FORBID_IMPORTED_NORETURN_C_FUNCTION(void exit(int), noexcept, "use os::exit")
53+
FORBID_IMPORTED_NORETURN_C_FUNCTION(void _Exit(int), noexcept, "use os::exit")
6354

6455
// Windows puts _exit in <stdlib.h>, POSIX in <unistd.h>.
65-
FORBID_IMPORTED_NORETURN_C_FUNCTION(void _exit(int), "use os::exit")
56+
FORBID_IMPORTED_NORETURN_C_FUNCTION(void _exit(int), /* not noexcept */, "use os::exit")
6657

67-
FORBID_IMPORTED_C_FUNCTION(char* strerror(int), "use os::strerror");
68-
FORBID_IMPORTED_C_FUNCTION(char* strtok(char*, const char*), "use strtok_r");
58+
FORBID_IMPORTED_C_FUNCTION(char* strerror(int), noexcept, "use os::strerror");
59+
FORBID_IMPORTED_C_FUNCTION(char* strtok(char*, const char*), noexcept, "use strtok_r");
6960

70-
FORBID_C_FUNCTION(int sprintf(char*, const char*, ...), "use os::snprintf");
71-
FORBID_C_FUNCTION(int snprintf(char*, size_t, const char*, ...), "use os::snprintf");
61+
// AIX declarations for sprintf and snprintf are not noexcept, which is
62+
// inconsistent with most other system header declarations, including being
63+
// inconsistent with vsprintf and fsnprintf.
64+
FORBID_C_FUNCTION(int sprintf(char*, const char*, ...), NOT_AIX(noexcept), "use os::snprintf");
65+
FORBID_C_FUNCTION(int snprintf(char*, size_t, const char*, ...), NOT_AIX(noexcept), "use os::snprintf");
7266

7367
PRAGMA_DIAG_PUSH
7468
FORBIDDEN_FUNCTION_IGNORE_CLANG_FORTIFY_WARNING
75-
FORBID_C_FUNCTION(int vsprintf(char*, const char*, va_list), "use os::vsnprintf");
76-
FORBID_C_FUNCTION(int vsnprintf(char*, size_t, const char*, va_list), "use os::vsnprintf");
69+
FORBID_C_FUNCTION(int vsprintf(char*, const char*, va_list), noexcept, "use os::vsnprintf");
70+
FORBID_C_FUNCTION(int vsnprintf(char*, size_t, const char*, va_list), noexcept, "use os::vsnprintf");
7771
PRAGMA_DIAG_POP
7872

7973
// All of the following functions return raw C-heap pointers (sometimes as an
8074
// option, e.g. realpath or getwd) or, in case of free(), take raw C-heap
8175
// pointers. We generally want allocation to be done through NMT.
82-
FORBID_IMPORTED_C_FUNCTION(void* malloc(size_t size), "use os::malloc");
83-
FORBID_IMPORTED_C_FUNCTION(void free(void *ptr), "use os::free");
84-
FORBID_IMPORTED_C_FUNCTION(void* calloc(size_t nmemb, size_t size), "use os::malloc and zero out manually");
85-
FORBID_IMPORTED_C_FUNCTION(void* realloc(void *ptr, size_t size), "use os::realloc");
86-
FORBID_IMPORTED_C_FUNCTION(char* strdup(const char *s), "use os::strdup");
87-
FORBID_IMPORTED_C_FUNCTION(wchar_t* wcsdup(const wchar_t *s), "don't use");
76+
FORBID_IMPORTED_C_FUNCTION(void* malloc(size_t size), noexcept, "use os::malloc");
77+
FORBID_IMPORTED_C_FUNCTION(void free(void *ptr), noexcept, "use os::free");
78+
FORBID_IMPORTED_C_FUNCTION(void* calloc(size_t nmemb, size_t size), noexcept, "use os::malloc and zero out manually");
79+
FORBID_IMPORTED_C_FUNCTION(void* realloc(void *ptr, size_t size), noexcept, "use os::realloc");
80+
FORBID_IMPORTED_C_FUNCTION(char* strdup(const char *s), noexcept, "use os::strdup");
81+
FORBID_IMPORTED_C_FUNCTION(wchar_t* wcsdup(const wchar_t *s), noexcept, "don't use");
8882

8983
#endif // SHARE_UTILITIES_FORBIDDENFUNCTIONS_HPP

0 commit comments

Comments
 (0)