Subject: toolchain/20421: gcc -isystem flag with C++ breaks templates in system paths (especially STL)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <andrew.e.white@motorola.com>
List: netbsd-bugs
Date: 02/18/2003 20:11:14
>Number:         20421
>Category:       toolchain
>Synopsis:       gcc -isystem flag with C++ breaks templates in system paths (especially STL)
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 18 20:12:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Andrew White
>Release:        1.6
>Organization:
Motorola Australian Research Centre
>Environment:
NetBSD conan.testbed.arc.corp.mot.com. 1.5.2 NetBSD 1.5.2 (ARTHUR_RAID) #1: Mon Jul 22 18:06:13 EST 2002
>Description:
When compiling C++ code, using -isystem appears to implicitly 'extern "C"' any system header files.  As a result, any templates in these files fail with a 'template with C linkage' error.  This renders the entire STL useless.

This seems to be a known bug with some distributions of the GCC 2.95 compiler - see http://gcc.gnu.org/cgi-bin/gnatsweb.pl report #7327.

This problem is serious because the NetBSD build tool builds C++ as follows:

sys.mk:COMPILE.cc?=     ${CXX} ${CXXFLAGS} ${CPPFLAGS} -c

bsd.lib.mk:CPPFLAGS+=   ${DESTDIR:D-nostdinc ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include}
bsd.lib.mk:CXXFLAGS+=   ${DESTDIR:D-nostdinc++ ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include/g++}

bsd.own.mk:CPPFLAG_ISYSTEM=     -isystem
bsd.own.mk:CPPFLAG_ISYSTEM=     -idirafter

bsd.prog.mk:CPPFLAGS+=  ${DESTDIR:D-nostdinc ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include}
bsd.prog.mk:CXXFLAGS+=  ${DESTDIR:D-nostdinc++ ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include/g++}

Thus, all C++ code built using into the NetBSD system will be built with -nostdinc++ -isystem (path) -nostdinc -isystem (path), invoking the error if it uses the STL.
>How-To-Repeat:
In C++ program on 1.6 system:

#include <hash_map>
  // or any other STL header

Compile using

gcc -nostdinc++ -isystem /usr/include/g++ ...

Compiler will descend into STL headers before failing with 'template with C linkage' on each template found.
>Fix:
Attempted workaround by replacing -isystem (and -idirafter) with -I.  Problem is that -isystem seems to search recursively, so including

  -nostdinc -isystem /usr/include/

will trigger the same behaviour, even though relevant headers are in /usr/include/g++.  When building NetBSD from source, both -nostdinc and -nostdinc++ are included.

Replacing all instances of -isystem and -idirafter with -I works as a workaround.  However, see below.

Editing CPPFLAG_ISYSTEM = -I in bsd.own.mk will cause all code (C and C++) to be built with -I rather than -isystem, which is probably not desired.

Correct fix is to disable implicit 'extern' on -isystem.
>Release-Note:
>Audit-Trail:
>Unformatted: