Bug 3482 - Compilation fails with clang
Summary: Compilation fails with clang
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: Miscellaneous (show other bugs)
Version: 9.1p1
Hardware: amd64 Linux
: P5 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_9_2
  Show dependency treegraph
 
Reported: 2022-10-11 02:39 AEDT by Julien Bigot
Modified: 2023-03-17 13:42 AEDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Julien Bigot 2022-10-11 02:39:57 AEDT
This issue is similar to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98733 or https://bugs.llvm.org/show_bug.cgi?id=23562 

Clang fails to compile `bsd-asprintf.c` that's part of openssh. It seems to turn the `asprintf` symbol into a macro when using `-O2` `-D_FORTIFY_SOURCE=2` + `#include includes.h`.

More detail here: https://github.com/spack/spack/issues/33131

```
/opt/spack/lib/spack/env/clang/clang -g -O2 -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -D_FORTIFY_SOURCE=2 -ftrapv -fzero-call-used-regs=all -fno-builtin-memset -fstack-protector-strong   -fPIC -I. -I.. -I. -I./..  -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -I/opt/install/linux-ubuntu18.04-x86_64/clang-15.0.0/krb5-1.19.3-riaeukuk7bbucxf5gmp6jeoh2ubhkrul/include -I/opt/install/linux-ubuntu18.04-x86_64/clang-15.0.0/krb5-1.19.3-riaeukuk7bbucxf5gmp6jeoh2ubhkrul/include -DHAVE_CONFIG_H -c bsd-asprintf.c


bsd-asprintf.c:86:5: error: expected parameter declarator
int asprintf(char **str, const char *fmt, ...)
    ^
/usr/include/x86_64-linux-gnu/bits/stdio2.h:199:24: note: expanded from macro 'asprintf'
  __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, VA_ARGS)
                       ^
/usr/include/features.h:382:31: note: expanded from macro '__USE_FORTIFY_LEVEL'
#  define __USE_FORTIFY_LEVEL 2
                              ^
bsd-asprintf.c:86:5: error: expected ')'
/usr/include/x86_64-linux-gnu/bits/stdio2.h:199:24: note: expanded from macro 'asprintf'
  __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, VA_ARGS)
                       ^
/usr/include/features.h:382:31: note: expanded from macro '__USE_FORTIFY_LEVEL'
#  define __USE_FORTIFY_LEVEL 2
                              ^
bsd-asprintf.c:86:5: note: to match this '('
/usr/include/x86_64-linux-gnu/bits/stdio2.h:199:18: note: expanded from macro 'asprintf'
  __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, VA_ARGS)
                 ^
bsd-asprintf.c:86:5: error: conflicting types for '__asprintf_chk'
int asprintf(char **str, const char *fmt, ...)
    ^
/usr/include/x86_64-linux-gnu/bits/stdio2.h:199:3: note: expanded from macro 'asprintf'
  __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, VA_ARGS)
  ^
/usr/include/x86_64-linux-gnu/bits/stdio2.h:158:12: note: previous declaration is here
extern int __asprintf_chk (char **__restrict __ptr, int __flag,
           ^
bsd-asprintf.c:92:15: error: use of undeclared identifier 'fmt'
        va_start(ap, fmt);
                     ^
bsd-asprintf.c:93:23: error: use of undeclared identifier 'fmt'
        ret = vasprintf(str, fmt, ap);
                             ^
5 errors generated.
```
Comment 1 Damien Miller 2022-10-11 09:30:55 AEDT
This code should only be compiled when libc fails to provide asprintf(), which most modern ones do (inc. glibc). So the problem is more likely configure failing to detect its presence.

Can you search though config.log to see what went wrong?
Comment 2 Darren Tucker 2022-10-13 23:15:31 AEDT
The log in the referenced bug does in fact detect asprintf and set "#define HAVE_ASPRINTF 1" so that code should not even be compiled on that configuration:

configure:11975: /opt/spack/lib/spack/env/clang/clang -o conftest -g -O2 -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -D_FORTIFY_SOURCE=2 -ftrapv -fzero-call-used-regs=all -fno-builtin-memset -fstack-protector-strong -fPIE  -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE  -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -fstack-protector-strong -pie conftest.c -lutil -lz  >&5
conftest.c:151:18: warning: format string missing [-Wformat]
return asprintf ();
       ~~~~~~~~  ^
1 warning generated.
configure:11975: $? = 0
configure:11975: result: yes
[...]
| #define HAVE_ASPRINTF 1

I am also not able to reproduce on Fedora 36 with a locally built clang 15:

$ /opt/clang-15.0.1/bin/clang --version
clang version 15.0.1 (https://github.com/llvm/llvm-project.git b73d2c8c720a8c8e6e73b11be4e27afa6cb75bdf)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/clang-15.0.1/bin

Is something modifying config.h, or is it picking up a config.h from some other location?
Comment 3 Julien Bigot 2022-10-13 23:59:10 AEDT
Hi, I am not the expert of spack packaging of openssh. I only reported the issue there and the spack packager pointed me here as he considered the issue to be upstream.

The config.log is attached to the spack issue: https://github.com/spack/spack/files/9741543/config.log
in there, I see ac_cv_func_asprintf=yes

As you can see in this issue https://github.com/spack/spack/issues/33131 , I provided docker image you can use to reproduce the bug: ghcr.io/pdidev/test_env/builder:latest-clang-2e69267
In this image, you can just run:
```
spack -e pdienv add -l mpi openssh
spack -e pdienv install --show-log-on-error --fail-fast
```

I don't see why the config.h would be tampered with and looking at the spack openssh "recipe", https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/openssh/package.py I don't see anything pointing to it.
Comment 4 haampie 2022-10-14 00:50:02 AEDT
openssh undefs it here:

/*
 * Don't let systems with broken printf(3) avoid our replacements
 * via asprintf(3)/vasprintf(3) calling libc internally.
 */
#if defined(BROKEN_SNPRINTF)
# undef HAVE_VASPRINTF
# undef HAVE_ASPRINTF
#endif

given BROKEN_SNPRINTF=1 in the config.log.

And it seems like the relevant configure test is broken?

| #include <stdio.h>
| #include <stdlib.h>
| #include <string.h>
| #ifdef HAVE_SNPRINTF
| main()
| {
| 	char buf[50];
| 	char expected_out[50];
| 	int mazsize = 50 ;
| #if (SIZEOF_LONG_INT == 8)
| 	long int num = 0x7fffffffffffffff;
| #else
| 	long long num = 0x7fffffffffffffffll;
| #endif
| 	strcpy(expected_out, "9223372036854775807");
| 	snprintf(buf, mazsize, "%lld", num);
| 	if(strcmp(buf, expected_out) != 0)
| 		exit(1);
| 	exit(0);
| }
| #else
| main() { exit(0); }
| #endif

there's no `int main` and it errors with 

conftest.c:367:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int]
Comment 6 Darren Tucker 2022-10-14 07:58:07 AEDT
Applied https://github.com/openssh/openssh-portable/pull/349, thanks.
Comment 7 Damien Miller 2023-03-17 13:42:10 AEDT
OpenSSH 9.3 has been released. Close resolved bugs