From 80bf4ec34b6ead7ba9649da68e4ae47d28b58701 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 4 Jul 2015 14:53:20 +0200 Subject: [PATCH] Provide proper build-time assertions for NSC_SITYPE() We want to cause a diagnostic when NSC_SITYPE()'s argument isn't implemented. Commit aa6ad9d's solution is to have the macro expand into 1/0 then. Works with GCC, but Clang always warns "division by zero is undefined". The better, portable way to conditionally break the build is an array type with a size that's negative when the build should fail, else positive. Implement that wrapped in a sizeof() to make it an expression as macro BUILD_ASSERT_ONE(), and use it in NSC_SITYPE(). No more warnings from Clang 3.5.0. GCC still produces its "may be used uninitialized" false positives. Signed-off-by: Markus Armbruster --- include/misc.h | 7 +++++++ include/nsc.h | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/misc.h b/include/misc.h index cce94dfc..29a3671c 100644 --- a/include/misc.h +++ b/include/misc.h @@ -75,6 +75,13 @@ extern void oops(char *, char *, int); extern void (*oops_handler)(void); +/* + * Assert constant expression @cond, return 1. + * If @cond is zero, force a compilation error. + */ +#define BUILD_ASSERT_ONE(cond) \ + (sizeof(char[1 - 2 * !(cond)])) + void exit_nomem(void) ATTRIBUTE((noreturn)); /* return codes from command routines */ diff --git a/include/nsc.h b/include/nsc.h index c3e39277..4797bcd3 100644 --- a/include/nsc.h +++ b/include/nsc.h @@ -67,12 +67,14 @@ enum nsc_type { #define NSC_IS_PROMOTED(type) (NSC_LONG <= (type) && (type) <= NSC_STRING) /* Return nsc_type for a signed integer with the same size as TYPE. */ -#define NSC_SITYPE(type) \ +#define NSC_SITYPE(type) \ + (BUILD_ASSERT_ONE(NSC_SITYPE_(type) != NSC_NOTYPE) * NSC_SITYPE_(type)) +#define NSC_SITYPE_(type) \ (sizeof(type) == 1 ? NSC_CHAR \ : sizeof(type) == sizeof(short) ? NSC_SHORT \ : sizeof(type) == sizeof(int) ? NSC_INT \ : sizeof(type) == sizeof(long) ? NSC_LONG \ - : 1/0) + : NSC_NOTYPE) /* Value category */ enum nsc_cat {