cf: Avoid nested C functions built by autoconf

Currently, two of the Linux-related autoconf macros try to compile code
containing nested C functions (AC_CHECK_LINUX_OPERATION and
LINUX_KMEM_CACHE_CREATE_CTOR_TAKES_VOID).  For example, the
AC_CHECK_LINUX_OPERATION check for 'follow_link' generates this code
where 'op' is a nested function inside 'conftest':

   #include <linux/module.h>
   #include <linux/fs.h>
   void conftest(void)
   {
       struct inode_operations ops;
       const char *op(struct dentry *dentry, void **link_date) {
           return (const char *)0;
       };
       ops.follow_link = op;
   }

Nested functions are a gcc-specific feature, and are not supported by
other compilers (e.g. clang), causing these checks to always fail when
using clang, leading to incorrect configure results.

To fix this, change AC_CHECK_LINUX_OPERATION and
LINUX_KMEM_CACHE_CREATE_CTOR_TAKES_VOID macros to just define the
relevant function as a proper top-level function.

(these were discovered by forcing a clang build of both the Linux kernel
and the openafs kernel module)

Change-Id: I1f5410d6702025d228b6ed80e7b86b9745ffe3dc
Reviewed-on: https://gerrit.openafs.org/14901
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
Cheyenne Wills 2022-02-17 18:27:02 -07:00 committed by Benjamin Kaduk
parent 573be02287
commit a4878a5e26
2 changed files with 7 additions and 3 deletions

View File

@ -178,7 +178,10 @@ AC_DEFUN([AC_CHECK_LINUX_OPERATION],
AC_CACHE_CHECK([operation $2 in $1], [ac_linux_operation],
[save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -Werror"
AC_TRY_KBUILD([$4], [struct $1 ops; $5 op($6) { return ($5)0; }; ops.$2 = op;],
AC_TRY_KBUILD(
[$4
$5 op($6) { return ($5)0; };],
[struct $1 ops; ops.$2 = op;],
AS_VAR_SET([ac_linux_operation], [yes]),
AS_VAR_SET([ac_linux_operation], [no]))
CPPFLAGS="$save_CPPFLAGS"

View File

@ -488,8 +488,9 @@ AC_DEFUN([LINUX_KMEM_CACHE_CREATE_TAKES_DTOR], [
AC_DEFUN([LINUX_KMEM_CACHE_CREATE_CTOR_TAKES_VOID],[
AC_CHECK_LINUX_BUILD([whether kmem_cache_create constructor takes a void pointer],
[ac_cv_linux_kmem_cache_create_ctor_takes_void],
[#include <linux/slab.h>],
[void _ctor(void *v) { }; kmem_cache_create(NULL, 0, 0, 0, _ctor);],
[#include <linux/slab.h>
void _ctor(void *v) { };],
[kmem_cache_create(NULL, 0, 0, 0, _ctor);],
[KMEM_CACHE_CTOR_TAKES_VOID],
[define if kmem_cache_create constructor takes a single void ptr],
[-Werror])