[patch V2 2/6] kbuild: Disable asm goto on clang < 17

Thomas Gleixner posted 6 patches 2 weeks, 1 day ago
[patch V2 2/6] kbuild: Disable asm goto on clang < 17
Posted by Thomas Gleixner 2 weeks, 1 day ago
clang < 17 fails to use scope local labels with asm goto:

     {
     	__label__ local_lbl;
	...
	unsafe_get_user(uval, uaddr, local_lbl);
	...
	return 0;
	local_lbl:
		return -EFAULT;
     }

when two such scopes exist in the same function:

  error: cannot jump from this asm goto statement to one of its possible targets

That prevents using local labels for a cleanup based user access mechanism.

As there is no way to provide a simple test case for the 'depends on' test
in Kconfig, mark ASM goto broken on clang versions < 17 to get this road
block out of the way.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Nathan Chancellor <nathan@kernel.org>
---
V2: New patch
---
 init/Kconfig |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/init/Kconfig
+++ b/init/Kconfig
@@ -96,9 +96,14 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN
 	default y if GCC_VERSION >= 120000 && GCC_VERSION < 120400
 	default y if GCC_VERSION >= 130000 && GCC_VERSION < 130300
 
+config CLANG_ASM_GOTO_OUTPUT_BROKEN
+	bool
+	depends on CC_IS_CLANG
+	default y if CLANG_VERSION < 170000
+
 config CC_HAS_ASM_GOTO_OUTPUT
 	def_bool y
-	depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
+	depends on !GCC_ASM_GOTO_OUTPUT_BROKEN && !CLANG_ASM_GOTO_OUTPUT_BROKEN
 	depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
 
 config CC_HAS_ASM_GOTO_TIED_OUTPUT
Re: [patch V2 2/6] kbuild: Disable asm goto on clang < 17
Posted by Nathan Chancellor 2 weeks, 1 day ago
Hi Thomas,

First of all, sorry you got bit by this issue.

On Tue, Sep 16, 2025 at 06:33:11PM +0200, Thomas Gleixner wrote:
> clang < 17 fails to use scope local labels with asm goto:
> 
>      {
>      	__label__ local_lbl;
> 	...
> 	unsafe_get_user(uval, uaddr, local_lbl);
> 	...
> 	return 0;
> 	local_lbl:
> 		return -EFAULT;
>      }
> 
> when two such scopes exist in the same function:
> 
>   error: cannot jump from this asm goto statement to one of its possible targets

For the record, this is not specific to local labels, unique function
labels could trigger this error as well, as demonstrated by Nick's test
case:

https://github.com/ClangBuiltLinux/linux/issues/1886#issuecomment-1636342477

> That prevents using local labels for a cleanup based user access mechanism.

Indeed. This has only popped up a couple of times in the past couple of
years and each time it has been easy enough to work around by shuffling
the use of asm goto but as cleanup gets used in more places, this is
likely to cause problems.

> As there is no way to provide a simple test case for the 'depends on' test
> in Kconfig, mark ASM goto broken on clang versions < 17 to get this road
> block out of the way.

That being said, the commit title and message always references asm goto
in the general sense but this change only affects asm goto with outputs.
Is it sufficient to resolve the issues you were seeing? As far as I
understand it, the general issue can affect asm goto with or without
outputs but I assume x86 won't have any issues because the label is not
used in __get_user_asm when asm goto with outputs is not supported?

> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Nathan Chancellor <nathan@kernel.org>
> ---
> V2: New patch
> ---
>  init/Kconfig |    7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -96,9 +96,14 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN
>  	default y if GCC_VERSION >= 120000 && GCC_VERSION < 120400
>  	default y if GCC_VERSION >= 130000 && GCC_VERSION < 130300
>  
> +config CLANG_ASM_GOTO_OUTPUT_BROKEN
> +	bool
> +	depends on CC_IS_CLANG
> +	default y if CLANG_VERSION < 170000

Assuming this change sticks, please consider including links to the
original bug report and the fix in LLVM:

  https://github.com/ClangBuiltLinux/linux/issues/1886
  https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14

> +
>  config CC_HAS_ASM_GOTO_OUTPUT
>  	def_bool y
> -	depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
> +	depends on !GCC_ASM_GOTO_OUTPUT_BROKEN && !CLANG_ASM_GOTO_OUTPUT_BROKEN
>  	depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
>  
>  config CC_HAS_ASM_GOTO_TIED_OUTPUT
>
Re: [patch V2 2/6] kbuild: Disable asm goto on clang < 17
Posted by Thomas Gleixner 2 weeks, 1 day ago
Nathan!

