From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michael Elizabeth Chastain To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org Subject: Re: libstdc++/2445: undefined reference to `std::errno' Date: Sun, 15 Apr 2001 00:26:00 -0000 Message-id: <20010415072600.31914.qmail@sourceware.cygnus.com> X-SW-Source: 2001-04/msg00272.html List-Id: The following reply was made to PR libstdc++/2445; it has been noted by GNATS. From: Michael Elizabeth Chastain To: gcc-gnats@gcc.gnu.org Cc: Subject: Re: libstdc++/2445: undefined reference to `std::errno' Date: Sun, 15 Apr 2001 00:19:04 -0700 I did some more analysis on this bug. It looks like a thorny C++ standards issue that revolves around this line of code: namespace std { extern "C" int errno; } I'm not an expert at this so I welcome corrections cheerfully. Also, I haven't followed the prior discussion in the gcc mailing lists, so some of this might be obvious or redundant. === Here is another test program. This program is a boiled-down and re-arranged version of libstdc++-v3/src/locale-inst.cc. extern "C" { extern int errno; } namespace std { extern "C" int errno; } namespace std { template class num_get { protected: virtual void do_get() const; }; } namespace std { template void num_get<_CharT>:: do_get() const { errno = 0; } template class num_get; } === My configuration is native sparc-sun-solaris2.6. Here's a script of the g++ invocation: Script started on Sat Apr 14 23:06:21 2001 [chastain@delta tmp]$ g++ -v -S y2.cc Reading specs from /horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install/lib/gcc-lib/sparc-sun-solaris2.6/3.0/specs Configured with: /horton/chastain/fsf/2001-03-20-14-05-00/source/configure --prefix=/horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install --disable-shared : (reconfigured) gcc version 3.0 20010320 (prerelease) /horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install/lib/gcc-lib/sparc-sun-solaris2.6/3.0/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNUC_PATCHLEVEL__=0 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix -Asystem=unix -Asystem=svr4 -D__STDC_HOSTED__=1 -D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc y2.cc -D__GNUG__=3 -D_GNU_SOURCE -D__EXCEPTIONS -D__GXX_ABI_VERSION=100 -quiet -dumpbase y2.cc -version -o y2.s GNU CPP version 3.0 20010320 (prerelease) (cpplib) (sparc) GNU C++ version 3.0 20010320 (prerelease) (sparc-sun-solaris2.6) compiled by GNU C version 2.9-gnupro-99r1. #include "..." search starts here: #include <...> search starts here: /horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install/include/g++-v3 /horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install/include/g++-v3/sparc-sun-solaris2.6 /horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install/include /horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install/lib/gcc-lib/sparc-sun-solaris2.6/3.0/include /horton/chastain/fsf/2001-03-20-14-05-00/delta/native/install/sparc-sun-solaris2.6/include /usr/include End of search list. [chastain@delta tmp]$ exit script done on Sat Apr 14 23:06:33 2001 And here's the generated assembly code: .file "y2.cc" gcc2_compiled.: .section ".gnu.linkonce.t._ZNKSt7num_getIcE6do_getEv",#alloc,#execinstr .align 4 .weak _ZNKSt7num_getIcE6do_getEv .type _ZNKSt7num_getIcE6do_getEv,#function .proc 020 _ZNKSt7num_getIcE6do_getEv: .LLFB1: !#PROLOGUE# 0 save %sp, -120, %sp .LLCFI0: !#PROLOGUE# 1 sethi %hi(_ZSt5errno), %i0 or %i0, %lo(_ZSt5errno), %i0 st %g0, [%i0] ret restore .LLFE1: .LLfe1: .size _ZNKSt7num_getIcE6do_getEv,.LLfe1-_ZNKSt7num_getIcE6do_getEv .weak _ZTVSt7num_getIcE .section ".gnu.linkonce.d._ZTVSt7num_getIcE",#alloc,#write .align 8 .type _ZTVSt7num_getIcE,#object .size _ZTVSt7num_getIcE,16 _ZTVSt7num_getIcE: .uaword 0 .uaword _ZTISt7num_getIcE .uaword _ZNKSt7num_getIcE6do_getEv .skip 4 .weak _ZTSSt7num_getIcE .section ".gnu.linkonce.r._ZTSSt7num_getIcE",#alloc .align 8 .type _ZTSSt7num_getIcE,#object .size _ZTSSt7num_getIcE,14 _ZTSSt7num_getIcE: .asciz "St7num_getIcE" .weak _ZTISt7num_getIcE .section ".gnu.linkonce.d._ZTISt7num_getIcE",#alloc,#write .align 4 .type _ZTISt7num_getIcE,#object .size _ZTISt7num_getIcE,8 _ZTISt7num_getIcE: .uaword _ZTVN10__cxxabiv117__class_type_infoE+8 .uaword _ZTSSt7num_getIcE .ident "GCC: (GNU) 3.0 20010320 (prerelease)" Note that the symbol "errno" has compiled to "_ZSt5errno", a mangled form of "std:errno". This eventually leads to errors of the form "undefined reference to `std::errno'" in the library function locale-inst.o. === See also these related messages: (recent breakage) http://gcc.gnu.org/ml/gcc-bugs/2001-04/msg00239.html http://gcc.gnu.org/ml/gcc-bugs/2001-04/msg00259.html http://gcc.gnu.org/ml/gcc-bugs/2001-03/msg00798.html (related work from Oct 2000) http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00155.html === IMHO there are two possibilities: . The compiler is translating the test program correctly; include/c_std/bits/std_cerrno.h is at fault for declaring "std:errno". . The library source code is correct; the compiler is at fault and a compiler change needs to be reverted. I am not a C++ language lawyer, but I favor the second alternative. The mailing list thread from Oct 2000 also takes this position. I cite Stroustrup, _The C++ Programming Language_, 3rd edition: 9.2.4 Linkage to Non-C++ Code ... A name with C linkage can be declared in a namespace. The namespace will affect the way the name is accessed in the C++ program, but not the way a linker sees it. The printf() from std is a typical example: #include void f() { std::printf("Hello, "); // ok printf("world!\n"); // error: no global prinf() } Even when called std::printf, it is still the same old C printf() (#21.8). I also cite ISO/IEC 14882, section 7.5 paragraph 6: Two declarations for an object with C language linkage with the same name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same object. === On native Linux, errno is a macro: define errno (*__errno_location ()) "extern "C"" is in effect for all of the underlying names. Given the function name "__errno_location", g++ generates an unmangled name. But given the variable name "errno", g++ generates a mangled name. If I compile the test program above with a Linux native compiler, it mangles the "errno" data symbol the same way as the Solaris compiler. It's just that on Linux, the compiler does not see an "errno" data symbol in the first place. === I date-searched the gcc sources and found the responsible patch. The last compiler that emits "errno" is: cvs -z 9 co -r gcc-3_0-branch -D "2001-03-20 14:00:00 PST" gcc The first compiler that emits "_ZSt5errno" is: cvs -z 9 co -r gcc-3_0-branch -D "2001-03-20 14:05:00 PST" gcc (Note that I executed these commands on a machine in the PST time zone -- I don't know if cvs handles the time zones correctly). The diff between these versions is 1600 lines long. Here are the ChangeLog entries: diff -u -r -N 2001-03-20-14-00-00/source/gcc/ChangeLog 2001-03-20-14-05-00/source/gcc/ChangeLog --- 2001-03-20-14-00-00/source/gcc/ChangeLog Tue Mar 20 12:11:43 2001 +++ 2001-03-20-14-05-00/source/gcc/ChangeLog Tue Mar 20 14:03:29 2001 @@ -1,3 +1,37 @@ +2001-03-20 Mark Mitchell + + * tree.c (set_decl_assembler_name): Set DECL_ASSEMBLER_NAME for + variables that are TREE_PUBLIC, even if not TREE_STATIC. + +2001-03-19 Mark Mitchell + + Compute DECL_ASSEMBLER_NAME lazily. + * tree.h (DECL_ASSEMBLER_NAME): Compute it lazily. + (DECL_ASSEMBLER_NAME_SET_P): New macro. + (SET_DECL_ASSEMBLER_NAME): Likewise. + (COPY_DECL_ASSEMBLER_NAME): Likewise. + (set_decl_assembler_name): Declare. + (lang_set_decl_assembler_name): Likewise. + * tree.c (lang_set_decl_assembler_name): New variab.e + (set_decl_assembler_name): New function. + (init_obstacks): Set lang_set_decl_assembler_name. + (build_decl): Don't set DECL_ASSEMBLER_NAME. + * c-decl.c (duplicate_decls): Use SET_DECL_ASSEMBLER_NAME, + COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME + where it's not necessary. + (builtin_function): Likewise. + (finish_decl): Likewise. + * dbxout.c (dbxout_type_methods): Likewise. + * ggc-common.c (ggc_mark_trees): Likewise. + * profile.c (output_func_start_profiler): Likewise. + * varasm.c (make_decl_rtl): Likewise. + + * cse.c (find_comparison_args): Update documentation. Fix + mishandling of COMPARE operations. + + * tree.def (ABS_EXPR): Add documentation. + * fold-const.c (fold): Improve folding of ABS_EXPRs. + 2001-03-20 Tom Tromey * libgcc-std.ver: Added __fixunssfsi and __fixunsdfsi. diff -u -r -N 2001-03-20-14-00-00/source/gcc/cp/ChangeLog 2001-03-20-14-05-00/source/gcc/cp/ChangeLog --- 2001-03-20-14-00-00/source/gcc/cp/ChangeLog Thu Mar 15 11:29:22 2001 +++ 2001-03-20-14-05-00/source/gcc/cp/ChangeLog Tue Mar 20 14:03:35 2001 @@ -1,3 +1,65 @@ +2001-03-19 Mark Mitchell + + * class.c (get_vtable_decl): Use SET_DECL_ASSEMBLER_NAME, + COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME + where it's not necessary. + (add_method): Remove optimization involving comparison of + DECL_ASSEMBLER_NAME. + (build_vtbl_or_vbase_field): Use SET_DECL_ASSEMBLER_NAME, + COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME + where it's not necessary. + (check_methods): Likewise. + (build_clone): Likewise. + (built_vtt): Likewise. + * cp-tree.h (DECL_NEEDED_P): Likewise. + * decl.c (pushtag): Likewise. + (duplicate_decls): Likewise. + (pushdecl): Likewise. + (builtin_function): Likewise. + (build_library_fn_1): Set DECL_LANGUAGE for library functions. + (build_cp_library_fn): Likewise. + (maybe_commonize_var): Use SET_DECL_ASSEMBLER_NAME, + COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME + where it's not necessary. + (make_rtl_for_nonlocal_decl): Likewise. + (cp_finish_decl): Likewise. + (grokfndecl): Likewise. + (grokvardecl): Likewise. + (grokdeclarator): Likewise. + (start_function): Likewise. + (cp_missing_return_ok_p): Likewise. + * decl2.c (grokclassfn): Likewise. + (check_classfn): Likewise. + (finish_static_data_member_decl): Likewise. + (grokfield): Likewise. + * error.c (GLOBAL_IORD_P): Remove. + (dump_global_iord): Improve output. + (dump_decl): Avoid using DECL_ASSEMBLER_NAME. + * except.c (nothrow_libfn_p): Summarily reject any function not in + namespace-scope. + * init.c (build_java_class_ref): Don't explicitly set + DECL_ASSEMBLER_NAME after calling mangle_decl. + * mangle.c (mangle_decl_string): Handle extern "C" functions. + (mangle_decl): Set the DECL_ASSEMBLER_NAME for the decl. + * method.c (set_mangled_name_for_decl): Don't explicitly set + DECL_ASSEMBLER_NAME after calling mangle_decl. + (make_thunk): Explicitly set the DECL_ASSEMBLER_NAME and + IDENTIFIER_GLOBAL_VALUE for the thunk. + * pt.c (set_mangled_name_for_template_decl): Remove. + (check_explicit_specialization): Don't use it. + (looup_template_class): Don't set DECL_ASSEMBLER_NAME. + (tsubst_friend_function): Likewise. + (tsubst_decl): Likewise. + (regenerate_decl_from_template): Use COPY_DECL_ASSEMBLER_NAME. + * rtti.c (get_tinfo_decl): Use SET_DECL_ASSEMBLER_NAME, + COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME + where it's not necessary. + (tinfo_base_init): Likewise. + (create_real_tinfo_var): Likewise. + * search.c (looup_field_1): Likewise. + * semantics.c (finish_named_return_value): Likewise. + * tree.c (init_tree): Set lang_set_decl_assembler_name. + 2001-03-15 Neil Booth * lex.c: Delete duplicate pending_lang_change. diff -u -r -N 2001-03-20-14-00-00/source/gcc/f/ChangeLog 2001-03-20-14-05-00/source/gcc/f/ChangeLog --- 2001-03-20-14-00-00/source/gcc/f/ChangeLog Thu Mar 15 11:02:09 2001 +++ 2001-03-20-14-05-00/source/gcc/f/ChangeLog Tue Mar 20 14:03:48 2001 @@ -1,3 +1,7 @@ +Mon Mar 19 15:05:39 2001 Mark Mitchell + + * com.c (builtin_function): Use SET_DECL_ASSEMBLER_NAME. + 2001-03-15 Zack Weinberg * proj.h, intdoc.c: Delete 'bool' type. Don't include diff -u -r -N 2001-03-20-14-00-00/source/gcc/java/ChangeLog 2001-03-20-14-05-00/source/gcc/java/ChangeLog --- 2001-03-20-14-00-00/source/gcc/java/ChangeLog Mon Mar 19 13:52:16 2001 +++ 2001-03-20-14-05-00/source/gcc/java/ChangeLog Tue Mar 20 14:03:49 2001 @@ -1,3 +1,12 @@ +2001-03-19 Mark Mitchell + + * class.c (build_class_ref): Use SET_DECL_ASSEMBLER_NAME. + (layout_class): Likewise. + (layout_class_method): Likewise. + (emit_register_classes): Likewise. + * decl.c (builtin_function): Likewise. + (give_name_to_locals): Likewise. + 2001-03-19 Per Bothner * jcf-parse.c (load_inner_classes): Check CLASS_LOADED_P