[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