On Tue, Sep 16 2025 at 11:44, Nathan Chancellor wrote:
> First of all, sorry you got bit by this issue.

The real annoying thing was that I could not makes sense of the error
messages and when I started shuffling code around for analysis it got
worse by failing reliably even with one instance or it exposed random
other incomprehensible errors which did not help analysis either.

Sh*t happens :)

> On Tue, Sep 16, 2025 at 06:33:11PM +0200, Thomas Gleixner wrote:
>> clang < 17 fails to use scope local labels with asm goto:
>> 
>>      {
>>      	__label__ local_lbl;
>> 	...
>> 	unsafe_get_user(uval, uaddr, local_lbl);
>> 	...
>> 	return 0;
>> 	local_lbl:
>> 		return -EFAULT;
>>      }
>> 
>> when two such scopes exist in the same function:
>> 
>>   error: cannot jump from this asm goto statement to one of its possible targets
>
> For the record, this is not specific to local labels, unique function
> labels could trigger this error as well, as demonstrated by Nick's test
> case:
>
> https://github.com/ClangBuiltLinux/linux/issues/1886#issuecomment-1636342477

Ah! I somehow failed to find this one.

I was actually trying to create a simple reproducer for using in the
depends on $(success,echo...) magic and could not manage.

The test case in the issue tracker is really helpful as it can be
condensed into the obfuscated C-code contest format required for
'depends on' checks. So we don't need the version number hack for
detecting it. That's definitely preferred as it catches potential
misbehaviour of later versions and of other compilers as well.

I'll send out a revised patch to that effect later.

>> That prevents using local labels for a cleanup based user access mechanism.
>
> Indeed. This has only popped up a couple of times in the past couple of
> years and each time it has been easy enough to work around by shuffling
> the use of asm goto but as cleanup gets used in more places, this is
> likely to cause problems.

Yes. I noticed that moving the label around or rearraning code slightly
makes it go away or even worse, but that's not a real solution :)

>> As there is no way to provide a simple test case for the 'depends on' test
>> in Kconfig, mark ASM goto broken on clang versions < 17 to get this road
>> block out of the way.
>
> That being said, the commit title and message always references asm goto
> in the general sense but this change only affects asm goto with
> outputs.

Right, that's misleading.

> Is it sufficient to resolve the issues you were seeing? As far as I
> understand it, the general issue can affect asm goto with or without
> outputs but I assume x86 won't have any issues because the label is not
> used in __get_user_asm when asm goto with outputs is not supported?

I haven't seen a problem with that yet. So yes, as things stand that
seems to be a ASM_GOTO_OUTPUT issue.

>> +config CLANG_ASM_GOTO_OUTPUT_BROKEN
>> +	bool
>> +	depends on CC_IS_CLANG
>> +	default y if CLANG_VERSION < 170000
>
> Assuming this change sticks, please consider including links to the
> original bug report and the fix in LLVM:
>
>   https://github.com/ClangBuiltLinux/linux/issues/1886
>   https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14

Sure! That's indeed useful.

Thanks,

        tglx
[patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Thomas Gleixner 2 weeks, 1 day ago
clang < 17 fails to use scope local labels with CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y:

     {
     	__label__ local_lbl;
	...
	unsafe_get_user(uval, uaddr, local_lbl);
	...
	return 0;
	local_lbl:
		return -EFAULT;
     }

when two such scopes exist in the same function:

  error: cannot jump from this asm goto statement to one of its possible targets

There are other failure scenarios. Shuffling code around slightly makes it
worse and fail even with one instance.

That issue prevents using local labels for a cleanup based user access
mechanism.

After failed attempts to provide a simple enough test case for the 'depends
on' test in Kconfig, the initial cure was to mark ASM goto broken on clang
versions < 17 to get this road block out of the way.

But Nathan pointed out that this is a known clang issue and indeed affects
clang < version 17 in combination with cleanup(). It's not even required to
use local labels for that.

The clang issue tracker has a small enough test case, which can be used as
a test in the 'depends on' section of CC_HAS_ASM_GOTO_OUTPUT:

void bar(void **);
void* baz();

int  foo (void) {
    {
	    asm goto("jmp %l0"::::l0);
	    return 0;
l0:
	    return 1;
    }
    void *x __attribute__((cleanup(bar))) = baz();
    {
	    asm goto("jmp %l0"::::l1);
	    return 42;
l1:
	    return 0xff;
    }
}

Add another dependency to config CC_HAS_ASM_GOTO_OUTPUT for it and use the
clang issue tracker test case for detection by condensing it to obfuscated
C-code contest format. This reliably catches the problem on clang < 17 and
did not show any issues on the non known to be broken GCC versions.

That test might be sufficient to catch all issues and therefore could
replace the existing test, but keeping that around does no harm either.

Thanks to Nathan for pointing to the relevant clang issue!

Suggested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Nathan Chancellor <nathan@kernel.org>
Link: https://github.com/ClangBuiltLinux/linux/issues/1886
Link: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14
---
V2a: Use the reproducer from llvm
V2: New patch
---
 init/Kconfig |    3 +++
 1 file changed, 3 insertions(+)

--- a/init/Kconfig
+++ b/init/Kconfig
@@ -99,7 +99,10 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN
 config CC_HAS_ASM_GOTO_OUTPUT
 	def_bool y
 	depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
+	# Find basic issues
 	depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
+	# Detect buggy clang, fixed in clang-17
+	depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)
 
 config CC_HAS_ASM_GOTO_TIED_OUTPUT
 	depends on CC_HAS_ASM_GOTO_OUTPUT
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Geert Uytterhoeven 3 days, 3 hours ago
Hi Thomas,

On Wed, 17 Sept 2025 at 07:51, Thomas Gleixner <tglx@linutronix.de> wrote:
> clang < 17 fails to use scope local labels with CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y:
>
>      {
>         __label__ local_lbl;
>         ...
>         unsafe_get_user(uval, uaddr, local_lbl);
>         ...
>         return 0;
>         local_lbl:
>                 return -EFAULT;
>      }
>
> when two such scopes exist in the same function:
>
>   error: cannot jump from this asm goto statement to one of its possible targets
>
> There are other failure scenarios. Shuffling code around slightly makes it
> worse and fail even with one instance.
>
> That issue prevents using local labels for a cleanup based user access
> mechanism.
>
> After failed attempts to provide a simple enough test case for the 'depends
> on' test in Kconfig, the initial cure was to mark ASM goto broken on clang
> versions < 17 to get this road block out of the way.
>
> But Nathan pointed out that this is a known clang issue and indeed affects
> clang < version 17 in combination with cleanup(). It's not even required to
> use local labels for that.
>
> The clang issue tracker has a small enough test case, which can be used as
> a test in the 'depends on' section of CC_HAS_ASM_GOTO_OUTPUT:
>
> void bar(void **);
> void* baz();
>
> int  foo (void) {
>     {
>             asm goto("jmp %l0"::::l0);
>             return 0;
> l0:
>             return 1;
>     }
>     void *x __attribute__((cleanup(bar))) = baz();
>     {
>             asm goto("jmp %l0"::::l1);
>             return 42;
> l1:
>             return 0xff;
>     }
> }
>
> Add another dependency to config CC_HAS_ASM_GOTO_OUTPUT for it and use the
> clang issue tracker test case for detection by condensing it to obfuscated
> C-code contest format. This reliably catches the problem on clang < 17 and
> did not show any issues on the non known to be broken GCC versions.
>
> That test might be sufficient to catch all issues and therefore could
> replace the existing test, but keeping that around does no harm either.
>
> Thanks to Nathan for pointing to the relevant clang issue!
>
> Suggested-by: Nathan Chancellor <nathan@kernel.org>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Link: https://github.com/ClangBuiltLinux/linux/issues/1886
> Link: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14

Thanks for your patch, which is now commit e2ffa15b9baa447e ("kbuild:
Disable CC_HAS_ASM_GOTO_OUTPUT on clang < 17") in v6.17.

> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -99,7 +99,10 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN
>  config CC_HAS_ASM_GOTO_OUTPUT
>         def_bool y
>         depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
> +       # Find basic issues
>         depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
> +       # Detect buggy clang, fixed in clang-17
> +       depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)

This is supposed to affect only clang builds, right?  I am using
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) to build for
arm32/arm64/riscv, and thus have:

    CONFIG_CC_IS_GCC=y

Still, this commit causes

    CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
    CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y

to disappear from my configs? Is that expected?

Thanks!

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Peter Zijlstra 3 days, 2 hours ago
On Mon, Sep 29, 2025 at 11:38:17AM +0200, Geert Uytterhoeven wrote:

