#907277 autoconf: AC_SEARCH_LIBS for __atomic_foo fails with AC_LANG([C++]) and g++-8

#907277#5
Date:
2018-08-25 19:56:51 UTC
From:
To:
Originally debugged by Amos Jeffries in #907106:

$ cat configure.ac
AC_INIT
AC_PROG_CXX
AC_LANG([C++])
AC_SEARCH_LIBS([__atomic_load_8],[atomic])
$ autoconf
$ CXX=g++-7 ./configure
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++-7 accepts -g... yes
checking for library containing __atomic_load_8... -latomic
$ CXX=g++-8 ./configure
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++-8 accepts -g... yes
checking for library containing __atomic_load_8... no
$


config.log says:

...
| #ifdef __cplusplus
| extern "C"
| #endif
| char __atomic_load_8 ();
| int
| main ()
| {
| return __atomic_load_8 ();
|   ;
|   return 0;
| }
configure:2326: g++-8 -o conftest -g -O2   conftest.cpp -latomic   >&5
conftest.cpp:16:6: error: new declaration 'char __atomic_load_8()' ambiguates built-in declaration 'long unsigned int __atomic_load_8(const volatile void*, int)' [-fpermissive]
 char __atomic_load_8 ();
      ^~~~~~~~~~~~~~~
conftest.cpp: In function 'int main()':
conftest.cpp:20:25: error: too few arguments to function 'long unsigned int __atomic_load_8(const volatile void*, int)'
 return __atomic_load_8 ();
                         ^
...

#907277#10
Date:
2019-01-12 20:37:26 UTC
From:
To:
Hi, autoconf developers, Debian gcc maintainers,

In Debian there is a bug [1] reported on the autoconf package which
relates to a change in gcc 8. After looking into the issue it's not
completely clear to me what the best solution should be.

