[PATCH] D154696: [Clang] Diagnose jumps into statement expressions

Nathan Chancellor via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 22 10:38:22 PDT 2023


nathanchance added a comment.

The error added by this patch triggers on some recently added code to the Linux kernel's -next tree, which I failed to test above due to its generally unstable nature:

  drivers/gpu/drm/tests/drm_exec_test.c:41:3: error: cannot jump from this indirect goto statement to one of its possible targets
     41 |                 drm_exec_retry_on_contention(&exec);
        |                 ^
  include/drm/drm_exec.h:96:4: note: expanded from macro 'drm_exec_retry_on_contention'
     96 |                         goto *__drm_exec_retry_ptr;             \
        |                         ^
  drivers/gpu/drm/tests/drm_exec_test.c:39:2: note: possible target of indirect goto statement
     39 |         drm_exec_until_all_locked(&exec) {
        |         ^
  include/drm/drm_exec.h:79:33: note: expanded from macro 'drm_exec_until_all_locked'
     79 |                 __label__ __drm_exec_retry;                     \
        |                                                                 ^
  drivers/gpu/drm/tests/drm_exec_test.c:39:2: note: jump enters a statement expression

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/include/drm/drm_exec.h
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/tests/drm_exec_test.c

A standalone reproducer from the kernel sources:

  struct drm_exec {};
  int drm_exec_cleanup(struct drm_exec *);
  void drm_exec_fini(struct drm_exec *);
  void drm_exec_init(struct drm_exec *);
  int drm_exec_is_contended(struct drm_exec *);
  void drm_exec_lock_obj(struct drm_exec *);
  
  void test_lock(void)
  {
          struct drm_exec exec;
  
          drm_exec_init(&exec);
          for (void *__drm_exec_retry_ptr; ({
                       __label__ __drm_exec_retry;
       __drm_exec_retry:
                       __drm_exec_retry_ptr = &&__drm_exec_retry;
                       (void)__drm_exec_retry_ptr;
                       drm_exec_cleanup(&exec);
               });) {
                  drm_exec_lock_obj(&exec);
                  do {
                          if (__builtin_expect(!!(drm_exec_is_contended(&exec)),
                                               0))
                                  goto *__drm_exec_retry_ptr;
                  } while (0);
          }
          drm_exec_fini(&exec);
  }



  $ clang -fsyntax-only test.c
  test.c:24:5: error: cannot jump from this indirect goto statement to one of its possible targets
     24 |                                 goto *__drm_exec_retry_ptr;
        |                                 ^
  test.c:15:6: note: possible target of indirect goto statement
     15 |      __drm_exec_retry:
        |      ^
  test.c:13:35: note: jump enters a statement expression
     13 |         for (void *__drm_exec_retry_ptr; ({
        |                                          ^
  1 error generated.

I am not sure this is a problem with the patch, since if I am reading GCC's documentation on statement expressions correctly (https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html), the construct the kernel is using with labels as values to jump into a statement expression with a computed goto is undefined behavior, but I figured I would bring it up just in case there is a problem.

> Jumping into a statement expression with goto or using a switch statement outside the statement expression with a case or default label inside the statement expression is not permitted. Jumping into a statement expression with a computed goto (see Labels as Values) has undefined behavior.

If this is a problem on the kernel side, I can bring this up to them. GCC 13.1.0 at least does not error on this but if it is documented as UB, the construct should still be avoided.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154696/new/

https://reviews.llvm.org/D154696



More information about the cfe-commits mailing list