Bug 94746

Summary: -Wsizeof-pointer-div not triggered by system header macros
Product: gcc Reporter: Alejandro Colomar <colomar.6.4.3>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: normal CC: asolokha
Priority: P3 Keywords: diagnostic
Version: 9.3.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Alejandro Colomar 2020-04-24 13:39:30 UTC
I found out that the macro `#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))` which is in libbsd's <sys/cdefs.h> doesn't trigger any warning when applied to a pointer.

I investigated the reason, and I found out that my own `#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))` doesn't trigger any warnings either (it is installed in `/usr/local/include/`, but it does trigger warnings when compiling before installing it.

So I came to the conclusion that the bug is the following:

GCC suppresses warnings in system headers, which of course is a generally good thing, but in this case it is not a good thing.

Maybe a solution would be to not suppress warnings about macros defined in system headers (this might suddenly trigger lots of warnings, some of them maybe unwanted, I don't know).  There might be more bugs like this one being ignored.

Code to reproduce the bug:

#include <sys/cdefs.h>

int main(void)
{
	int *p;

	return	__arraycount(p);
}

Minimum compilation settings to reproduce the bug:

$ gcc -Wsizeof-pointer-div bug.c `pkg-config --cflags libbsd-overlay`
Comment 1 Arseny Solokha 2020-04-25 19:10:30 UTC
I'm not a GCC developer, but this is by design.

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wsystem-headers
Comment 2 Alejandro Colomar 2020-04-25 22:15:54 UTC
Maybe the design is not perfect.

Maybe some special warnings should still be warned about when they are used in user's code.  I don't think there are any possible false positives with this warning.  But still I don't know.

Maybe I should add a pragma in the system header to enable `-Wsystem-headers` for that macro.
Comment 3 Alejandro Colomar 2020-04-26 00:08:03 UTC
I tried to use ``#pragma GCC diagnostic`` to enable ``-Wsystem-headers`` only for that macro.  It bloated me with completely unrelated errors from libraries.  So it is not an option.

The only workaround right now is to use a ``_Static_assert``:

.. code-block:: c

	#include <sys/cdefs.h>


	#define is_same_type(a, b)					\
		__builtin_types_compatible_p(__typeof__(a), __typeof__(b))

	#define is_array(a)		(!is_same_type((a), &(a)[0]))

	#define Static_assert_array(a)					\
		_Static_assert(is_array(a), "Not a `[]` !")

	#define ARRAY_SIZE(arr)		__extension__(			\
	{								\
		Static_assert_array(arr);				\
		__arraycount((arr));					\
	}								\
	)

This macro is safe no matter which warnings are enabled.  There is no other way to write a safe macro in a system library for calculating the size of an array.  I would call that a bug.  The warning is completely useless, unless you keep copy&pasting that macro for each and every project, which is of course *wrong*.