chiark / gitweb /
lib/sod.h (SOD_DECL): Check that we allocated the right size.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 5 Aug 2019 09:27:42 +0000 (10:27 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 5 Aug 2019 09:27:42 +0000 (10:27 +0100)
doc/runtime.tex
lib/sod-hosted.c
lib/sod.3
lib/sod.h

index 4f6d277c673b6159116293faed8d1ecac3d7716b..59b4d72dd3069e200d8b9f6a9ac2dc2337bf4e70 100644 (file)
@@ -824,6 +824,10 @@ The following macro constructs an instance with automatic storage duration.
   instance should be torn down before this happens, using the
   \descref{fun}{sod_teardown}[function].  It may be appropriate to @|assert|
   that the object is ready for deallocation at this time.
   instance should be torn down before this happens, using the
   \descref{fun}{sod_teardown}[function].  It may be appropriate to @|assert|
   that the object is ready for deallocation at this time.
+
+  By default, this macro will abort the program if the size allocated for the
+  instance doesn't match the size required by the class object; set
+  \descref{feat}{SOD_RECKLESS} to inhibit this check.
 \end{describe}
 
 \subsubsection{Dynamic allocation}
 \end{describe}
 
 \subsubsection{Dynamic allocation}
index 961aa225bf569f4a7c3e366b5049bcc97ecb9ac6..5b6e3786d304c3fc9b0be1888a6e6357d267b16a 100644 (file)
 
 /*----- Header files ------------------------------------------------------*/
 
 
 /*----- Header files ------------------------------------------------------*/
 
+#include <stdio.h>
 #include <stdlib.h>
 
 #include "sod.h"
 
 #include <stdlib.h>
 
 #include "sod.h"
 
+/*----- Preliminary macros ------------------------------------------------*/
+
+#if __STDC_VERSION__ >= 199901
+#  define PRIuSZ "zu"
+#  define PRINT_SZ(x) (x)
+#else
+#  define PRIuSZ "lu"
+#  define PRINT_SZ(x) ((unsigned long)(x))
+#endif
+
 /*----- Main code ---------------------------------------------------------*/
 
 /*----- Main code ---------------------------------------------------------*/
 
+/* --- @sod__chksz_fail@ --- *
+ *
+ * Arguments:  @const SodClass *cls@ = class we were trying to instantiate
+ *             @size_t sz@ = size allocated
+ *
+ * Returns:    Doesn't.
+ *
+ * Use:                Reports instantiation failure caused by a mismatch between
+ *             the size allocated (@sz@) and the size required for an
+ *             instance of class @cls@.
+ */
+
+SOD__NORETURN void sod__chksz_fail(const SodClass *cls, size_t sz)
+{
+  fprintf(stderr, "INTERNAL ERROR: size mismatch for class `%s': "
+         "%"PRIuSZ" allocated but %"PRIuSZ" required",
+         cls->cls.name, PRINT_SZ(sz), PRINT_SZ(cls->cls.initsz));
+  abort();
+}
+
 /* --- @sod_make@, @sod_makev@ --- *
  *
  * Arguments:  @const SodClass *cls@ = class object for new instance
 /* --- @sod_make@, @sod_makev@ --- *
  *
  * Arguments:  @const SodClass *cls@ = class object for new instance
index de46128cf5568081ae01450ccfbc943637cea0c6..c49378a1222a787e843afc7118716e75fd5bffeb 100644 (file)
--- a/lib/sod.3
+++ b/lib/sod.3
@@ -494,6 +494,13 @@ It may be appropriate to
 .BR assert (3)
 that the object is ready for deallocation at this time.
 .PP
 .BR assert (3)
 that the object is ready for deallocation at this time.
 .PP
+By default, this macro will abort the program
+if the size allocated for the instance doesn't match
+the size required by the class object;
+set
+.B SOD_RECKLESS
+to inhibit this check.
+.PP
 The
 .B SOD_MAKE
 macro,
 The
 .B SOD_MAKE
 macro,
index dd1ee03aa1533259ad4a7fbe3bd83c98b9961a30..eb4a4edccd7b8367d6a28ec69d3899a62b8440c1 100644 (file)
--- a/lib/sod.h
+++ b/lib/sod.h
@@ -116,6 +116,19 @@ SOD__VARARGS_MACROS_PREAMBLE
 
 #define SOD__IGNORE(var) ((void)(var))
 
 
 #define SOD__IGNORE(var) ((void)(var))
 
+/* --- @SOD__NORETURN@ --- *
+ *
+ * Use:                Marks functions which are not expected to return.
+ */
+
+#if SOD__GCC_P(2, 5)
+#  define SOD__NORETURN __attribute__((__noreturn__))
+#endif
+
+#ifndef SOD__NORETURN
+#  define SOD__NORETURN
+#endif
+
 /* --- @SOD__PARANOIA@ --- *
  *
  * Arguments:  @cond@ = a condition to check
 /* --- @SOD__PARANOIA@ --- *
  *
  * Arguments:  @cond@ = a condition to check
@@ -307,7 +320,7 @@ struct sod_chain {
 
 /* --- @SOD_DECL@ --- *
  *
 
 /* --- @SOD_DECL@ --- *
  *
- * Arguments:  @cls@ = a class type name
+ * Arguments:  @cls_@ = a class type name
  *             @var@ = a variable name
  *             @keys@ = a @KWARGS(...)@ keyword argument sequence
  *
  *             @var@ = a variable name
  *             @keys@ = a @KWARGS(...)@ keyword argument sequence
  *
@@ -315,12 +328,31 @@ struct sod_chain {
  *             @cls@ with automatic lifetime.
  */
 
  *             @cls@ with automatic lifetime.
  */
 
-#define SOD_DECL(cls, var, keys)                                       \
-  struct cls##__ilayout var##__layout;                                 \
-  cls *var = (cls *)sod_init(cls##__class, &var##__layout, keys)
+#define SOD_DECL(cls_, var, keys)                                      \
+  struct cls_##__ilayout var##__layout;                                        \
+  cls_ *var =                                                          \
+    SOD__PARANOIA(sizeof(var##__layout) == cls_##__class->cls.initsz,  \
+                 (cls_ *)sod_init(cls_##__class, &var##__layout, keys), \
+                 (sod__chksz_fail(cls_##__class, sizeof(var##__layout)), \
+                  (cls_ *)0))
 
 /*----- Functions provided ------------------------------------------------*/
 
 
 /*----- Functions provided ------------------------------------------------*/
 
+/* --- @sod__chksz_fail@ --- *
+ *
+ * Arguments:  @const SodClass *cls@ = class we were trying to instantiate
+ *             @size_t sz@ = size allocated
+ *
+ * Returns:    Doesn't.
+ *
+ * Use:                Reports instantiation failure caused by a mismatch between
+ *             the size allocated (@sz@) and the size required for an
+ *             instance of class @cls@.
+ */
+
+extern SOD__NORETURN
+  void sod__chksz_fail(const SodClass */*cls*/, size_t /*sz*/);
+
 /* --- @sod_subclassp@ --- *
  *
  * Arguments:  @const SodClass *sub, *super@ = pointers to two classes
 /* --- @sod_subclassp@ --- *
  *
  * Arguments:  @const SodClass *sub, *super@ = pointers to two classes