gold/
authorCary Coutant <ccoutant@google.com>
Tue, 21 May 2013 21:14:40 +0000 (21:14 +0000)
committerCary Coutant <ccoutant@google.com>
Tue, 21 May 2013 21:14:40 +0000 (21:14 +0000)
* symtab.h (Symbol::is_cxx_vtable): New function.
* target-reloc.h (relocate_section): Check for vtable symbol.
* testsuite/Makefile.am (missing_key_func.sh): New test case.
* testsuite/Makefile.in: Regenerate.
* testsuite/missing_key_func.cc: New test source.
* testsuite/missing_key_func.sh: New test script.

gold/ChangeLog
gold/symtab.h
gold/target-reloc.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/missing_key_func.cc [new file with mode: 0644]
gold/testsuite/missing_key_func.sh [new file with mode: 0755]

index c0fd434a315883e5e4d3dcb890aa1bf086892c65..d53df062e7b68f0c7767b3038edd1c8c889e1fa1 100644 (file)
@@ -1,3 +1,12 @@
+2013-05-21  Cary Coutant  <ccoutant@google.com>
+
+       * symtab.h (Symbol::is_cxx_vtable): New function.
+       * target-reloc.h (relocate_section): Check for vtable symbol.
+       * testsuite/Makefile.am (missing_key_func.sh): New test case.
+       * testsuite/Makefile.in: Regenerate.
+       * testsuite/missing_key_func.cc: New test source.
+       * testsuite/missing_key_func.sh: New test script.
+
 2013-05-21  Cary Coutant  <ccoutant@google.com>
 
        * object.cc (Sized_relobj_file::get_symbol_location_info): Set
index 689d99f5bf0442479034defe542cb121729f32d8..9299ea8abe9bb36ab4ab24b3e60fcb43342e6c97 100644 (file)
@@ -817,6 +817,11 @@ class Symbol
   is_predefined() const
   { return this->is_predefined_; }
 
+  // Return true if this is a C++ vtable symbol.
+  bool
+  is_cxx_vtable() const
+  { return is_prefix_of("_ZTV", this->name_); }
+
  protected:
   // Instances of this class should always be created at a specific
   // size.
index cf5e389565d5ba6331c076c2e63a1e64aefb6cb0..b544c78f371464c16fed5f749ff8bb029ae1ba20 100644 (file)
@@ -411,7 +411,13 @@ relocate_section(
        }
 
       if (issue_undefined_symbol_error(sym))
-       gold_undefined_symbol_at_location(sym, relinfo, i, offset);
+       {
+         gold_undefined_symbol_at_location(sym, relinfo, i, offset);
+         if (sym->is_cxx_vtable())
+           gold_info(_("%s: the vtable symbol may be undefined because "
+                       "the class is missing its key function"),
+                     program_name);
+       }
       else if (sym != NULL
               && sym->visibility() != elfcpp::STV_DEFAULT
               && (sym->is_undefined() || sym->is_from_dynobj()))
index 785adab9746beed843016a77027a20c76489dcda..4936e14887c63b84e28b0284183d55c0f3324d3a 100644 (file)
@@ -974,6 +974,20 @@ debug_msg.err: debug_msg.o odr_violation1.o odr_violation2.o gcctestdir/ld
          exit 1; \
        fi
 
+# Test error message when a vtable is undefined.
+check_SCRIPTS += missing_key_func.sh
+check_DATA += missing_key_func.err
+MOSTLYCLEANFILES += missing_key_func.err
+missing_key_func.o: missing_key_func.cc
+       $(CXXCOMPILE) -O0 -g -c -o $@ $(srcdir)/missing_key_func.cc
+missing_key_func.err: missing_key_func.o gcctestdir/ld
+       @echo $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o "2>$@"
+       @if $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o 2>$@; \
+       then \
+         echo 1>&2 "Link of missing_key_func should have failed"; \
+         rm -f $@; \
+         exit 1; \
+       fi
 
 if HAVE_ZLIB
 
index 1e00b152e05bcebc2865ecfd85dbdda92b0a9052..495b7d06f164c53186e76149714016fb04419f84 100644 (file)
@@ -69,6 +69,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 
 # Test --detect-odr-violations
 
+# Test error message when a vtable is undefined.
+
 # Similar to --detect-odr-violations: check for undefined symbols in .so's
 
 # Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new,
@@ -87,11 +89,11 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.sh weak_plt.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.sh undef_symbol.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_1.sh ver_test_2.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_4.sh ver_test_5.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.sh ver_test_10.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ relro_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.sh missing_key_func.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.sh ver_test_1.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_2.sh ver_test_4.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_5.sh ver_test_7.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_10.sh relro_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4.sh \
@@ -122,7 +124,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_plt_shared.so debug_msg.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_plt_shared.so debug_msg.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ missing_key_func.err
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_4 = incremental_test \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test.cmdline \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test gc_tls_test \
@@ -225,7 +228,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ many_sections_check.h
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_26 = many_sections_define.h \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ many_sections_check.h \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ missing_key_func.err
 @GCC_FALSE@initpri1_DEPENDENCIES =
 @NATIVE_LINKER_FALSE@initpri1_DEPENDENCIES =
 @GCC_FALSE@initpri2_DEPENDENCIES =
@@ -3767,6 +3771,8 @@ weak_plt.sh.log: weak_plt.sh
        @p='weak_plt.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 debug_msg.sh.log: debug_msg.sh
        @p='debug_msg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+missing_key_func.sh.log: missing_key_func.sh
+       @p='missing_key_func.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 undef_symbol.sh.log: undef_symbol.sh
        @p='undef_symbol.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 ver_test_1.sh.log: ver_test_1.sh
@@ -4663,6 +4669,16 @@ uninstall-am:
 @GCC_TRUE@@NATIVE_LINKER_TRUE@   rm -f $@; \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@   exit 1; \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ fi
+@GCC_TRUE@@NATIVE_LINKER_TRUE@missing_key_func.o: missing_key_func.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -g -c -o $@ $(srcdir)/missing_key_func.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@missing_key_func.err: missing_key_func.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ @echo $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o "2>$@"
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ @if $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o 2>$@; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ then \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@   echo 1>&2 "Link of missing_key_func should have failed"; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@   rm -f $@; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@   exit 1; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ fi
 @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@debug_msg_cdebug.o: debug_msg.cc gcctestdir/as
 @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -Bgcctestdir/ -O0 -g -Wa,--compress-debug-sections -c -w -o $@ $(srcdir)/debug_msg.cc
 @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@odr_violation1_cdebug.o: odr_violation1.cc gcctestdir/as
diff --git a/gold/testsuite/missing_key_func.cc b/gold/testsuite/missing_key_func.cc
new file mode 100644 (file)
index 0000000..5a5b7d9
--- /dev/null
@@ -0,0 +1,46 @@
+// basic_test.cc -- a test case for gold
+
+// Copyright 2013 Free Software Foundation, Inc.
+// Written by Cary Coutant <ccoutant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// Define a class, but leave its key function undefined.
+
+class C
+{
+ public:
+  C() : c(1) { }
+  virtual void set();
+  virtual void clear();
+  int c;
+};
+
+void
+C::clear()
+{
+  c = 0;
+}
+
+int
+main()
+{
+  C c;
+  c.clear();
+  return c.c;
+}
diff --git a/gold/testsuite/missing_key_func.sh b/gold/testsuite/missing_key_func.sh
new file mode 100755 (executable)
index 0000000..54c7b57
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# missing_key_func.sh -- a test case for printing error messages when
+# a class is missing its key function.
+
+# Copyright 2013 Free Software Foundation, Inc.
+# Written by Cary Coutant <ccoutant@google.com>
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# This file goes with debug_msg.cc, a C++ source file constructed to
+# have undefined references.  We compile that file with debug
+# information and then try to link it, and make sure the proper errors
+# are displayed.  The errors will be found in debug_msg.err.
+
+check()
+{
+    if ! grep -q "$2" "$1"
+    then
+       echo "Did not find expected error in $1:"
+       echo "   $2"
+       echo ""
+       echo "Actual error output below:"
+       cat "$1"
+       exit 1
+    fi
+}
+
+check_missing()
+{
+    if grep -q "$2" "$1"
+    then
+       echo "Found unexpected error in $1:"
+       echo "   $2"
+       echo ""
+       echo "Actual error output below:"
+       cat "$1"
+       exit 1
+    fi
+}
+
+check missing_key_func.err "error: undefined reference to 'vtable for C'"
+check missing_key_func.err "class is missing its key function"