nathanchance added subscribers: nickdesaulniers, nathanchance. nathanchance added a comment.
This patch breaks building the Linux kernel for PowerPC, which uses `asm goto` with a local label in a statement expression for the WARN macro. It seems like something with the scoping is going wrong. I have two reproducers. The first is manually reduced from the kernel sources: struct rb_node { unsigned long __rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } __attribute__((aligned(sizeof(long)))); struct rb_root { struct rb_node *rb_node; }; struct kernfs_elem_dir { struct rb_root children; }; struct kernfs_node { struct kernfs_elem_dir dir; unsigned short flags; }; enum kernfs_node_flag { KERNFS_ACTIVATED = 0x0010, KERNFS_NS = 0x0020, KERNFS_HAS_SEQ_SHOW = 0x0040, KERNFS_HAS_MMAP = 0x0080, KERNFS_LOCKDEP = 0x0100, KERNFS_HIDDEN = 0x0200, KERNFS_SUICIDAL = 0x0400, KERNFS_SUICIDED = 0x0800, KERNFS_EMPTY_DIR = 0x1000, KERNFS_HAS_RELEASE = 0x2000, KERNFS_REMOVING = 0x4000, }; enum kernfs_node_type { KERNFS_DIR = 0x0001, KERNFS_FILE = 0x0002, KERNFS_LINK = 0x0004, }; #define KERNFS_TYPE_MASK 0x000f struct bug_entry { signed int bug_addr_disp; signed int file_disp; unsigned short line; unsigned short flags; }; static enum kernfs_node_type kernfs_type(struct kernfs_node *kn) { return kn->flags & KERNFS_TYPE_MASK; } void kernfs_enable_ns(struct kernfs_node *kn) { ({ int __ret_warn_on = !!(kernfs_type(kn) != KERNFS_DIR); if (__builtin_expect(!!(__ret_warn_on), 0)) do { __label__ __label_warn_on; asm goto("1: " "twi 31, 0, 0" "\n" ".section __ex_table,\"a\";" " " ".balign 4;" " " ".long (1b) - . ;" " " ".long (%l[__label_warn_on]) - . ;" " " ".previous" " " ".section __bug_table,\"aw\"\n" "2: .4byte 1b - .\n" " .4byte %0 - .\n" " .short %1, %2\n" ".org 2b+%3\n" ".previous\n" : : "i"("include/linux/kernfs.h"), "i"(378), "i"((1 << 0) | ((1 << 1) | ((9) << 8))), "i"(sizeof(struct bug_entry)) : : __label_warn_on); do { } while (0); __builtin_unreachable(); __label_warn_on: break; } while (0); __builtin_expect(!!(__ret_warn_on), 0); }); ({ int __ret_warn_on = !!(!( ({ do { __attribute__(( __noreturn__)) extern void __compiletime_assert_244(void) __attribute__((__error__( "Unsupported access size for {READ,WRITE}_ONCE()."))); if (!((sizeof((&kn->dir.children) ->rb_node) == sizeof(char) || sizeof((&kn->dir.children) ->rb_node) == sizeof(short) || sizeof((&kn->dir.children) ->rb_node) == sizeof(int) || sizeof((&kn->dir.children) ->rb_node) == sizeof(long)) || sizeof((&kn->dir.children) ->rb_node) == sizeof(long long))) __compiletime_assert_244(); } while (0); (*(const volatile typeof(_Generic( ((&kn->dir.children)->rb_node), char: (char)0, unsigned char: (unsigned char)0, signed char: (signed char)0, unsigned short: (unsigned short)0, signed short: (signed short)0, unsigned int: (unsigned int)0, signed int: (signed int)0, unsigned long: (unsigned long)0, signed long: (signed long)0, unsigned long long: ( unsigned long long)0, signed long long: (signed long long)0, default: ((&kn->dir.children)->rb_node))) *)&((&kn->dir.children)->rb_node)); }) == ((void *)0))); if (__builtin_expect(!!(__ret_warn_on), 0)) do { __label__ __label_warn_on; asm goto("1: " "twi 31, 0, 0" "\n" ".section __ex_table,\"a\";" " " ".balign 4;" " " ".long (1b) - . ;" " " ".long (%l[__label_warn_on]) - . ;" " " ".previous" " " ".section __bug_table,\"aw\"\n" "2: .4byte 1b - .\n" " .4byte %0 - .\n" " .short %1, %2\n" ".org 2b+%3\n" ".previous\n" : : "i"("include/linux/kernfs.h"), "i"(379), "i"((1 << 0) | ((1 << 1) | ((9) << 8))), "i"(sizeof(struct bug_entry)) : : __label_warn_on); do { } while (0); __builtin_unreachable(); __label_warn_on: break; } while (0); __builtin_expect(!!(__ret_warn_on), 0); }); kn->flags |= KERNFS_NS; } $ ../install/llvm-good/bin/clang --target=powerpc64le-linux-gnu -c -o /dev/null test.c test.c:93:3: warning: ignoring return value of function declared with const attribute [-Wunused-value] 93 | __builtin_expect(!!(__ret_warn_on), 0); | ^~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ test.c:174:3: warning: ignoring return value of function declared with const attribute [-Wunused-value] 174 | __builtin_expect(!!(__ret_warn_on), 0); | ^~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ 2 warnings generated. $ ../install/llvm-bad/bin/clang --target=powerpc64le-linux-gnu -c -o /dev/null test.c test.c:93:3: warning: ignoring return value of function declared with const attribute [-Wunused-value] 93 | __builtin_expect(!!(__ret_warn_on), 0); | ^~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ test.c:174:3: warning: ignoring return value of function declared with const attribute [-Wunused-value] 174 | __builtin_expect(!!(__ret_warn_on), 0); | ^~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ test.c:60:5: error: cannot jump from this asm goto statement to one of its possible targets 60 | asm goto("1: " | ^ test.c:171:1: note: possible target of asm goto statement 171 | __label_warn_on: | ^ test.c:95:2: note: jump enters a statement expression 95 | ({ | ^ test.c:141:5: error: cannot jump from this asm goto statement to one of its possible targets 141 | asm goto("1: " | ^ test.c:90:1: note: possible target of asm goto statement 90 | __label_warn_on: | ^ test.c:55:2: note: jump enters a statement expression 55 | ({ | ^ 2 warnings and 2 errors generated. The second is a simpler one from `cvise`, which should convey the same idea. void kernfs_enable_ns() { ({ __label__ __label_warn_on; asm goto("" : : : : __label_warn_on); __label_warn_on:; }); ({ __label__ __label_warn_on; asm goto("" : : : : __label_warn_on); __label_warn_on:; }); } $ ../install/llvm-good/bin/clang -c -o /dev/null asm-offsets.i $ ../install/llvm-bad/bin/clang -c -o /dev/null asm-offsets.i asm-offsets.i:4:5: error: cannot jump from this asm goto statement to one of its possible targets 4 | asm goto("" : : : : __label_warn_on); | ^ asm-offsets.i:11:1: note: possible target of asm goto statement 11 | __label_warn_on:; | ^ asm-offsets.i:8:3: note: jump enters a statement expression 8 | ({ | ^ asm-offsets.i:10:5: error: cannot jump from this asm goto statement to one of its possible targets 10 | asm goto("" : : : : __label_warn_on); | ^ asm-offsets.i:5:1: note: possible target of asm goto statement 5 | __label_warn_on:; | ^ asm-offsets.i:2:3: note: jump enters a statement expression 2 | ({ | ^ 2 errors generated. GCC 13.1.0 has no issues with either of these test cases. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154696/new/ https://reviews.llvm.org/D154696 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits