Re: autoconf: AC_SEARCH_LIBS with AC_LANG([C++]) broken when using gcc 8

Matthias Klose <[email protected]>
Newsgroups gmane.linux.debian.devel.gcc,gmane.comp.sysutils.autoconf.bugs
Message-ID <[email protected]>
On 12.01.19 21:37, Chaim Zax wrote:
> 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.

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.

> 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;
> }
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.