[Git][ghc/ghc][master] 9 commits: rts: introduce (and use) `STG_NORETURN`
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Wed Nov 2 16:07:13 UTC 2022
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
6b400d26 by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: introduce (and use) `STG_NORETURN`
Instead of sprinkling the codebase with
`GNU(C3)_ATTRIBUTE(__noreturn__)`, add a `STG_NORETURN` macro (for,
basically, the same thing) similar to `STG_UNUSED` and others, and
update the code to use this macro where applicable.
- - - - -
f9638654 by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: consistently use `STG_UNUSED`
- - - - -
81a58433 by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: introduce (and use) `STG_USED`
Similar to `STG_UNUSED`, have a specific macro for
`__attribute__(used)`.
- - - - -
41e1f748 by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: introduce (and use) `STG_MALLOC`
Instead of using `GNUC3_ATTRIBUTE(__malloc__)`, provide a `STG_MALLOC`
macro definition and use it instead.
- - - - -
3a9a8bde by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: use `STG_UNUSED`
- - - - -
9ab999de by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: specify deallocator of allocating functions
This patch adds a new `STG_MALLOC1` macro (and its counterpart
`STG_MALLOC2` for completeness) which allows to specify the deallocation
function to be used with allocations of allocating functions, and
applies it to `stg*allocBytes`.
It also fixes a case where `free` was used to free up an
`stgMallocBytes` allocation, found by the above change.
See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381
- - - - -
81c0c7c9 by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: use `alloc_size` attribute
This patch adds the `STG_ALLOC_SIZE1` and `STG_ALLOC_SIZE2` macros which
allow to set the `alloc_size` attribute on functions, when available.
See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute
See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381
- - - - -
99a1d896 by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: add and use `STG_RETURNS_NONNULL`
See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-returns_005fnonnull-function-attribute
See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381
- - - - -
c235b399 by Nicolas Trangez at 2022-11-02T12:06:48-04:00
rts: tag `stgStrndup` as `STG_MALLOC`
See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381
- - - - -
23 changed files:
- rts/CloneStack.c
- rts/Heap.c
- rts/Hpc.c
- rts/Linker.c
- rts/RtsAPI.c
- rts/RtsFlags.c
- rts/RtsMessages.c
- rts/RtsStartup.c
- rts/RtsUtils.h
- rts/StgCRun.c
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/Stg.h
- rts/include/rts/Main.h
- rts/include/rts/Messages.h
- rts/include/rts/OSThreads.h
- rts/include/rts/Threads.h
- rts/linker/Elf.c
- rts/linker/M32Alloc.h
- rts/linker/elf_reloc_aarch64.c
- rts/linker/elf_tlsgd.c
- rts/posix/OSThreads.c
- rts/posix/Select.c
Changes:
=====================================
rts/CloneStack.c
=====================================
@@ -98,7 +98,7 @@ void handleCloneStackMessage(MessageCloneStack *msg){
#else // !defined(THREADED_RTS)
-GNU_ATTRIBUTE(__noreturn__)
+STG_NORETURN
void sendCloneStackMessage(StgTSO *tso STG_UNUSED, HsStablePtr mvar STG_UNUSED) {
barf("Sending CloneStackMessages is only available in threaded RTS!");
}
=====================================
rts/Heap.c
=====================================
@@ -278,7 +278,7 @@ StgMutArrPtrs *heap_view_closurePtrs(Capability *cap, StgClosure *closure) {
for (StgWord i = 0; i<nptrs; i++) {
arr->payload[i] = ptrs[i];
}
- free(ptrs);
+ stgFree(ptrs);
return arr;
}
=====================================
rts/Hpc.c
=====================================
@@ -45,7 +45,7 @@ HpcModuleInfo *modules = 0;
static char *tixFilename = NULL;
-static void GNU_ATTRIBUTE(__noreturn__)
+static void STG_NORETURN
failure(char *msg) {
debugTrace(DEBUG_hpc,"hpc failure: %s\n",msg);
fprintf(stderr,"Hpc failure: %s\n",msg);
=====================================
rts/Linker.c
=====================================
@@ -1971,7 +1971,7 @@ void * loadNativeObj (pathchar *path, char **errmsg)
return r;
}
#else
-void * GNU_ATTRIBUTE(__noreturn__)
+void * STG_NORETURN
loadNativeObj (pathchar *path, char **errmsg)
{
UNUSED(path);
=====================================
rts/RtsAPI.c
=====================================
@@ -862,7 +862,7 @@ void rts_listMiscRoots (ListRootsCb cb, void *user)
}
#else
-PauseToken GNU_ATTRIBUTE(__noreturn__)
+PauseToken STG_NORETURN
*rts_pause (void)
{
errorBelch("Warning: Pausing the RTS is only possible for "
@@ -870,7 +870,7 @@ PauseToken GNU_ATTRIBUTE(__noreturn__)
stg_exit(EXIT_FAILURE);
}
-void GNU_ATTRIBUTE(__noreturn__)
+void STG_NORETURN
rts_resume (PauseToken *pauseToken STG_UNUSED)
{
errorBelch("Warning: Resuming the RTS is only possible for "
=====================================
rts/RtsFlags.c
=====================================
@@ -119,7 +119,7 @@ static bool read_heap_profiling_flag(const char *arg);
static void read_trace_flags(const char *arg);
#endif
-static void errorUsage (void) GNU_ATTRIBUTE(__noreturn__);
+static void errorUsage (void) STG_NORETURN;
#if defined(mingw32_HOST_OS)
static char** win32_full_utf8_argv;
@@ -2421,7 +2421,7 @@ static void read_trace_flags(const char *arg)
}
#endif
-static void GNU_ATTRIBUTE(__noreturn__)
+static void STG_NORETURN
bad_option(const char *s)
{
errorBelch("bad RTS option: %s", s);
=====================================
rts/RtsMessages.c
=====================================
@@ -139,7 +139,7 @@ isGUIApp(void)
}
#endif
-void GNU_ATTRIBUTE(__noreturn__)
+void STG_NORETURN
rtsFatalInternalErrorFn(const char *s, va_list ap)
{
#if defined(mingw32_HOST_OS)
@@ -322,7 +322,7 @@ rtsDebugMsgFn(const char *s, va_list ap)
// Used in stg_badAlignment_entry defined in StgStartup.cmm.
-void rtsBadAlignmentBarf(void) GNUC3_ATTRIBUTE(__noreturn__);
+void rtsBadAlignmentBarf(void) STG_NORETURN;
void
rtsBadAlignmentBarf()
@@ -331,7 +331,7 @@ rtsBadAlignmentBarf()
}
// Used by code generator
-void rtsOutOfBoundsAccess(void) GNUC3_ATTRIBUTE(__noreturn__);
+void rtsOutOfBoundsAccess(void) STG_NORETURN;
void
rtsOutOfBoundsAccess()
=====================================
rts/RtsStartup.c
=====================================
@@ -660,7 +660,7 @@ shutdownHaskellAndExit(int n, int fastExit)
}
#if !defined(mingw32_HOST_OS)
-static void exitBySignal(int sig) GNUC3_ATTRIBUTE(__noreturn__);
+static void exitBySignal(int sig) STG_NORETURN;
void
shutdownHaskellAndSignal(int sig, int fastExit)
=====================================
rts/RtsUtils.h
=====================================
@@ -17,17 +17,36 @@
void initAllocator(void);
void shutdownAllocator(void);
-void *stgMallocBytes(size_t n, char *msg)
- GNUC3_ATTRIBUTE(__malloc__);
+void stgFree(void* p);
-void *stgReallocBytes(void *p, size_t n, char *msg);
+void *stgMallocBytes(size_t n, char *msg)
+ STG_MALLOC STG_MALLOC1(stgFree)
+ STG_ALLOC_SIZE1(1);
+/* Note: unlike `stgReallocBytes` and `stgCallocBytes`, `stgMallocBytes` is
+ * *not* `STG_RETURNS_NONNULL`, since it will return `NULL` when the requested
+ * allocation size is zero.
+ *
+ * See: https://gitlab.haskell.org/ghc/ghc/-/issues/22380
+ */
+
+void *stgReallocBytes(void *p, size_t n, char *msg)
+ STG_MALLOC1(stgFree)
+ STG_ALLOC_SIZE1(2)
+ STG_RETURNS_NONNULL;
+/* Note: `stgRallocBytes` can *not* be tagged as `STG_MALLOC`
+ * since its return value *can* alias an existing pointer (i.e.,
+ * the given pointer `p`).
+ * See the documentation of the `malloc` attribute in the GCC manual
+ * for more information.
+ */
void *stgCallocBytes(size_t count, size_t size, char *msg)
- GNUC3_ATTRIBUTE(__malloc__);
-
-char *stgStrndup(const char *s, size_t n);
+ STG_MALLOC STG_MALLOC1(stgFree)
+ STG_ALLOC_SIZE2(1, 2)
+ STG_RETURNS_NONNULL;
-void stgFree(void* p);
+char *stgStrndup(const char *s, size_t n)
+ STG_MALLOC STG_MALLOC1(stgFree);
/* -----------------------------------------------------------------------------
* Misc other utilities
=====================================
rts/StgCRun.c
=====================================
@@ -163,7 +163,7 @@ StgFunPtr StgReturn(void)
* */
-static void GNUC3_ATTRIBUTE(used)
+static void STG_USED
StgRunIsImplementedInAssembler(void)
{
__asm__ volatile (
@@ -372,7 +372,7 @@ stack unwinding.
*/
-static void GNUC3_ATTRIBUTE(used)
+static void STG_USED
StgRunIsImplementedInAssembler(void)
{
__asm__ volatile (
@@ -595,7 +595,7 @@ StgRunIsImplementedInAssembler(void)
// This version is for PowerPC Linux.
-static void GNUC3_ATTRIBUTE(used)
+static void STG_USED
StgRunIsImplementedInAssembler(void)
{
__asm__ volatile (
@@ -698,7 +698,7 @@ StgRunIsImplementedInAssembler(void)
* the TOC pointer from the function descriptor upon a call to StgReturn.
* That TOC pointer is the same as the TOC pointer in StgRun.
*/
-static void GNUC3_ATTRIBUTE(used)
+static void STG_USED
StgRunIsImplementedInAssembler(void)
{
__asm__ volatile (
=====================================
rts/include/Rts.h
=====================================
@@ -121,7 +121,7 @@ extern "C" {
-------------------------------------------------------------------------- */
void _assertFail(const char *filename, unsigned int linenum)
- GNUC3_ATTRIBUTE(__noreturn__);
+ STG_NORETURN;
void _warnFail(const char *filename, unsigned int linenum);
@@ -290,7 +290,7 @@ DLL_IMPORT_RTS extern char *prog_name;
void reportStackOverflow(StgTSO* tso);
void reportHeapOverflow(void);
-void stg_exit(int n) GNU_ATTRIBUTE(__noreturn__);
+void stg_exit(int n) STG_NORETURN;
#if !defined(mingw32_HOST_OS)
int stg_sig_install (int, int, void *);
=====================================
rts/include/RtsAPI.h
=====================================
@@ -310,11 +310,11 @@ extern void hs_init_ghc (int *argc, char **argv[], // program arguments
RtsConfig rts_config); // RTS configuration
extern void shutdownHaskellAndExit (int exitCode, int fastExit)
- GNUC3_ATTRIBUTE(__noreturn__);
+ STG_NORETURN;
#if !defined(mingw32_HOST_OS)
extern void shutdownHaskellAndSignal (int sig, int fastExit)
- GNUC3_ATTRIBUTE(__noreturn__);
+ STG_NORETURN;
#endif
extern void getProgArgv ( int *argc, char **argv[] );
=====================================
rts/include/Stg.h
=====================================
@@ -220,6 +220,7 @@
#endif
#define STG_UNUSED GNUC3_ATTRIBUTE(__unused__)
+#define STG_USED GNUC3_ATTRIBUTE(__used__)
/* Prevent functions from being optimized.
See Note [Windows Stack allocations] */
@@ -241,6 +242,67 @@
#define STG_PRINTF_ATTR(fmt_arg, rest) GNUC3_ATTRIBUTE(format(printf, fmt_arg, rest))
#endif
+#define STG_NORETURN GNU_ATTRIBUTE(__noreturn__)
+
+#define STG_MALLOC GNUC3_ATTRIBUTE(__malloc__)
+
+/* Instead of relying on GCC version checks to expand attributes,
+ * use `__has_attribute` which is supported by GCC >= 5 and Clang. Hence, the
+ * following macros won't expand on older compiler versions, but since they're
+ * purely for optimization or static analysis purposes, there's no harm done.
+ *
+ * See: https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html
+ * See: https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+ */
+#ifdef __has_attribute
+# define stg__has_attribute(attr) __has_attribute(attr)
+#else
+# define stg__has_attribute(attr) (0)
+#endif
+
+#ifdef __GNUC__
+# define STG_GNUC_GUARD_VERSION(major, minor) \
+ ((__GNUC__ > (major)) || \
+ ((__GNUC__ == (major)) && (__GNUC_MINOR__ >= (minor))))
+#else
+# define STG_GNUC_GUARD_VERSION(major, minor) (0)
+#endif
+
+/*
+ * The versions of the `__malloc__` attribute which take arguments are only
+ * supported in GCC 11 and later.
+ *
+ * See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
+ * See: https://developers.redhat.com/blog/2021/04/30/detecting-memory-management-bugs-with-gcc-11-part-1-understanding-dynamic-allocation#attribute_malloc
+ */
+#if stg__has_attribute(__malloc__) && STG_GNUC_GUARD_VERSION(11, 0)
+# define STG_MALLOC1(deallocator) __attribute__((__malloc__(deallocator)))
+# define STG_MALLOC2(deallocator, ptrIndex) __attribute__((__malloc__(deallocator, ptrIndex)))
+#else
+# define STG_MALLOC1(deallocator)
+# define STG_MALLOC2(deallocator, ptrIndex)
+#endif
+
+/*
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute
+ */
+#if stg__has_attribute(__alloc_size__)
+# define STG_ALLOC_SIZE1(position) __attribute__((__alloc_size__(position)))
+# define STG_ALLOC_SIZE2(position1, position2) __attribute__((__alloc_size__(position1, position2)))
+#else
+# define STG_ALLOC_SIZE1(position)
+# define STG_ALLOC_SIZE2(position1, position2)
+#endif
+
+/*
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-returns_005fnonnull-function-attribute
+ */
+#if stg__has_attribute(__returns_nonnull__)
+# define STG_RETURNS_NONNULL __attribute__((__returns_nonnull__))
+#else
+# define STG_RETURNS_NONNULL
+#endif
+
/* -----------------------------------------------------------------------------
Global type definitions
-------------------------------------------------------------------------- */
=====================================
rts/include/rts/Main.h
=====================================
@@ -15,4 +15,4 @@
int hs_main (int argc, char *argv[], // program args
StgClosure *main_closure, // closure for Main.main
RtsConfig rts_config) // RTS configuration
- GNUC3_ATTRIBUTE(__noreturn__);
+ STG_NORETURN;
=====================================
rts/include/rts/Messages.h
=====================================
@@ -31,15 +31,15 @@
* expected to return.
*/
void barf(const char *s, ...)
- GNUC3_ATTRIBUTE(__noreturn__)
+ STG_NORETURN
STG_PRINTF_ATTR(1, 2);
void vbarf(const char *s, va_list ap)
- GNUC3_ATTRIBUTE(__noreturn__);
+ STG_NORETURN;
// declared in Rts.h:
// extern void _assertFail(const char *filename, unsigned int linenum)
-// GNUC3_ATTRIBUTE(__noreturn__);
+// STG_NORETURN;
/*
* An error condition which is caused by and/or can be corrected by
=====================================
rts/include/rts/OSThreads.h
=====================================
@@ -168,7 +168,7 @@ typedef SRWLOCK Mutex;
// General thread operations
//
extern OSThreadId osThreadId ( void );
-extern void shutdownThread ( void ) GNUC3_ATTRIBUTE(__noreturn__);
+extern void shutdownThread ( void ) STG_NORETURN;
extern void yieldThread ( void );
typedef void* OSThreadProcAttr OSThreadProc(void *);
=====================================
rts/include/rts/Threads.h
=====================================
@@ -61,7 +61,7 @@ struct _StgMutArrPtrs *listThreads (Capability *cap);
pid_t forkProcess (HsStablePtr *entry);
#else
pid_t forkProcess (HsStablePtr *entry)
- GNU_ATTRIBUTE(__noreturn__);
+ STG_NORETURN;
#endif
HsBool rtsSupportsBoundThreads (void);
=====================================
rts/linker/Elf.c
=====================================
@@ -2054,7 +2054,7 @@ struct piterate_cb_info {
};
static int loadNativeObjCb_(struct dl_phdr_info *info,
- size_t _size GNUC3_ATTRIBUTE(__unused__), void *data) {
+ size_t _size STG_UNUSED, void *data) {
struct piterate_cb_info *s = (struct piterate_cb_info *) data;
// This logic mimicks _dl_addr_inside_object from glibc
=====================================
rts/linker/M32Alloc.h
=====================================
@@ -21,7 +21,7 @@
#if defined(NEED_M32)
#define M32_NO_RETURN /* Nothing */
#else
-#define M32_NO_RETURN GNUC3_ATTRIBUTE(__noreturn__)
+#define M32_NO_RETURN STG_NORETURN
#endif
struct m32_allocator_t;
=====================================
rts/linker/elf_reloc_aarch64.c
=====================================
@@ -22,7 +22,7 @@ bool isAdrp(addr_t p);
bool isLoadStore(addr_t p);
bool isAddSub(addr_t p);
bool isVectorOp(addr_t p);
-int64_t decodeAddendAarch64(Section * section, Elf_Rel * rel) GNU_ATTRIBUTE(__noreturn__);
+int64_t decodeAddendAarch64(Section * section, Elf_Rel * rel) STG_NORETURN;
bool encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend);
bool isBranch(addr_t p) {
@@ -51,8 +51,8 @@ bool isVectorOp(addr_t p) {
typedef uint32_t inst_t;
int64_t
-decodeAddendAarch64(Section * section __attribute__((unused)),
- Elf_Rel * rel __attribute__((unused)))
+decodeAddendAarch64(Section * section STG_UNUSED,
+ Elf_Rel * rel STG_UNUSED)
{
abort(/* we don't support Rel locations yet. */);
}
=====================================
rts/linker/elf_tlsgd.c
=====================================
@@ -161,7 +161,7 @@ typedef struct tls_sym {
typedef struct dl_phdr_info dlpi;
static int
-find_tls_sym(dlpi *info, size_t sz __attribute__((unused)), void *data)
+find_tls_sym(dlpi *info, size_t sz STG_UNUSED, void *data)
{
tls_sym *wanted = (tls_sym *)data;
const Elf_Addr base = info->dlpi_addr;
=====================================
rts/posix/OSThreads.c
=====================================
@@ -445,7 +445,7 @@ setThreadAffinity (uint32_t n, uint32_t m)
#elif defined(darwin_HOST_OS) && defined(THREAD_AFFINITY_POLICY)
// Schedules the current thread in the affinity set identified by tag n.
void
-setThreadAffinity (uint32_t n, uint32_t m GNUC3_ATTRIBUTE(__unused__))
+setThreadAffinity (uint32_t n, uint32_t m STG_UNUSED)
{
thread_affinity_policy_data_t policy;
=====================================
rts/posix/Select.c
=====================================
@@ -115,7 +115,7 @@ static bool wakeUpSleepingThreads (LowResTime now)
return flag;
}
-static void GNUC3_ATTRIBUTE(__noreturn__)
+static void STG_NORETURN
fdOutOfRange (int fd)
{
errorBelch("file descriptor %d out of range for select (0--%d).\n"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4521f6498d09f48a775a028efdd763c874da3451...c235b399d094af3b706eb5a4bf15712fe5e4f795
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4521f6498d09f48a775a028efdd763c874da3451...c235b399d094af3b706eb5a4bf15712fe5e4f795
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20221102/773fab22/attachment-0001.html>
More information about the ghc-commits
mailing list