A new on by default warning in clang [1] aims to flags instances where
const variables without static or thread local storage are not
initialized because it can lead to an indeterminate value. The __dummy
variables in the typecheck() macro are the only places within the kernel
where this warning currently occurs.
drivers/gpu/drm/i915/gt/intel_ring.h:62:2: error: default initialization of an object of type 'typeof (ring->size)' (aka 'const unsigned int') leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-var-unsafe]
62 | typecheck(typeof(ring->size), next);
| ^
include/linux/typecheck.h:10:9: note: expanded from macro 'typecheck'
10 | ({ type __dummy; \
| ^
include/net/ip.h:478:14: error: default initialization of an object of type 'typeof (rt->dst.expires)' (aka 'const unsigned long') leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-var-unsafe]
478 | if (mtu && time_before(jiffies, rt->dst.expires))
| ^
include/linux/jiffies.h:138:26: note: expanded from macro 'time_before'
138 | #define time_before(a,b) time_after(b,a)
| ^
include/linux/jiffies.h:128:3: note: expanded from macro 'time_after'
128 | (typecheck(unsigned long, a) && \
| ^
include/linux/typecheck.h:11:12: note: expanded from macro 'typecheck'
11 | typeof(x) __dummy2; \
| ^
Zero initialize the variables to silence the warning while not impacting
the final code generation because the comparison only matters at compile
time, as suggested on the PR of [1] by the clang maintainer.
Cc: stable@vger.kernel.org
Link: https://github.com/llvm/llvm-project/commit/576161cb6069e2c7656a8ef530727a0f4aefff30 [1]
Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
Closes: https://lore.kernel.org/CA+G9fYuNjKcxFKS_MKPRuga32XbndkLGcY-PVuoSwzv6VWbY=w@mail.gmail.com/
Reported-by: Marcus Seyfarth <m.seyfarth@gmail.com>
Closes: https://github.com/ClangBuiltLinux/linux/issues/2088
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
include/linux/typecheck.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/typecheck.h b/include/linux/typecheck.h
index 46b15e2aaefb4e7a4d21c8797ec4d1578998981c..5b473c9905ae7fce58b7226b57b668f9ddaccaca 100644
--- a/include/linux/typecheck.h
+++ b/include/linux/typecheck.h
@@ -7,8 +7,8 @@
* Always evaluates to 1 so you may use it easily in comparisons.
*/
#define typecheck(type,x) \
-({ type __dummy; \
- typeof(x) __dummy2; \
+({ type __dummy = {}; \
+ typeof(x) __dummy2 = {}; \
(void)(&__dummy == &__dummy2); \
1; \
})
--
2.49.0
Hi Nathan,
kernel test robot noticed the following build errors:
[auto build test ERROR on ebd297a2affadb6f6f4d2e5d975c1eda18ac762d]
url: https://github.com/intel-lab-lkp/linux/commits/Nathan-Chancellor/kbuild-Disable-Wdefault-const-init-field-unsafe/20250502-070313
base: ebd297a2affadb6f6f4d2e5d975c1eda18ac762d
patch link: https://lore.kernel.org/r/20250501-default-const-init-clang-v1-2-3d2c6c185dbb%40kernel.org
patch subject: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
config: arc-randconfig-002-20250502 (https://download.01.org/0day-ci/archive/20250502/202505021716.olmL8WzB-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 12.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505021716.olmL8WzB-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505021716.olmL8WzB-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from include/linux/preempt.h:11,
from include/linux/sched.h:15,
from arch/arc/kernel/asm-offsets.c:6:
include/linux/irqflags.h: In function 'class_irqsave_destructor':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:268:21: note: in expansion of macro 'local_irq_restore'
268 | local_irq_restore(_T->flags),
| ^~~~~~~~~~~~~~~~~
include/linux/irqflags.h: In function 'class_irqsave_constructor':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:403:9: note: in definition of macro '__DEFINE_LOCK_GUARD_0'
403 | _lock; \
| ^~~~~
include/linux/irqflags.h:266:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_0'
266 | DEFINE_LOCK_GUARD_0(irqsave,
| ^~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:267:21: note: in expansion of macro 'local_irq_save'
267 | local_irq_save(_T->flags),
| ^~~~~~~~~~~~~~
In file included from include/linux/bitops.h:7,
from include/linux/thread_info.h:27,
from include/linux/sched.h:14:
include/linux/spinlock_api_smp.h: In function '__raw_spin_lock_irqsave':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:108:9: note: in expansion of macro 'local_irq_save'
108 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h: In function '__raw_spin_unlock_irqrestore':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock_api_smp.h:151:9: note: in expansion of macro 'local_irq_restore'
151 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h: In function '__raw_read_lock_irqsave':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:158:9: note: in expansion of macro 'local_irq_save'
158 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h: In function '__raw_write_lock_irqsave':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:184:9: note: in expansion of macro 'local_irq_save'
184 | local_irq_save(flags);
| ^~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h: In function '__raw_read_unlock_irqrestore':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:241:9: note: in expansion of macro 'local_irq_restore'
241 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h: In function '__raw_write_unlock_irqrestore':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:223:22: note: in expansion of macro 'raw_irqs_disabled_flags'
223 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/irqflags.h:177:17: note: in expansion of macro 'typecheck'
177 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:225:17: note: in expansion of macro 'raw_local_irq_restore'
225 | raw_local_irq_restore(flags); \
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/rwlock_api_smp.h:265:9: note: in expansion of macro 'local_irq_restore'
265 | local_irq_restore(flags);
| ^~~~~~~~~~~~~~~~~
include/linux/spinlock.h: In function 'spin_unlock_irqrestore':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:406:9: note: in expansion of macro 'raw_spin_unlock_irqrestore'
406 | raw_spin_unlock_irqrestore(&lock->rlock, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:406:9: note: in expansion of macro 'raw_spin_unlock_irqrestore'
406 | raw_spin_unlock_irqrestore(&lock->rlock, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:406:9: note: in expansion of macro 'raw_spin_unlock_irqrestore'
406 | raw_spin_unlock_irqrestore(&lock->rlock, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:406:9: note: in expansion of macro 'raw_spin_unlock_irqrestore'
406 | raw_spin_unlock_irqrestore(&lock->rlock, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h: In function 'class_raw_spinlock_irqsave_destructor':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:559:21: note: in expansion of macro 'raw_spin_unlock_irqrestore'
559 | raw_spin_unlock_irqrestore(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:559:21: note: in expansion of macro 'raw_spin_unlock_irqrestore'
559 | raw_spin_unlock_irqrestore(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:559:21: note: in expansion of macro 'raw_spin_unlock_irqrestore'
559 | raw_spin_unlock_irqrestore(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:385:25: note: in definition of macro '__DEFINE_UNLOCK_GUARD'
385 | if (_T->lock) { _unlock; } \
| ^~~~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:281:17: note: in expansion of macro 'typecheck'
281 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:559:21: note: in expansion of macro 'raw_spin_unlock_irqrestore'
559 | raw_spin_unlock_irqrestore(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h: In function 'class_raw_spinlock_irqsave_constructor':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:394:9: note: in definition of macro '__DEFINE_LOCK_GUARD_1'
394 | _lock; \
| ^~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:243:17: note: in expansion of macro 'typecheck'
243 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:558:21: note: in expansion of macro 'raw_spin_lock_irqsave'
558 | raw_spin_lock_irqsave(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:394:9: note: in definition of macro '__DEFINE_LOCK_GUARD_1'
394 | _lock; \
| ^~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:243:17: note: in expansion of macro 'typecheck'
243 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:558:21: note: in expansion of macro 'raw_spin_lock_irqsave'
558 | raw_spin_lock_irqsave(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:394:9: note: in definition of macro '__DEFINE_LOCK_GUARD_1'
394 | _lock; \
| ^~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:243:17: note: in expansion of macro 'typecheck'
243 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:558:21: note: in expansion of macro 'raw_spin_lock_irqsave'
558 | raw_spin_lock_irqsave(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:394:9: note: in definition of macro '__DEFINE_LOCK_GUARD_1'
394 | _lock; \
| ^~~~~
include/linux/spinlock.h:557:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1'
557 | DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t,
| ^~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:243:17: note: in expansion of macro 'typecheck'
243 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/spinlock.h:558:21: note: in expansion of macro 'raw_spin_lock_irqsave'
558 | raw_spin_lock_irqsave(_T->lock, _T->flags),
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h: In function 'class_raw_spinlock_irqsave_try_constructor':
>> include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:255:25: note: in definition of macro 'EXTEND_CLASS'
255 | { class_##_name##_t t = _init; return t; }
| ^~~~~
include/linux/spinlock.h:562:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1_COND'
562 | DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try,
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:298:9: note: in expansion of macro 'local_irq_save'
298 | local_irq_save(flags); \
| ^~~~~~~~~~~~~~
include/linux/spinlock.h:563:26: note: in expansion of macro 'raw_spin_trylock_irqsave'
563 | raw_spin_trylock_irqsave(_T->lock, _T->flags))
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: note: (near initialization for '__dummy')
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:255:25: note: in definition of macro 'EXTEND_CLASS'
255 | { class_##_name##_t t = _init; return t; }
| ^~~~~
include/linux/spinlock.h:562:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1_COND'
562 | DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try,
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:298:9: note: in expansion of macro 'local_irq_save'
298 | local_irq_save(flags); \
| ^~~~~~~~~~~~~~
include/linux/spinlock.h:563:26: note: in expansion of macro 'raw_spin_trylock_irqsave'
563 | raw_spin_trylock_irqsave(_T->lock, _T->flags))
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: error: empty scalar initializer
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:255:25: note: in definition of macro 'EXTEND_CLASS'
255 | { class_##_name##_t t = _init; return t; }
| ^~~~~
include/linux/spinlock.h:562:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1_COND'
562 | DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try,
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:298:9: note: in expansion of macro 'local_irq_save'
298 | local_irq_save(flags); \
| ^~~~~~~~~~~~~~
include/linux/spinlock.h:563:26: note: in expansion of macro 'raw_spin_trylock_irqsave'
563 | raw_spin_trylock_irqsave(_T->lock, _T->flags))
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:11:30: note: (near initialization for '__dummy2')
11 | typeof(x) __dummy2 = {}; \
| ^
include/linux/cleanup.h:255:25: note: in definition of macro 'EXTEND_CLASS'
255 | { class_##_name##_t t = _init; return t; }
| ^~~~~
include/linux/spinlock.h:562:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1_COND'
562 | DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try,
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:172:17: note: in expansion of macro 'typecheck'
172 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:216:17: note: in expansion of macro 'raw_local_irq_save'
216 | raw_local_irq_save(flags); \
| ^~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:298:9: note: in expansion of macro 'local_irq_save'
298 | local_irq_save(flags); \
| ^~~~~~~~~~~~~~
include/linux/spinlock.h:563:26: note: in expansion of macro 'raw_spin_trylock_irqsave'
563 | raw_spin_trylock_irqsave(_T->lock, _T->flags))
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/typecheck.h:10:24: error: empty scalar initializer
10 | ({ type __dummy = {}; \
| ^
include/linux/cleanup.h:255:25: note: in definition of macro 'EXTEND_CLASS'
255 | { class_##_name##_t t = _init; return t; }
| ^~~~~
include/linux/spinlock.h:562:1: note: in expansion of macro 'DEFINE_LOCK_GUARD_1_COND'
562 | DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try,
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/irqflags.h:188:17: note: in expansion of macro 'typecheck'
188 | typecheck(unsigned long, flags); \
| ^~~~~~~~~
include/linux/irqflags.h:217:22: note: in expansion of macro 'raw_irqs_disabled_flags'
217 | if (!raw_irqs_disabled_flags(flags)) \
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/spinlock.h:298:9: note: in expansion of macro 'local_irq_save'
298 | local_irq_save(flags); \
vim +10 include/linux/typecheck.h
4
5 /*
6 * Check at compile time that something is of a particular type.
7 * Always evaluates to 1 so you may use it easily in comparisons.
8 */
9 #define typecheck(type,x) \
> 10 ({ type __dummy = {}; \
11 typeof(x) __dummy2 = {}; \
12 (void)(&__dummy == &__dummy2); \
13 1; \
14 })
15
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Thu, 1 May 2025 at 16:00, Nathan Chancellor <nathan@kernel.org> wrote:
>
> +({ type __dummy = {}; \
> + typeof(x) __dummy2 = {}; \
I'm actually surprised that this doesn't cause warnings in itself.
The types in question are not necessarily compound types, and can be
simple types like 'int'.
The fact that you can write
int x = {};
without the compiler screaming bloody murder about that insanity blows
my mind, but it does seem to be valid C (*).
How long has that been valid? Because this is certainly new to the
kernel, and sparse does complain about this initializer.
So honestly, this will just cause endless sparse warnings instead. I
think disabling this warning for now is likely the right thing to do.
Linus
(*) Yes, the empty initializer is new in C23, but we've used that in
the kernel for non-scalar objects for a long time.
On Thu, May 01, 2025 at 04:28:25PM -0700, Linus Torvalds wrote:
> On Thu, 1 May 2025 at 16:00, Nathan Chancellor <nathan@kernel.org> wrote:
> >
> > +({ type __dummy = {}; \
> > + typeof(x) __dummy2 = {}; \
>
> I'm actually surprised that this doesn't cause warnings in itself.
>
> The types in question are not necessarily compound types, and can be
> simple types like 'int'.
>
> The fact that you can write
>
> int x = {};
>
> without the compiler screaming bloody murder about that insanity blows
> my mind, but it does seem to be valid C (*).
I thought the same thing but I tend to trust people who are smarter than
I am :)
> How long has that been valid? Because this is certainly new to the
> kernel, and sparse does complain about this initializer.
As you noted, brace initialization for scalars appears to always be
valid (at least in my testing) but as Al points out, empty braces for
scalars is only supported in GCC 13+ and Clang 17+ (I think [1] was the
clang commit), so that is not going to fly...
> So honestly, this will just cause endless sparse warnings instead. I
> think disabling this warning for now is likely the right thing to do.
but '= {0}' appears to work: https://godbolt.org/z/x7eae5vex
If using that instead upsets sparse still, then I can just abandon this
change and update the other patch to disable -Wdefault-const-init-unsafe
altogether (rather than just the field variant) but it seems like you
were not entirely opposed to this even in spite of sparse not supporting
it. If that does work, I will send a v2 tomorrow.
[1]: https://github.com/llvm/llvm-project/commit/5d8aaad4452f60ba8902e921d9bed606713a8f26
Cheers,
Nathan
On Thu, May 01, 2025 at 06:24:49PM -0700, Nathan Chancellor wrote:
> > How long has that been valid? Because this is certainly new to the
> > kernel, and sparse does complain about this initializer.
>
> As you noted, brace initialization for scalars appears to always be
> valid (at least in my testing) but as Al points out, empty braces for
> scalars is only supported in GCC 13+ and Clang 17+ (I think [1] was the
> clang commit), so that is not going to fly...
From some digging around it looks like
* {} for compounds had been an extension for quite a while
* C++11 got it into standard, with semantics defined as "same
value you get for static-duration variables of that type without an
explicit initializer". For scalar types as well, with the same
semantics.
* On C side that happened (again, with scalar types allowed)
in 2022; N2912 is the first draft with that change already merged,
N2913 is the corresponding editor's report, saying that change in question
(N2900) got merged in January/February virtual meeting.
IOW, C23 has it, no previous versions do. For C17 this syntax
is an error, and AFAICS you need at least -std=c2x or -std=gnu2x to have
it acceptable.
We can make sparse accept it (either unconditionally or with sufficient
-std in arguments), but that won't do a damn thing for cc(1). Does
clang (any version) really accept it with -std=gnu11?
On Fri, May 02, 2025 at 03:05:34AM +0100, Al Viro wrote:
> On Thu, May 01, 2025 at 06:24:49PM -0700, Nathan Chancellor wrote:
>
> > > How long has that been valid? Because this is certainly new to the
> > > kernel, and sparse does complain about this initializer.
> >
> > As you noted, brace initialization for scalars appears to always be
> > valid (at least in my testing) but as Al points out, empty braces for
> > scalars is only supported in GCC 13+ and Clang 17+ (I think [1] was the
> > clang commit), so that is not going to fly...
>
> From some digging around it looks like
> * {} for compounds had been an extension for quite a while
> * C++11 got it into standard, with semantics defined as "same
> value you get for static-duration variables of that type without an
> explicit initializer". For scalar types as well, with the same
> semantics.
> * On C side that happened (again, with scalar types allowed)
> in 2022; N2912 is the first draft with that change already merged,
> N2913 is the corresponding editor's report, saying that change in question
> (N2900) got merged in January/February virtual meeting.
> IOW, C23 has it, no previous versions do. For C17 this syntax
> is an error, and AFAICS you need at least -std=c2x or -std=gnu2x to have
> it acceptable.
Neat, thanks for digging around.
> We can make sparse accept it (either unconditionally or with sufficient
> -std in arguments), but that won't do a damn thing for cc(1). Does
> clang (any version) really accept it with -std=gnu11?
Yes, it appears that both GCC and clang accept it even with -std=gnu89:
https://godbolt.org/z/GYKrKhTdf
The clang commit mentions that this is exposed to older C modes like the
GNU extension was.
I guess another option to locally silence the warning would be to insert
something like
#if defined(__clang__) && __clang_major__ >= 21
#define typecheck_init = {}
#else
#define typecheck_init
#endif
#define typecheck(type,x) \
({ type __dummy typecheck_init; \
typeof(x) __dummy2 typecheck_init; \
(void)(&__dummy == &__dummy2); \
1; \
})
but maybe that is just too ugly or worthless.
Cheers,
Nathan
On Thu, 1 May 2025 at 18:24, Nathan Chancellor <nathan@kernel.org> wrote:
>
> but '= {0}' appears to work: https://godbolt.org/z/x7eae5vex
>
> If using that instead upsets sparse still, then I can just abandon this
> change and update the other patch to disable -Wdefault-const-init-unsafe
> altogether (
The "= { 0 }" form makes sparse unhappy for a different reason:
void *a = { 0 };
makes sparse (correctly) complain about the use of '0' for 'NULL'.
warning: Using plain integer as NULL pointer
and gcc has also finally adopted that warning for braindamage:
warning: zero as null pointer constant [-Wzero-as-null-pointer-constant]
although it's not on by default (and apparently we've never enabled it
for the kernel - although we really should).
sparse has complained about this since day one, because I personally
find the "plain 0 as NULL" to be a complete BS mistake in the language
(that came from avoiding a keyword, not from some "design" reason),
and while it took C++ people three decades to figure that out, in the
end they did indeed figure it out.
In case anybody wonders why '0' is so broken for NULL, think stdarg.
But also think "Christ people, it's fundamental type safety!!%^%!!"
Linus
On Thu, May 01, 2025 at 06:34:57PM -0700, Linus Torvalds wrote:
> On Thu, 1 May 2025 at 18:24, Nathan Chancellor <nathan@kernel.org> wrote:
> >
> > but '= {0}' appears to work: https://godbolt.org/z/x7eae5vex
> >
> > If using that instead upsets sparse still, then I can just abandon this
> > change and update the other patch to disable -Wdefault-const-init-unsafe
> > altogether (
>
> The "= { 0 }" form makes sparse unhappy for a different reason:
>
> void *a = { 0 };
>
> makes sparse (correctly) complain about the use of '0' for 'NULL'.
>
> warning: Using plain integer as NULL pointer
>
> and gcc has also finally adopted that warning for braindamage:
>
> warning: zero as null pointer constant [-Wzero-as-null-pointer-constant]
> although it's not on by default (and apparently we've never enabled it
> for the kernel - although we really should).
>
> sparse has complained about this since day one, because I personally
> find the "plain 0 as NULL" to be a complete BS mistake in the language
> (that came from avoiding a keyword, not from some "design" reason),
> and while it took C++ people three decades to figure that out, in the
> end they did indeed figure it out.
Yeah, that is all entirely reasonable. It does not really seem like
there is a clean way to deal with this with our matrix (aside from
something like a local __diag_push() sequence, which I understand you do
not like), so I will abandon this and just turn off the warning entirely
(unless folks have other ideas). I am not really sure we will miss it
because clang will still warn if the variable is used uninitialized
since -Wuninitialized is enabled in -Wall.
$ cat test.c
int main(void)
{
const int a, b;
return a;
}
$ clang -fsyntax-only test.c
test.c:3:15: warning: default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++ [-Wdefault-const-init-var-unsafe]
3 | const int a, b;
| ^
test.c:3:18: warning: default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++ [-Wdefault-const-init-var-unsafe]
3 | const int a, b;
| ^
2 warnings generated.
$ clang -fsyntax-only -Wuninitialized test.c
test.c:3:15: warning: default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++ [-Wdefault-const-init-var-unsafe]
3 | const int a, b;
| ^
test.c:3:18: warning: default initialization of an object of type 'const int' leaves the object uninitialized and is incompatible with C++ [-Wdefault-const-init-var-unsafe]
3 | const int a, b;
| ^
test.c:4:12: warning: variable 'a' is uninitialized when used here [-Wuninitialized]
4 | return a;
| ^
test.c:3:16: note: initialize the variable 'a' to silence this warning
3 | const int a, b;
| ^
| = 0
3 warnings generated.
Cheers,
Nathan
On Thu, May 01, 2025 at 04:28:25PM -0700, Linus Torvalds wrote:
> On Thu, 1 May 2025 at 16:00, Nathan Chancellor <nathan@kernel.org> wrote:
> >
> > +({ type __dummy = {}; \
> > + typeof(x) __dummy2 = {}; \
>
> I'm actually surprised that this doesn't cause warnings in itself.
>
> The types in question are not necessarily compound types, and can be
> simple types like 'int'.
>
> The fact that you can write
>
> int x = {};
>
> without the compiler screaming bloody murder about that insanity blows
> my mind, but it does seem to be valid C (*).
>
> How long has that been valid? Because this is certainly new to the
> kernel, and sparse does complain about this initializer.
>
> So honestly, this will just cause endless sparse warnings instead. I
> think disabling this warning for now is likely the right thing to do.
>
> Linus
>
> (*) Yes, the empty initializer is new in C23, but we've used that in
> the kernel for non-scalar objects for a long time.
For scalars it had been flat-out invalid all along - doesn't even
need -Wpedantic for gcc to reject that. I hadn't checked C23, but
older variants all fail on that.
We can force sparse to accept that thing, but I rather wonder if it's
a good idea. Both gcc 12 and clang 14 give hard error with -std=gnu11;
do we really want to bump the minimal versions that much?
On Thu, 1 May 2025 at 16:28, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> How long has that been valid? Because this is certainly new to the
> kernel, and sparse does complain about this initializer.
Sparse is clearly wrong.
I went back to my old K&R book, and the "perhaps in braces" languager
is there in that original (ok, so I only have the "newer" ANSI version
of K&R, so I'm not checking the _original_ original).
I guess we might as well ignore the sparse problem, since sparse ends
up having issues with so many other newer things we're doing, and we
don't have anybody maintaining it.
Linus
© 2016 - 2026 Red Hat, Inc.