[[gnu::nonnull(1, 2)]]
void *memcpy_bad(void *restrict dest, const void *restrict src, size_t
count)
{
    while (count--)
        ((char *)dest)[count] = ((const char *)src)[count];
    return dest;
}

__attribute__((nonnull(1, 2)))
void *memcpy_good(void *restrict dest, const void *restrict src, size_t
count)
{
    while (count--)
        ((char *)dest)[count] = ((const char *)src)[count];
    return dest;
}

/*
  global -f fails to report functions using [[gnu::nonnull(...)]]

  ENVIRONMENT: msys2 (ucrt64)

  global --version
  global (GNU Global) 6.6.14
  Powered by Berkeley DB 1.85.

  ctags --version
  Universal Ctags 6.2.1, Copyright (C) 2015-2025 Universal Ctags Team
  Universal Ctags is derived from Exuberant Ctags.
  Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Oct 25 2025, 21:43:59
  URL: https://ctags.io/
  Output version: 1.1
  Optional compiled features: +win32, +wildcards, +regex, +gnulib_regex,
+internal-sort, +unix-path-separator, +iconv, +option-directory, +xpath,
+json, +interactive, +yaml, +case-insensitive-filenames, +packcc,
+optscript, +pcre2

  cat ~/.globalrc
  default:\
          :tc=gtags@/msys64/ucrt64/share/gtags/gtags.conf:

  universal-ctags:\
          :ctagscom=/msys64/ucrt64/bin/ctags.exe:\
          :tc=universal-ctags@/msys64/ucrt64/share/gtags/gtags.conf:\
          :gtags_parser=rnc\:$ctagslib:\
          :langmap=rnc\:.rnc:

  REPRODUCER

  1. gtags --gtagslabel=universal-ctags -v
     ...

  2. global -f global-f_bug.c
     memcpy_good 10 global-f_bug.c void *memcpy_good(void *restrict
dest, const void *restrict src, size_t count)

     Note: memcpy_bad was not printed here!

  3. global -f global-f_bug.c -r
     memcpy_bad 2 global-f_bug.c void *memcpy_bad(void *restrict dest,
const void *restrict src, size_t count)

     Note: memcpy_bad is printed as a reference instead!

  4. gtags -d GTAGS
     __.COMPNAME     __.COMPNAME
     __.COMPRESS     __.COMPRESS ddefine ttypedef
     __.VERSION      __.VERSION 6
     memcpy_bad  1 @n 2 void *@n(void *restrict dest, const void
*restrict src, size_t count)
     memcpy_good 1 @n 10 void *@n(void *restrict dest, const void
*restrict src, size_t count)

     Note: Looks correct.

  5. gtags -d GRTAGS
     __.COMPACT      __.COMPACT
     __.COMPLINE     __.COMPLINE
     __.COMPNAME     __.COMPNAME
     __.VERSION      __.VERSION 6

     Note: Looks correct.

  6. ctags --output-format=json -o - global-f_bug.c
     {"_type": "tag", "name": "memcpy_bad",  "path": "global-f_bug.c",
"pattern": "/^void *memcpy_bad (void *restrict dest, const void
*restrict src, size_t count)$/", "typeref": "typename:void *", "kind":
"function"}
     {"_type": "tag", "name": "memcpy_good", "path": "global-f_bug.c",
"pattern": "/^void *memcpy_good(void *restrict dest, const void
*restrict src, size_t count)$/", "typeref": "typename:void *", "kind":
"function"}
 */
[[gnu::nonnull(1, 2)]]
void *memcpy_bad(void *restrict dest, const void *restrict src, size_t count)
{
    while (count--)
        ((char *)dest)[count] = ((const char *)src)[count];
    return dest;
}

__attribute__((nonnull(1, 2)))
void *memcpy_good(void *restrict dest, const void *restrict src, size_t count)
{
    while (count--)
        ((char *)dest)[count] = ((const char *)src)[count];
    return dest;
}

/*
  global -f fails to report functions using [[gnu::nonnull(...)]]

  ENVIRONMENT: msys2 (ucrt64)

  global --version
  global (GNU Global) 6.6.14
  Powered by Berkeley DB 1.85.

  ctags --version
  Universal Ctags 6.2.1, Copyright (C) 2015-2025 Universal Ctags Team
  Universal Ctags is derived from Exuberant Ctags.
  Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Oct 25 2025, 21:43:59
  URL: https://ctags.io/
  Output version: 1.1
  Optional compiled features: +win32, +wildcards, +regex, +gnulib_regex, 
+internal-sort, +unix-path-separator, +iconv, +option-directory, +xpath, +json, 
+interactive, +yaml, +case-insensitive-filenames, +packcc, +optscript, +pcre2

  cat ~/.globalrc
  default:\
          :tc=gtags@/msys64/ucrt64/share/gtags/gtags.conf:

  universal-ctags:\
          :ctagscom=/msys64/ucrt64/bin/ctags.exe:\
          :tc=universal-ctags@/msys64/ucrt64/share/gtags/gtags.conf:\
          :gtags_parser=rnc\:$ctagslib:\
          :langmap=rnc\:.rnc:

  REPRODUCER

  1. gtags --gtagslabel=universal-ctags -v
     ...

  2. global -f global-f_bug.c
     memcpy_good 10 global-f_bug.c void *memcpy_good(void *restrict dest, const 
void *restrict src, size_t count)

     Note: memcpy_bad was not printed here!

  3. global -f global-f_bug.c -r
     memcpy_bad 2 global-f_bug.c void *memcpy_bad(void *restrict dest, const 
void *restrict src, size_t count)

     Note: memcpy_bad is printed as a reference instead!

  4. gtags -d GTAGS
     __.COMPNAME     __.COMPNAME
     __.COMPRESS     __.COMPRESS ddefine ttypedef
     __.VERSION      __.VERSION 6
     memcpy_bad  1 @n 2 void *@n(void *restrict dest, const void *restrict src, 
size_t count)
     memcpy_good 1 @n 10 void *@n(void *restrict dest, const void *restrict 
src, size_t count)

     Note: Looks correct.

  5. gtags -d GRTAGS
     __.COMPACT      __.COMPACT
     __.COMPLINE     __.COMPLINE
     __.COMPNAME     __.COMPNAME
     __.VERSION      __.VERSION 6

     Note: Looks correct.

  6. ctags --output-format=json -o - global-f_bug.c
     {"_type": "tag", "name": "memcpy_bad",  "path": "global-f_bug.c", 
"pattern": "/^void *memcpy_bad (void *restrict dest, const void *restrict src, 
size_t count)$/", "typeref": "typename:void *", "kind": "function"}
     {"_type": "tag", "name": "memcpy_good", "path": "global-f_bug.c", 
"pattern": "/^void *memcpy_good(void *restrict dest, const void *restrict src, 
size_t count)$/", "typeref": "typename:void *", "kind": "function"}
 */

Reply via email to