about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJim Meyering <meyering@fb.com>2014-06-05 10:42:05 -0700
committerJim Meyering <meyering@fb.com>2016-12-18 01:30:51 -0800
commite077349ce589466eecd47213db4fae6b80ec18c4 (patch)
tree3f8dc06410c398f69426bf115e643284a133436b
parent009ba649b4999ea269de8d0b301e659f075df495 (diff)
downloadglibc-e077349ce589466eecd47213db4fae6b80ec18c4.tar.gz
glibc-e077349ce589466eecd47213db4fae6b80ec18c4.tar.xz
glibc-e077349ce589466eecd47213db4fae6b80ec18c4.zip
assert.h: allow gcc to detect assert(a = 1) errors
* assert/assert.h (assert): Rewrite assert's definition so that
a s/==/=/ typo, e.g., assert(errno = ENOENT) is not hidden from
gcc's -Wparentheses by assert-added parentheses.  The new definition
uses "if (expr) /* empty */; else __assert_fail...", so
gcc -Wall will now detect that type of error in an assert, too.
The __STRICT_ANSI__ disjunct is to make this work also with both
-ansi and  -pedantic, which would reject the use of ({...}).
I would have preferred to use __extension__ to mark that, but
doing so would mistakenly suppress warnings about any extension
in the user-supplied "expr".
E.g., "assert ( ({1;}) )" must continue to evoke a warning.
-rw-r--r--ChangeLog8
-rw-r--r--assert/assert.h21
2 files changed, 25 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 452210e9ca..5e49f6ba29 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2016-11-25  Jim Meyering  <meyering@fb.com>
+
+	Let gcc detect assert(a = 1) errors.
+	* assert/assert.h (assert) Rewrite, retaining the old definintion
+	when required, but otherwise putting the expression as-is in an "if"
+	expression (hence, with no added parentheses) within a statement
+	expression.
+
 2016-12-17  Siddhesh Poyarekar  <siddhesh@sourceware.org>
 
 	* benchtests/Makefile (binaries-benchset): Depend on libsupport
diff --git a/assert/assert.h b/assert/assert.h
index 729edeb949..0f25131ae4 100644
--- a/assert/assert.h
+++ b/assert/assert.h
@@ -82,10 +82,23 @@ extern void __assert (const char *__assertion, const char *__file, int __line)
 
 __END_DECLS
 
-# define assert(expr)							\
-  ((expr)								\
-   ? __ASSERT_VOID_CAST (0)						\
-   : __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
+/* When possible, define assert so that it does not add extra
+   parentheses around EXPR.  Otherwise, those added parentheses would
+   suppress warnings we'd expect to be detected by gcc's -Wparentheses.  */
+# if !defined __GNUC__ || defined __STRICT_ANSI__
+#  define assert(expr)							\
+    ((expr)								\
+     ? __ASSERT_VOID_CAST (0)						\
+     : __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
+# else
+#  define assert(expr)							\
+    ({									\
+      if (expr)								\
+        ; /* empty */							\
+      else								\
+        __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION);	\
+    })
+# endif
 
 # ifdef	__USE_GNU
 #  define assert_perror(errnum)						\