> > +       # Detect buggy clang, fixed in clang-17
> > +       depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)
> 
> This is supposed to affect only clang builds, right?  I am using
> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) to build for
> arm32/arm64/riscv, and thus have:
> 
>     CONFIG_CC_IS_GCC=y
> 
> Still, this commit causes
> 
>     CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
>     CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
> 
> to disappear from my configs? Is that expected?

Not expected -- that means your GCC is somehow failing that test case.
Ideally some GCC person will investigate why this is so.
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Geert Uytterhoeven 3 days, 2 hours ago
On Mon, 29 Sept 2025 at 12:09, Peter Zijlstra <peterz@infradead.org> wrote:
> On Mon, Sep 29, 2025 at 11:38:17AM +0200, Geert Uytterhoeven wrote:
>
> > > +       # Detect buggy clang, fixed in clang-17
> > > +       depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)
> >
> > This is supposed to affect only clang builds, right?  I am using
> > gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) to build for
> > arm32/arm64/riscv, and thus have:
> >
> >     CONFIG_CC_IS_GCC=y
> >
> > Still, this commit causes
> >
> >     CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
> >     CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
> >
> > to disappear from my configs? Is that expected?
>
> Not expected -- that means your GCC is somehow failing that test case.
> Ideally some GCC person will investigate why this is so.

Oh, "jmp" is not a valid mnemonic on arm and riscv, and several other
architectures...

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Peter Zijlstra 3 days, 2 hours ago
On Mon, Sep 29, 2025 at 12:58:14PM +0200, Geert Uytterhoeven wrote:
> On Mon, 29 Sept 2025 at 12:09, Peter Zijlstra <peterz@infradead.org> wrote:
> > On Mon, Sep 29, 2025 at 11:38:17AM +0200, Geert Uytterhoeven wrote:
> >
> > > > +       # Detect buggy clang, fixed in clang-17
> > > > +       depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)
> > >
> > > This is supposed to affect only clang builds, right?  I am using
> > > gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) to build for
> > > arm32/arm64/riscv, and thus have:
> > >
> > >     CONFIG_CC_IS_GCC=y
> > >
> > > Still, this commit causes
> > >
> > >     CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
> > >     CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
> > >
> > > to disappear from my configs? Is that expected?
> >
> > Not expected -- that means your GCC is somehow failing that test case.
> > Ideally some GCC person will investigate why this is so.
> 
> Oh, "jmp" is not a valid mnemonic on arm and riscv, and several other
> architectures...

Ah, d'0h indeed.

void b(void **);void* c();int f(void){{asm goto(""::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto(""::::l1);return 2;l1:return 1;}}

Seems to still finger the issue on x86_64. That should build on !x86
too, right?
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Thomas Gleixner 2 days, 15 hours ago
On Mon, Sep 29 2025 at 13:04, Peter Zijlstra wrote:
> On Mon, Sep 29, 2025 at 12:58:14PM +0200, Geert Uytterhoeven wrote:
>> On Mon, 29 Sept 2025 at 12:09, Peter Zijlstra <peterz@infradead.org> wrote:
>> > On Mon, Sep 29, 2025 at 11:38:17AM +0200, Geert Uytterhoeven wrote:
>> >
>> > > > +       # Detect buggy clang, fixed in clang-17
>> > > > +       depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)
>> > >
>> > > This is supposed to affect only clang builds, right?  I am using
>> > > gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) to build for
>> > > arm32/arm64/riscv, and thus have:
>> > >
>> > >     CONFIG_CC_IS_GCC=y
>> > >
>> > > Still, this commit causes
>> > >
>> > >     CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
>> > >     CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
>> > >
>> > > to disappear from my configs? Is that expected?
>> >
>> > Not expected -- that means your GCC is somehow failing that test case.
>> > Ideally some GCC person will investigate why this is so.
>> 
>> Oh, "jmp" is not a valid mnemonic on arm and riscv, and several other
>> architectures...
>
> Ah, d'0h indeed.
>
> void b(void **);void* c();int f(void){{asm goto(""::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto(""::::l1);return 2;l1:return 1;}}
>
> Seems to still finger the issue on x86_64. That should build on !x86
> too, right?

Ooops.

Thanks for the quick fix!

       tglx
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Geert Uytterhoeven 3 days, 1 hour ago
Hoi Peter,

On Mon, 29 Sept 2025 at 13:04, Peter Zijlstra <peterz@infradead.org> wrote:
> On Mon, Sep 29, 2025 at 12:58:14PM +0200, Geert Uytterhoeven wrote:
> > On Mon, 29 Sept 2025 at 12:09, Peter Zijlstra <peterz@infradead.org> wrote:
> > > On Mon, Sep 29, 2025 at 11:38:17AM +0200, Geert Uytterhoeven wrote:
> > >
> > > > > +       # Detect buggy clang, fixed in clang-17
> > > > > +       depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)
> > > >
> > > > This is supposed to affect only clang builds, right?  I am using
> > > > gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) to build for
> > > > arm32/arm64/riscv, and thus have:
> > > >
> > > >     CONFIG_CC_IS_GCC=y
> > > >
> > > > Still, this commit causes
> > > >
> > > >     CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
> > > >     CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
> > > >
> > > > to disappear from my configs? Is that expected?
> > >
> > > Not expected -- that means your GCC is somehow failing that test case.
> > > Ideally some GCC person will investigate why this is so.
> >
> > Oh, "jmp" is not a valid mnemonic on arm and riscv, and several other
> > architectures...
>
> Ah, d'0h indeed.
>
> void b(void **);void* c();int f(void){{asm goto(""::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto(""::::l1);return 2;l1:return 1;}}
>
> Seems to still finger the issue on x86_64. That should build on !x86
> too, right?

Thanks, builds fine on arm32, arm64, riscv, m68k, powerpc, mips, s390.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Linus Torvalds 2 days, 21 hours ago
On Mon, 29 Sept 2025 at 04:10, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> >
> > Ah, d'0h indeed.
> >
> > void b(void **);void* c();int f(void){{asm goto(""::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto(""::::l1);return 2;l1:return 1;}}
> >
> > Seems to still finger the issue on x86_64. That should build on !x86
> > too, right?
>
> Thanks, builds fine on arm32, arm64, riscv, m68k, powerpc, mips, s390.

Ok, I just applied that fix directly. It's clearly not a fatal bug
since it just falls back on the non-optimal code, but it's one of
those "silly and subtle code generation issues" so I'd rather have it
fixed asap in the upstream kernel.

Geert, thanks for noticing.

             Linus
Re: [patch V2a 2/6] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < version 17
Posted by Nathan Chancellor 2 weeks, 1 day ago
On Tue, Sep 16, 2025 at 10:56:36PM +0200, Thomas Gleixner wrote:
> clang < 17 fails to use scope local labels with CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y:
> 
>      {
>      	__label__ local_lbl;
> 	...
> 	unsafe_get_user(uval, uaddr, local_lbl);
> 	...
> 	return 0;
> 	local_lbl:
> 		return -EFAULT;
>      }
> 
> when two such scopes exist in the same function:
> 
>   error: cannot jump from this asm goto statement to one of its possible targets
> 
> There are other failure scenarios. Shuffling code around slightly makes it
> worse and fail even with one instance.
> 
> That issue prevents using local labels for a cleanup based user access
> mechanism.
> 
> After failed attempts to provide a simple enough test case for the 'depends
> on' test in Kconfig, the initial cure was to mark ASM goto broken on clang
> versions < 17 to get this road block out of the way.
> 
> But Nathan pointed out that this is a known clang issue and indeed affects
> clang < version 17 in combination with cleanup(). It's not even required to
> use local labels for that.
> 
> The clang issue tracker has a small enough test case, which can be used as
> a test in the 'depends on' section of CC_HAS_ASM_GOTO_OUTPUT:
> 
> void bar(void **);
> void* baz();

I would recommend

  void* baz(void);

here and in the actual test to preemptively harden against the
possibility of a future where -Wstrict-prototypes is turned on as an
error by default (as unlikely as this may be, it has been brought up
before [1]), as I would not want this to get silently disabled.

> int  foo (void) {
>     {
> 	    asm goto("jmp %l0"::::l0);
> 	    return 0;
> l0:
> 	    return 1;
>     }
>     void *x __attribute__((cleanup(bar))) = baz();
>     {
> 	    asm goto("jmp %l0"::::l1);
> 	    return 42;
> l1:
> 	    return 0xff;
>     }
> }
> 
> Add another dependency to config CC_HAS_ASM_GOTO_OUTPUT for it and use the
> clang issue tracker test case for detection by condensing it to obfuscated
> C-code contest format. This reliably catches the problem on clang < 17 and
> did not show any issues on the non known to be broken GCC versions.
> 
> That test might be sufficient to catch all issues and therefore could
> replace the existing test, but keeping that around does no harm either.
> 
> Thanks to Nathan for pointing to the relevant clang issue!
> 
> Suggested-by: Nathan Chancellor <nathan@kernel.org>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Link: https://github.com/ClangBuiltLinux/linux/issues/1886
> Link: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14

Reviewed-by: Nathan Chancellor <nathan@kernel.org>

> ---
> V2a: Use the reproducer from llvm
> V2: New patch
> ---
>  init/Kconfig |    3 +++
>  1 file changed, 3 insertions(+)
> 
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -99,7 +99,10 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN
>  config CC_HAS_ASM_GOTO_OUTPUT
>  	def_bool y
>  	depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
> +	# Find basic issues

Maybe "Detect basic support" or something like that? This is not really
an "issues" test, more of a "does the compiler support it at all?" test
if I understand correctly.

>  	depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
> +	# Detect buggy clang, fixed in clang-17
> +	depends on $(success,echo 'void b(void **);void* c();int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b))) = c();{asm goto("jmp %l0"::::l1);return 2;l1:return 1;}}' | $(CC) -x c - -c -o /dev/null)
>  
>  config CC_HAS_ASM_GOTO_TIED_OUTPUT
>  	depends on CC_HAS_ASM_GOTO_OUTPUT
[tip: core/urgent] kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < 17
Posted by tip-bot2 for Thomas Gleixner 1 week, 1 day ago
The following commit has been merged into the core/urgent branch of tip:

Commit-ID:     e2ffa15b9baa447e444d654ffd47123ba6443ae4
Gitweb:        https://git.kernel.org/tip/e2ffa15b9baa447e444d654ffd47123ba6443ae4
Author:        Thomas Gleixner <tglx@linutronix.de>
AuthorDate:    Tue, 16 Sep 2025 15:21:51 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 24 Sep 2025 09:29:15 +02:00

kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < 17

clang < 17 fails to use scope local labels with CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y:

     {
     	__label__ local_lbl;
	...
	unsafe_get_user(uval, uaddr, local_lbl);
	...
	return 0;
	local_lbl:
		return -EFAULT;
     }

when two such scopes exist in the same function:

  error: cannot jump from this asm goto statement to one of its possible targets

There are other failure scenarios. Shuffling code around slightly makes it
worse and fail even with one instance.

That issue prevents using local labels for a cleanup based user access
mechanism.

After failed attempts to provide a simple enough test case for the 'depends
on' test in Kconfig, the initial cure was to mark ASM goto broken on clang
versions < 17 to get this road block out of the way.

But Nathan pointed out that this is a known clang issue and indeed affects
clang < version 17 in combination with cleanup(). It's not even required to
use local labels for that.

The clang issue tracker has a small enough test case, which can be used as
a test in the 'depends on' section of CC_HAS_ASM_GOTO_OUTPUT:

void bar(void **);
void* baz(void);

int  foo (void) {
    {
	    asm goto("jmp %l0"::::l0);
	    return 0;
l0:
	    return 1;
    }
    void *x __attribute__((cleanup(bar))) = baz();
    {
	    asm goto("jmp %l0"::::l1);
	    return 42;
l1:
	    return 0xff;
    }
}

Add another dependency to config CC_HAS_ASM_GOTO_OUTPUT for it and use the
clang issue tracker test case for detection by condensing it to obfuscated
C-code contest format. This reliably catches the problem on clang < 17 and
did not show any issues on the non broken GCC versions.

That test might be sufficient to catch all issues and therefore could
replace the existing test, but keeping that around does no harm either.

Thanks to Nathan for pointing to the relevant clang issue!

Suggested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Link: https://github.com/ClangBuiltLinux/linux/issues/1886
Link: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14
---
 init/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index e3eb63e..ecddb94 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -99,7 +99,10 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN
 config CC_HAS_ASM_GOTO_OUTPUT
 	def_bool y
 	depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
+	# Detect basic support
 	depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
+	# Detect clang (< v17) scoped label issues
+	depends on $(success,echo 'void b(void **);void* c(void);int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b)))=c();{asm goto("jmp %l0"::::l1);return 2;l1:return 3;}}' | $(CC) -x c - -c -o /dev/null)
 
 config CC_HAS_ASM_GOTO_TIED_OUTPUT
 	depends on CC_HAS_ASM_GOTO_OUTPUT