Module Name:    src
Committed By:   riastradh
Date:           Sun Apr 30 08:45:48 UTC 2023

Modified Files:
        src/sys/sys: cdefs.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.159 -r1.160 src/sys/sys/cdefs.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/sys/cdefs.h
diff -u src/sys/sys/cdefs.h:1.159 src/sys/sys/cdefs.h:1.160
--- src/sys/sys/cdefs.h:1.159	Sat Jan 22 08:58:48 2022
+++ src/sys/sys/cdefs.h	Sun Apr 30 08:45:48 2023
@@ -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)

Reply via email to