Module Name:    src
Committed By:   kamil
Date:           Sun Sep 22 23:13:10 UTC 2019

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

Log Message:
Make __CTASSERT static assert again

Today GCC/Clang allow to specify typedef char[] with the dynamic VLA
property (as introduced in C99). This means that __CTASSERT(), when
misused with run-time semantics, was a dummy check generating either
1 or -1 size of typedef char[].

It was caught in runtime by kUBSan as -1 is size of VLA with unspecified
semantics in runtime (Undefined Behavior).

Use bit-field to enforce compile-time constant.

This approach has been inspired by the Perl variation of static_assert().


To generate a diff of this commit:
cvs rdiff -u -r1.144 -r1.145 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.144 src/sys/sys/cdefs.h:1.145
--- src/sys/sys/cdefs.h:1.144	Wed Sep 18 15:06:03 2019
+++ src/sys/sys/cdefs.h	Sun Sep 22 23:13:10 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cdefs.h,v 1.144 2019/09/18 15:06:03 kamil Exp $	*/
+/*	$NetBSD: cdefs.h,v 1.145 2019/09/22 23:13:10 kamil Exp $	*/
 
 /* * Copyright (c) 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -172,8 +172,11 @@
 #define	__CTASSERT99(x, a, b)	__CTASSERT0(x, __CONCAT(__ctassert,a), \
 					       __CONCAT(_,b))
 #endif
-#define	__CTASSERT0(x, y, z)	__CTASSERT1(x, y, z) 
-#define	__CTASSERT1(x, y, z)	typedef char y ## z[/*CONSTCOND*/(x) ? 1 : -1] __unused
+#define	__CTASSERT0(x, y, z)	__CTASSERT1(x, y, z)
+#define	__CTASSERT1(x, y, z)	\
+	typedef struct { \
+		unsigned int y ## z : /*CONSTCOND*/(x) ? 1 : -1; \
+	} y ## z ## _struct __unused
 
 /*
  * The following macro is used to remove const cast-away warnings

Reply via email to