Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/sys sys/cdefs.h: New __MACROUSE for macros to type-check...



details:   https://anonhg.NetBSD.org/src/rev/a47e01d4d06c
branches:  trunk
changeset: 374526:a47e01d4d06c
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Apr 30 08:45:48 2023 +0000

description:
sys/cdefs.h: New __MACROUSE for macros to type-check arguments.

This way, if there's a macro F(x) with a conditional definition --
e.g., conditional on DIAGNOSTIC or KDTRACE_HOOKS -- it can do
__MACROUSE(x) in the definition that's supposed to compile away,
without triggering `variable set but not used' errors, while still
catching type errors in the expression x.  But there's no cost or
side effects incurred in the generated code because the value is not
computed.

This should be the same as __USE, but I haven't figured out how to
make it work for both bit fields (which are likely to appear in macro
arguments) and aggregates (structs/unions, which are likely to appear
as variable declarations), so for now we use two separate macros.

diffstat:

 sys/sys/cdefs.h |  35 +++++++++++++++++++++++++++++++++--
 1 files changed, 33 insertions(+), 2 deletions(-)

diffs (49 lines):

diff -r a1050d15d93f -r a47e01d4d06c sys/sys/cdefs.h
--- a/sys/sys/cdefs.h   Sun Apr 30 08:45:39 2023 +0000
+++ b/sys/sys/cdefs.h   Sun Apr 30 08:45:48 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cdefs.h,v 1.159 2022/01/22 08:58:48 skrll Exp $        */
+/*     $NetBSD: cdefs.h,v 1.160 2023/04/30 08:45:48 riastradh Exp $    */
 
 /* * Copyright (c) 1991, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -687,7 +687,38 @@
 #define __CASTV(__dt, __st)    __CAST(__dt, __CAST(void *, __st))
 #define __CASTCV(__dt, __st)   __CAST(__dt, __CAST(const void *, __st))
 
-#define __USE(a) (/*LINTED*/(void)(a))
+/*
+ * Suppresses `variable set but not used' warnings.
+ *
+ * Typically for #ifdefs, where one branch of the #ifdef uses a
+ * variable but the other does not.  Useful in patching external code
+ * to keep the patches narrowly scoped.
+ *
+ * Limitation: Only for variables, and only non-volatile variables.
+ *
+ * (Abusing this for anything else may lead to side effects.  Pointers
+ * to volatile objects are OK, as in `volatile int *a', as long as the
+ * pointer itself is not volatile, as in `int *volatile a'.)
+ */
+#define        __USE(a) (/*LINTED*/(void)(a))
+
+/*
+ * Verifies the expression e compiles, but does not evaluate it.  Safe
+ * when e has side effects.
+ *
+ * Typically used for the arguments to macros with conditional
+ * definitions like DIAGNOSTIC or KDTRACE_HOOKS: when enabled, the
+ * macro uses the argument; when disabled, the macro passes the
+ * argument to __MACROUSE but doesn't otherwise use it.  Cast to long
+ * in case the argument is a bit field, which is forbidden in sizeof.
+ *
+ * Limitation: Doesn't work for expressions of aggregate (struct/union)
+ * types.
+ *
+ * (If you find a way to handle both bit fields and aggregate types,
+ * you could unify __USE and __MACROUSE.)
+ */
+#define        __MACROUSE(e)   (/*LINTED*/(void)sizeof((long)(e)))
 
 #define __type_mask(t) (/*LINTED*/sizeof(t) < sizeof(intmax_t) ? \
     (~((1ULL << (sizeof(t) * NBBY)) - 1)) : 0ULL)



Home | Main Index | Thread Index | Old Index