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 <armbru@pond.sub.org>
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 */
#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 {