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 <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2015-07-04 14:53:20 +02:00
parent d074d29736
commit 80bf4ec34b
2 changed files with 11 additions and 2 deletions

View file

@ -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 */

View file

@ -68,11 +68,13 @@ enum nsc_type {
/* Return nsc_type for a signed integer with the same size as 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 {