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

Reply via email to