patches.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Deal with clang's -Wdefault-const-init-unsafe
@ 2025-05-01 23:00 Nathan Chancellor
  2025-05-01 23:00 ` [PATCH 1/2] kbuild: Disable -Wdefault-const-init-field-unsafe Nathan Chancellor
  2025-05-01 23:00 ` [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables Nathan Chancellor
  0 siblings, 2 replies; 13+ messages in thread
From: Nathan Chancellor @ 2025-05-01 23:00 UTC (permalink / raw)
  To: Andrew Morton, Masahiro Yamada
  Cc: Nicolas Schier, Andrew Morton, Nick Desaulniers, Bill Wendling,
	Justin Stitt, Linus Torvalds, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth,
	Nathan Chancellor

A new on by default warning in clang aims to flag cases where a const
variable or field is not initialized and has no default value (i.e., not
static or thread local). The field version of the warning triggers in
several places within the kernel that are not problematic so it is
disabled in the first patch. The variable version of the warning only
triggers in one place, the typecheck() macro, so I opted to silence it
in that one place to keep it enabled until it can be proved to be
problematic enough to disable it.

---
Nathan Chancellor (2):
      kbuild: Disable -Wdefault-const-init-field-unsafe
      include/linux/typecheck.h: Zero initialize dummy variables

 include/linux/typecheck.h  | 4 ++--
 scripts/Makefile.extrawarn | 7 +++++++
 2 files changed, 9 insertions(+), 2 deletions(-)
---
base-commit: ebd297a2affadb6f6f4d2e5d975c1eda18ac762d
change-id: 20250430-default-const-init-clang-b6e21b8d03b6

Best regards,
-- 
Nathan Chancellor <nathan@kernel.org>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/2] kbuild: Disable -Wdefault-const-init-field-unsafe
  2025-05-01 23:00 [PATCH 0/2] Deal with clang's -Wdefault-const-init-unsafe Nathan Chancellor
@ 2025-05-01 23:00 ` Nathan Chancellor
  2025-05-09 13:02   ` Masahiro Yamada
  2025-05-01 23:00 ` [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables Nathan Chancellor
  1 sibling, 1 reply; 13+ messages in thread
From: Nathan Chancellor @ 2025-05-01 23:00 UTC (permalink / raw)
  To: Andrew Morton, Masahiro Yamada
  Cc: Nicolas Schier, Andrew Morton, Nick Desaulniers, Bill Wendling,
	Justin Stitt, Linus Torvalds, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth,
	Nathan Chancellor

A new on by default warning in clang [1] flags several places within the
kernel where a const member of an aggregate type appears to be
uninitialized:

  include/linux/list.h:409:27: warning: default initialization of an object of type 'union (unnamed union at include/linux/list.h:409:27)' with const member leaves the object uninitialized and is incompatible with C++ [-Wdefault-const-init-field-unsafe]
    409 |         struct list_head *next = smp_load_acquire(&head->next);
        |                                  ^
  include/asm-generic/barrier.h:176:29: note: expanded from macro 'smp_load_acquire'
    176 | #define smp_load_acquire(p) __smp_load_acquire(p)
        |                             ^
  arch/arm64/include/asm/barrier.h:164:59: note: expanded from macro '__smp_load_acquire'
    164 |         union { __unqual_scalar_typeof(*p) __val; char __c[1]; } __u;   \
        |                                                                  ^
  include/linux/list.h:409:27: note: member '__val' declared 'const' here

  crypto/scatterwalk.c:66:22: error: default initialization of an object of type 'struct scatter_walk' with const member leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-field-unsafe]
     66 |         struct scatter_walk walk;
        |                             ^
  include/crypto/algapi.h:112:15: note: member 'addr' declared 'const' here
    112 |                 void *const addr;
        |                             ^

  fs/hugetlbfs/inode.c:733:24: error: default initialization of an object of type 'struct vm_area_struct' with const member leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-field-unsafe]
    733 |         struct vm_area_struct pseudo_vma;
        |                               ^
  include/linux/mm_types.h:803:20: note: member 'vm_flags' declared 'const' here
    803 |                 const vm_flags_t vm_flags;
        |                                  ^

In all audited cases, the members are either not used in the particular
call path, modified through other means such as memset() / memcpy()
because the containing object is not const, or are within a union with
other non-const members. Since these are technically false positives,
the warning was split out from its main group [2] to allow the kernel to
disable it while keeping the variable aspect of the warning enabled.

Cc: stable@vger.kernel.org
Link: https://github.com/llvm/llvm-project/commit/576161cb6069e2c7656a8ef530727a0f4aefff30 [1]
Link: https://github.com/llvm/llvm-project/commit/00f9ef282c7482754a0fea497417604d1deca9fa [2]
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>
---
 scripts/Makefile.extrawarn | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index d88acdf4085524b672c69fb75148ee87c30f88d8..b4d8265e587082687bc1d3de3fcc70e4a3f4f50d 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -37,6 +37,13 @@ KBUILD_CFLAGS += -Wno-gnu
 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111219
 KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow-non-kprintf)
 KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation-non-kprintf)
+
+# clang emits a warning when a const member of an aggregate type is not
+# initialized but there are several places in the kernel where this is
+# intentional because the field is never used within a particular call path,
+# the field is within a union with other non-const members, or the containing
+# object is not const so the field can be modified via memcpy() / memset().
+KBUILD_CFLAGS += $(call cc-disable-warning, default-const-init-field-unsafe)
 else
 
 # gcc inanely warns about local variables called 'main'

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-01 23:00 [PATCH 0/2] Deal with clang's -Wdefault-const-init-unsafe Nathan Chancellor
  2025-05-01 23:00 ` [PATCH 1/2] kbuild: Disable -Wdefault-const-init-field-unsafe Nathan Chancellor
@ 2025-05-01 23:00 ` Nathan Chancellor
  2025-05-01 23:28   ` Linus Torvalds
  2025-05-02  9:46   ` kernel test robot
  1 sibling, 2 replies; 13+ messages in thread
From: Nathan Chancellor @ 2025-05-01 23:00 UTC (permalink / raw)
  To: Andrew Morton, Masahiro Yamada
  Cc: Nicolas Schier, Andrew Morton, Nick Desaulniers, Bill Wendling,
	Justin Stitt, Linus Torvalds, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth,
	Nathan Chancellor

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


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-01 23:00 ` [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables Nathan Chancellor
@ 2025-05-01 23:28   ` Linus Torvalds
  2025-05-01 23:37     ` Linus Torvalds
                       ` (2 more replies)
  2025-05-02  9:46   ` kernel test robot
  1 sibling, 3 replies; 13+ messages in thread
From: Linus Torvalds @ 2025-05-01 23:28 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Andrew Morton, Masahiro Yamada, Nicolas Schier, Nick Desaulniers,
	Bill Wendling, Justin Stitt, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth

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.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-01 23:28   ` Linus Torvalds
@ 2025-05-01 23:37     ` Linus Torvalds
  2025-05-02  0:28     ` Al Viro
  2025-05-02  1:24     ` Nathan Chancellor
  2 siblings, 0 replies; 13+ messages in thread
From: Linus Torvalds @ 2025-05-01 23:37 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Andrew Morton, Masahiro Yamada, Nicolas Schier, Nick Desaulniers,
	Bill Wendling, Justin Stitt, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-01 23:28   ` Linus Torvalds
  2025-05-01 23:37     ` Linus Torvalds
@ 2025-05-02  0:28     ` Al Viro
  2025-05-02  1:24     ` Nathan Chancellor
  2 siblings, 0 replies; 13+ messages in thread
From: Al Viro @ 2025-05-02  0:28 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Nathan Chancellor, Andrew Morton, Masahiro Yamada, Nicolas Schier,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-kbuild,
	linux-kernel, llvm, patches, stable,
	Linux Kernel Functional Testing, Marcus Seyfarth

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?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-01 23:28   ` Linus Torvalds
  2025-05-01 23:37     ` Linus Torvalds
  2025-05-02  0:28     ` Al Viro
@ 2025-05-02  1:24     ` Nathan Chancellor
  2025-05-02  1:34       ` Linus Torvalds
  2025-05-02  2:05       ` Al Viro
  2 siblings, 2 replies; 13+ messages in thread
From: Nathan Chancellor @ 2025-05-02  1:24 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Masahiro Yamada, Nicolas Schier, Nick Desaulniers,
	Bill Wendling, Justin Stitt, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth,
	Al Viro

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-02  1:24     ` Nathan Chancellor
@ 2025-05-02  1:34       ` Linus Torvalds
  2025-05-02  2:09         ` Nathan Chancellor
  2025-05-02  2:05       ` Al Viro
  1 sibling, 1 reply; 13+ messages in thread
From: Linus Torvalds @ 2025-05-02  1:34 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Andrew Morton, Masahiro Yamada, Nicolas Schier, Nick Desaulniers,
	Bill Wendling, Justin Stitt, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth,
	Al Viro

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-02  1:24     ` Nathan Chancellor
  2025-05-02  1:34       ` Linus Torvalds
@ 2025-05-02  2:05       ` Al Viro
  2025-05-02  2:36         ` Nathan Chancellor
  1 sibling, 1 reply; 13+ messages in thread
From: Al Viro @ 2025-05-02  2:05 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Linus Torvalds, Andrew Morton, Masahiro Yamada, Nicolas Schier,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-kbuild,
	linux-kernel, llvm, patches, stable,
	Linux Kernel Functional Testing, Marcus Seyfarth

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?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-02  1:34       ` Linus Torvalds
@ 2025-05-02  2:09         ` Nathan Chancellor
  0 siblings, 0 replies; 13+ messages in thread
From: Nathan Chancellor @ 2025-05-02  2:09 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Masahiro Yamada, Nicolas Schier, Nick Desaulniers,
	Bill Wendling, Justin Stitt, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth,
	Al Viro

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-02  2:05       ` Al Viro
@ 2025-05-02  2:36         ` Nathan Chancellor
  0 siblings, 0 replies; 13+ messages in thread
From: Nathan Chancellor @ 2025-05-02  2:36 UTC (permalink / raw)
  To: Al Viro
  Cc: Linus Torvalds, Andrew Morton, Masahiro Yamada, Nicolas Schier,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-kbuild,
	linux-kernel, llvm, patches, stable,
	Linux Kernel Functional Testing, Marcus Seyfarth

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables
  2025-05-01 23:00 ` [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables Nathan Chancellor
  2025-05-01 23:28   ` Linus Torvalds
@ 2025-05-02  9:46   ` kernel test robot
  1 sibling, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-05-02  9:46 UTC (permalink / raw)
  To: Nathan Chancellor, Andrew Morton, Masahiro Yamada
  Cc: oe-kbuild-all, Linux Memory Management List, Nicolas Schier,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-kbuild,
	linux-kernel, llvm, patches, stable,
	Linux Kernel Functional Testing, Marcus Seyfarth,
	Nathan Chancellor

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] kbuild: Disable -Wdefault-const-init-field-unsafe
  2025-05-01 23:00 ` [PATCH 1/2] kbuild: Disable -Wdefault-const-init-field-unsafe Nathan Chancellor
@ 2025-05-09 13:02   ` Masahiro Yamada
  0 siblings, 0 replies; 13+ messages in thread
From: Masahiro Yamada @ 2025-05-09 13:02 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Andrew Morton, Nicolas Schier, Nick Desaulniers, Bill Wendling,
	Justin Stitt, Linus Torvalds, linux-kbuild, linux-kernel, llvm,
	patches, stable, Linux Kernel Functional Testing, Marcus Seyfarth

On Fri, May 2, 2025 at 8:00 AM Nathan Chancellor <nathan@kernel.org> wrote:
>
> A new on by default warning in clang [1] flags several places within the
> kernel where a const member of an aggregate type appears to be
> uninitialized:
>
>   include/linux/list.h:409:27: warning: default initialization of an object of type 'union (unnamed union at include/linux/list.h:409:27)' with const member leaves the object uninitialized and is incompatible with C++ [-Wdefault-const-init-field-unsafe]
>     409 |         struct list_head *next = smp_load_acquire(&head->next);
>         |                                  ^
>   include/asm-generic/barrier.h:176:29: note: expanded from macro 'smp_load_acquire'
>     176 | #define smp_load_acquire(p) __smp_load_acquire(p)
>         |                             ^
>   arch/arm64/include/asm/barrier.h:164:59: note: expanded from macro '__smp_load_acquire'
>     164 |         union { __unqual_scalar_typeof(*p) __val; char __c[1]; } __u;   \
>         |                                                                  ^
>   include/linux/list.h:409:27: note: member '__val' declared 'const' here
>
>   crypto/scatterwalk.c:66:22: error: default initialization of an object of type 'struct scatter_walk' with const member leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-field-unsafe]
>      66 |         struct scatter_walk walk;
>         |                             ^
>   include/crypto/algapi.h:112:15: note: member 'addr' declared 'const' here
>     112 |                 void *const addr;
>         |                             ^
>
>   fs/hugetlbfs/inode.c:733:24: error: default initialization of an object of type 'struct vm_area_struct' with const member leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-field-unsafe]
>     733 |         struct vm_area_struct pseudo_vma;
>         |                               ^
>   include/linux/mm_types.h:803:20: note: member 'vm_flags' declared 'const' here
>     803 |                 const vm_flags_t vm_flags;
>         |                                  ^
>
> In all audited cases, the members are either not used in the particular
> call path, modified through other means such as memset() / memcpy()
> because the containing object is not const, or are within a union with
> other non-const members. Since these are technically false positives,
> the warning was split out from its main group [2] to allow the kernel to
> disable it while keeping the variable aspect of the warning enabled.
>
> Cc: stable@vger.kernel.org
> Link: https://github.com/llvm/llvm-project/commit/576161cb6069e2c7656a8ef530727a0f4aefff30 [1]
> Link: https://github.com/llvm/llvm-project/commit/00f9ef282c7482754a0fea497417604d1deca9fa [2]
> 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>
> ---


Applied to linux-kbuild.
Thanks.

>  scripts/Makefile.extrawarn | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
> index d88acdf4085524b672c69fb75148ee87c30f88d8..b4d8265e587082687bc1d3de3fcc70e4a3f4f50d 100644
> --- a/scripts/Makefile.extrawarn
> +++ b/scripts/Makefile.extrawarn
> @@ -37,6 +37,13 @@ KBUILD_CFLAGS += -Wno-gnu
>  # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111219
>  KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow-non-kprintf)
>  KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation-non-kprintf)
> +
> +# clang emits a warning when a const member of an aggregate type is not
> +# initialized but there are several places in the kernel where this is
> +# intentional because the field is never used within a particular call path,
> +# the field is within a union with other non-const members, or the containing
> +# object is not const so the field can be modified via memcpy() / memset().
> +KBUILD_CFLAGS += $(call cc-disable-warning, default-const-init-field-unsafe)
>  else
>
>  # gcc inanely warns about local variables called 'main'
>
> --
> 2.49.0
>


-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2025-05-09 13:03 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-01 23:00 [PATCH 0/2] Deal with clang's -Wdefault-const-init-unsafe Nathan Chancellor
2025-05-01 23:00 ` [PATCH 1/2] kbuild: Disable -Wdefault-const-init-field-unsafe Nathan Chancellor
2025-05-09 13:02   ` Masahiro Yamada
2025-05-01 23:00 ` [PATCH 2/2] include/linux/typecheck.h: Zero initialize dummy variables Nathan Chancellor
2025-05-01 23:28   ` Linus Torvalds
2025-05-01 23:37     ` Linus Torvalds
2025-05-02  0:28     ` Al Viro
2025-05-02  1:24     ` Nathan Chancellor
2025-05-02  1:34       ` Linus Torvalds
2025-05-02  2:09         ` Nathan Chancellor
2025-05-02  2:05       ` Al Viro
2025-05-02  2:36         ` Nathan Chancellor
2025-05-02  9:46   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).