The autoconf function AC_SEARCH_LIBS check the availability of a
specific library by generating and compiling a small c++ program. From
gcc version 8 on this seems to fail for some libraries (e.g. atomic),
but not all (we haven't seen major fallout so far).

To reproduce this issue the following configure.ac script can be used:

$ cat configure.ac
AC_INIT
AC_PROG_CXX
AC_LANG([C++])
AC_SEARCH_LIBS([__atomic_load_8],[atomic])

$ autoconf


When configured (build) with g++ 7 the result is correct, as expected:

$ CXX=g++-7 ./configure
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++-7 accepts -g... yes
checking for library containing __atomic_load_8... -latomic


But when configured (build) with g++ 8 the atomic library is not found:

$ CXX=g++-8 ./configure
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++-8 accepts -g... yes
checking for library containing __atomic_load_8... no


The c++ file generated is:

/* confdefs.h */
#define PACKAGE_NAME ""
#define PACKAGE_TARNAME ""
#define PACKAGE_VERSION ""
#define PACKAGE_STRING ""
#define PACKAGE_BUGREPORT ""
#define PACKAGE_URL ""
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char __atomic_load_8 ();
int
main ()
{
return __atomic_load_8 ();
  ;
  return 0;
}


When compiled with g++ 7 it only gives a warning, the function arguments
of '__atomic_load_8' are missing:

$ g++-7 -o conftest -g -O2   test.cpp -latomic
test.cpp:16:6: warning: new declaration ‘char __atomic_load_8()’
ambiguates built-in declaration ‘long unsigned int __atomic_load_8(const
volatile void*, int)’ [-Wbuiltin-declaration-mismatch]
 char __atomic_load_8 ();
      ^~~~~~~~~~~~~~~


When compiled with g++ 8 it fails with an compilation error, the missing
arguments are now resulting in an error:

$ g++-8 -o conftest -g -O2   test.cpp -latomic
test.cpp:16:6: error: new declaration ‘char __atomic_load_8()’
ambiguates built-in declaration ‘long unsigned int __atomic_load_8(const
volatile void*, int)’ [-fpermissive]
 char __atomic_load_8 ();
      ^~~~~~~~~~~~~~~
test.cpp: In function ‘int main()’:
test.cpp:20:25: error: too few arguments to function ‘long unsigned int
__atomic_load_8(const volatile void*, int)’
 return __atomic_load_8 ();


This error is interpreted by autoconf, which concludes the library is
not available. When the generated c++ file is changed to use a different
function from different library (e.g. the 'exp' function from 'libm')
the file [2] does compile with c++ 8.

$ g++-8 -o conftest -g -O2   exp.cpp -latomic
exp.cpp:16:6: warning: declaration of ‘char exp()’ conflicts with
built-in declaration ‘double exp(double)’ [-Wbuiltin-declaration-mismatch]
 char exp();
      ^~~


To know the impact of this bug on other Debian packages it's important
to know when g++ will produce an error, and when only a warning. We
suspect only the libraries provided by gcc itself seem to produce this
error (although we haven't investigated that further), otherwise it
would be likely lots of other Debian packages would produce this error
as well. Perhaps someone knows exactly when g++ triggers this error, and
possibly on which libraries? When updating autoconf it might be
interesting to know if there is a compilation flag to change this error
to a warning.

To fix this issue it's most likely autoconf itself that needs to be
updated as well. If this check only fails on libraries provided with g++
the usage of the AC_SEARCH_LIBS function is probably not needed at all
to check the availability on these libraries, Debian's package
dependencies will automatically make sure these libraries will be
available when autoconf is installed.

Because autoconf can be used outside a Debian environment this solution
might not work for everyone. Perhaps the AC_SEARCH_LIBS function should
be extended so function arguments needed to check a library could be
provided as well, or perhaps there is an other way to make it compatible
with g++ 8.

Regards,
Chaim Zax & Paul

p.s. I'm not an autoconf developer, currently working at the BSP in
Venlo (https://wiki.debian.org/BSP/2019/01/nl/Venlo)


[1] https://bugs.debian.org/907277

[2] contents of the exp.cpp file from above:

/* confdefs.h */
#define PACKAGE_NAME ""
#define PACKAGE_TARNAME ""
#define PACKAGE_VERSION ""
#define PACKAGE_STRING ""
#define PACKAGE_BUGREPORT ""
#define PACKAGE_URL ""
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char exp();
int
main ()
{
return exp();
  ;
  return 0;
}

#907277#15
Date:
2019-01-14 10:57:34 UTC
From:
To:
g++ 8 got more strict. You could check if that's the case for g++ 9 as well (or
gcc-snapshot).  In any case, autoconf should be adjusted to avoid the warning/error.

#907277#20
Date:
2019-01-17 13:53:24 UTC
From:
To:
Hi Doko,

Thanks for your reply.

Do you happen to know why g++ 8 happens to fail on this library and
doesn't fail on other libraries we checked? Does g++ know which
libraries it includes and is it pickier on those?

Paul

#907277#25
Date:
2019-01-17 16:00:40 UTC
From:
To:
appears to be specific to these __atomic_xyz builtins which seem
to get special treatment in g++.  Other builtins I tested do not
exhibit such failures.

There is no obvious way to disable the error in GCC: -fno-buitlin
appears not to affect these functions and -fpermissive does not resolve
the error at the call site.  AC_SEARCH_LIBS can present a simple
interface based on the assumption that correct declarations are not
required to test linking against a particular symbol in a library.

Clearly this assumption is not valid for these particular functions in
C++ mode, so it is likely that AC_SEARCH_LIBS simply cannot be used to
reliably probe for __atomic_xyz functions in libatomic.  In that case,
configure authors must use an alternate approach.  For example,

 - probing a different function from libatomic, if possible,
 - probing in C mode, if possible,
 - using AC_LINK_IFELSE with a valid test program, or
 - something else?

Cheers,
  Nick

#907277#30
Date:
2019-03-10 12:41:10 UTC
From:
To:
Control: retitle -1 autoconf: AC_SEARCH_LIBS for __atomic_foo fails with AC_LANG([C++]) and g++-8

Retitling to reflect the scope of the bug.

https://codesearch.debian.net/search?q=AC_SEARCH_LIBS.*__atomic says this
potentially affects:

* squid (#907106, which was already successfully worked around)

* users of openvswitch's OVS_CHECK_ATOMIC_LIBS (seems to be just
  openvswitch itself, which isn't C++ so isn't a problem)

* gnutls28 (isn't C++ so isn't a problem)

* users of gcc-7's phobos libraries.m4

That seems relatively infrequent, so perhaps this bug doesn't need to
be treated as release-critical?

Regards,
    smcv
    at the Cambridge BSP

#907277#37
Date:
2019-03-11 19:35:03 UTC
From:
To:
Hi all,

Does anybody know why gcc got more picky, but ONLY for __atomic_foo?

If it is only __atomic_foo that is failing, can't we special case that?
I.e. if testing for __atomic_foo, pass the test? Maybe only in Debian
and not upstream, albeit I rather have a generic solution, but then it
shouldn't be Debian pulling the boat.

Or is this a ridiculous proposal?

I fear that although this may have limited impact on packages in the
archive, I don't know how many private builds are impacted by this.

Paul

#907277#42
Date:
2019-04-05 10:29:44 UTC
From:
To:
Control: tags -1 buster-ignore

Tagging -ignore for buster.

Thanks,

Ivo