Project

General

Profile

Bug #3853

__cplusplus change and headers incompatibility with clang

Added by Alexander Pyhalov over 7 years ago. Updated over 2 years ago.

Status:
New
Priority:
Normal
Category:
lib - userland libraries
Start date:
2013-06-29
Due date:
% Done:

50%

Estimated time:
Difficulty:
Medium
Tags:
needs-triage
Gerrit CR:

Description

Clang++ fails to compile some programs (including clang itself) using g++ 4.7 c++ headers. The bug is caused by more strict rules then in g++.
Example error message is the following.

In file included from test1.cpp:2:
In file included from /usr/gcc/4.7/include/c++/4.7.3/cstdlib:66:
/usr/include/stdlib.h:52:12: error: target of using declaration 
conflicts with declaration already in scope
using std::atof;
^
/usr/include/iso/stdlib_iso.h:124:15: note: target of using declaration
extern double atof(const char *);
^
/usr/include/floatingpoint.h:204:15: note: conflicting declaration
extern double atof __P((const char *));
^
In file included from test1.cpp:2:
In file included from /usr/gcc/4.7/include/c++/4.7.3/cstdlib:66:
/usr/include/stdlib.h:71:12: error: target of using declaration 
conflicts with declaration already in scope
using std::strtod;
^
/usr/include/iso/stdlib_iso.h:157:15: note: target of using declaration
extern double strtod(const char *_RESTRICT_KYWD, char **_RESTRICT_KYWD);
^
/usr/include/floatingpoint.h:205:15: note: conflicting declaration
extern double strtod __P((const char *, char **));
^
In file included from test1.cpp:2:
/usr/gcc/4.7/include/c++/4.7.3/cstdlib:108:11: error: target of using 
declaration conflicts with declaration already in scope
using ::atof;
^
/usr/include/floatingpoint.h:204:15: note: target of using declaration
extern double atof __P((const char *));
^
/usr/include/iso/stdlib_iso.h:124:15: note: conflicting declaration
extern double atof(const char *);
^
In file included from test1.cpp:2:
/usr/gcc/4.7/include/c++/4.7.3/cstdlib:129:11: error: target of using 
declaration conflicts with declaration already in scope
using ::strtod;
^
/usr/include/floatingpoint.h:205:15: note: target of using declaration
extern double strtod __P((const char *, char **));
^
/usr/include/iso/stdlib_iso.h:157:15: note: conflicting declaration
extern double strtod(const char *_RESTRICT_KYWD, char **_RESTRICT_KYWD);
^

It is cased by atof,strtod and some other functions having the same declarations in std:: and global namespace.

So far, I've found that the following symbols in system headers are affected:
unistd.h: rename
malloc.h: malloc, free, realloc, calloc
floatingpoint.h: atof, strtod
sys/lc_core.h: struct tm;

The first three can be hitted by compiling clang with clang. The last one can be cause by any C++ program including sys/localedef.h .
The problem is that floatingpoint.h and lc_core.h are not in the gate, but comes from separate "closed bins". So I attach two patches: for the gate and for closed bins (we can apply it in distributions).
With these two patches applied clang (with some minor patches) can be built with clang and its test results are the same as for gcc build.


Files

closed_clang.patch (1.1 KB) closed_clang.patch Alexander Pyhalov, 2013-06-29 11:15 AM
illumos_clang.patch (1.21 KB) illumos_clang.patch Alexander Pyhalov, 2013-06-29 11:15 AM
closed_clang.patch (1.1 KB) closed_clang.patch Alexander Pyhalov, 2013-06-30 10:20 PM
illumos_clang.patch (1.21 KB) illumos_clang.patch Alexander Pyhalov, 2013-06-30 10:20 PM
closed_clang.patch (1.09 KB) closed_clang.patch Alexander Pyhalov, 2013-06-30 10:22 PM
illumos_clang.patch (1.35 KB) illumos_clang.patch Alexander Pyhalov, 2013-06-30 10:22 PM

History

#1

Updated by Andrew Stormont over 7 years ago

FYI floatingpoint.h is not closed, it's actually part of libm which is open-source but distributed separately from illumos-gate.

#2

Updated by Ian Collins over 7 years ago

No one should be using malloc.h any more, maybe just remove it?

#3

Updated by Alexander Pyhalov over 7 years ago

I'm not sure about "no one using" - at least during clang compilation it was used in some way. I can see it is used unconditionnaly in lib/ExecutionEngine/IntelJITEvents/jitprofiling.c and in tools/clang/test/SemaCXX/builtin-exception-spec.cpp test. However, in some other cases its use is conditional and depends on HAVE_MALLOC_H.

#4

Updated by Alexander Pyhalov over 7 years ago

Linux (glibc) still provides malloc.h. FreeBSD malloc.h errors out if STDC is defined. LLVM errors out if malloc.h is removed:
lib/Support/Unix/Process.inc:113:19: error: variable has incomplete type 'struct mallinfo'. Or do you propose to move it in stdlib.h or other header?

#5

Updated by Alexander Pyhalov over 7 years ago

One real issue was to reimport all declarations back to global namespace.

#6

Updated by Alexander Pyhalov over 7 years ago

Last time I've chosen old patches. Correcting...

#7

Updated by Albert Lee over 7 years ago

Some history:
malloc.h:
malloc, free, realloc, and calloc were declared by <malloc.h> in POSIX-1988 and the related XPG3 standard. We have K&R C style declarations as well, but the oldest standard we nominally support is XPG3. These predate ANSI and ISO C, which declare them in <stdlib.h>. Later X/Open and POSIX standards follow the C standard in this regard, and the <malloc.h> header is deprecated. However, it is also used for the system-specific mallopt and mallinfo functions.

Three major classes of programs still use <malloc.h>:
  1. Programs written for POSIX-1988, XPG3, or pre-ANSI C that consume malloc/free.
  2. Programs consuming mallopt or mallinfo.
  3. Programs written incorrectly that consume malloc/free.

The first case is detectable. The second case and third case are difficult to differentiate, unfortunately. GCC does us the disfavour of defining _POSIX_C_SOURCE by default so we cannot tell when POSIX support is explicitly requested.

We should endeavour to eliminate namespace pollution by hiding these declarations to support current POSIX standards. Unfortunately this will certainly break the third class of programs that still use them, and increase the amount of porting effort. It is probably outside the scope of this change. In order to not break these incorrectly written programs, the current guard around the malloc/free declarations retains them when visibility of XPG3 symbols is requested, which is currently true for newer POSIX versions as well. Thus, it is effectively a no-op until we drop XPG3 support.

unistd.h:
rename was formerly an extension to C in POSIX-1988 and XPG3 declared by <unistd.h>, and is declared by <stdio.h> in ANSI and ISO C and the subsequent X/Open and POSIX standards that use standard C. The <unistd.h> header is retained in current POSIX standards, but the declaration of rename has moved to <stdio.h>.

Previously existing guards require \\\\__EXTENSIONS__ to be defined or XPG3 support requested to make this declaration visible. However, requesting XPG4 (in our case, any standard based on XPG4 or later will have this effect) hides the declaration, thus eliminating namespace pollution.

We leave this behaviour unchanged.

#8

Updated by Yuri Pankov about 6 years ago

  • Subject changed from __cplusplus change and headers incompatipility with clang to __cplusplus change and headers incompatibility with clang

Also available in: Atom PDF