summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/mangle.c8
-rw-r--r--gcc/vtable-verify.c92
-rw-r--r--gcc/vtable-verify.h5
-rw-r--r--libvtv/ChangeLog11
-rw-r--r--libvtv/testsuite/Makefile.am16
-rw-r--r--libvtv/testsuite/Makefile.in14
-rw-r--r--libvtv/testsuite/lib/libvtv.exp37
-rw-r--r--libvtv/vtv_malloc.cc2
-rw-r--r--libvtv/vtv_rts.cc7
11 files changed, 186 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 53b44c1bbc48..ea9dbe11596d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+2015-08-01 Caroline Tice <cmtice@google.com>
+
+ PR 66521
+ * vtable-verify.c (vtbl_mangled_name_types, vtbl_mangled_name_ids): New
+ global variables.
+ (vtbl_find_mangled_name): New function.
+ (vtbl_register_mangled_name): New function.
+ (vtbl_map_get_node): If DECL_ASSEMBLER_NAME is "<anon>", look up
+ mangled name in mangled name vectors.
+ (find_or_create_vtbl_map_node): Ditto.
+ (var_is_used_for_virtual_call_p): Add recursion_depth parameter;
+ update recursion_depth on function entry; pass it to every recursive
+ call; automatically exit if depth > 25 (give up looking at that point).
+ (verify_bb_vtables): Initialize recursion_depth and pass it to
+ var_is_used_for_virtual_call_p.
+ * vtable-verify.h (vtbl_mangbled_name_types, vtbl_mangled_name_ids): New
+ global variable decls.
+ (vtbl_register_mangled_name): New extern function decl.
+
2015-08-01 Tom de Vries <tom@codesourcery.com>
* tree.c (operation_can_overflow, operation_no_trapping_overflow): New
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8d286a62d9e3..db7d616df0b3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2015-08-01 Caroline Tice <cmtice@google.com>
+
+ PR 66521
+ * mangle.c : Add vtable-verify.h to include files.
+ (get_mangled_vtable_map_var_name): If the DECL_ASSEMBLER_NAME
+ is "<anon>" get the real mangled name for the class instead, and
+ also store the real mangled name in a vector for use later.
+
2015-07-31 Marek Polacek <polacek@redhat.com>
PR sanitizer/66977
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index b4d4c0e5c0e7..d471f4f0a068 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "cgraph.h"
#include "attribs.h"
+#include "vtable-verify.h"
/* Debugging support. */
@@ -4036,6 +4037,13 @@ get_mangled_vtable_map_var_name (tree class_type)
gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);
tree class_id = DECL_ASSEMBLER_NAME (TYPE_NAME (class_type));
+
+ if (strstr (IDENTIFIER_POINTER (class_id), "<anon>") != NULL)
+ {
+ class_id = get_mangled_id (TYPE_NAME (class_type));
+ vtbl_register_mangled_name (TYPE_NAME (class_type), class_id);
+ }
+
unsigned int len = strlen (IDENTIFIER_POINTER (class_id)) +
strlen (prefix) +
strlen (postfix) + 1;
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
index 46506af36d2e..a8345882045f 100644
--- a/gcc/vtable-verify.c
+++ b/gcc/vtable-verify.c
@@ -310,6 +310,70 @@ static vtbl_map_table_type *vtbl_map_hash;
/* Vtable map variable nodes stored in a vector. */
vec<struct vtbl_map_node *> vtbl_map_nodes_vec;
+/* Vector of mangled names for anonymous classes. */
+extern GTY(()) vec<tree, va_gc> *vtbl_mangled_name_types;
+extern GTY(()) vec<tree, va_gc> *vtbl_mangled_name_ids;
+vec<tree, va_gc> *vtbl_mangled_name_types;
+vec<tree, va_gc> *vtbl_mangled_name_ids;
+
+/* Look up class_type (a type decl for record types) in the vtbl_mangled_names_*
+ vectors. This is a linear lookup. Return the associated mangled name for
+ the class type. This is for handling types from anonymous namespaces, whose
+ DECL_ASSEMBLER_NAME ends up being "<anon>", which is useless for our
+ purposes.
+
+ We use two vectors of trees to keep track of the mangled names: One is a
+ vector of class types and the other is a vector of the mangled names. The
+ assumption is that these two vectors are kept in perfect lock-step so that
+ vtbl_mangled_name_ids[i] is the mangled name for
+ vtbl_mangled_name_types[i]. */
+
+static tree
+vtbl_find_mangled_name (tree class_type)
+{
+ tree result = NULL_TREE;
+ unsigned i;
+
+ if (!vtbl_mangled_name_types or !vtbl_mangled_name_ids)
+ return result;
+
+ if (vtbl_mangled_name_types->length() != vtbl_mangled_name_ids->length())
+ return result;
+
+ for (i = 0; i < vtbl_mangled_name_types->length(); ++i)
+ if ((*vtbl_mangled_name_types)[i] == class_type)
+ {
+ result = (*vtbl_mangled_name_ids)[i];
+ break;
+ }
+
+ return result;
+}
+
+/* Store a class type decl and its mangled name, for an anonymous RECORD_TYPE,
+ in the vtbl_mangled_names vector. Make sure there is not already an
+ entry for the class type before adding it. */
+
+void
+vtbl_register_mangled_name (tree class_type, tree mangled_name)
+{
+ if (!vtbl_mangled_name_types)
+ vec_alloc (vtbl_mangled_name_types, 10);
+
+ if (!vtbl_mangled_name_ids)
+ vec_alloc (vtbl_mangled_name_ids, 10);
+
+ gcc_assert (vtbl_mangled_name_types->length() ==
+ vtbl_mangled_name_ids->length());
+
+
+ if (vtbl_find_mangled_name (class_type) == NULL_TREE)
+ {
+ vec_safe_push (vtbl_mangled_name_types, class_type);
+ vec_safe_push (vtbl_mangled_name_ids, mangled_name);
+ }
+}
+
/* Return vtbl_map node for CLASS_NAME without creating a new one. */
struct vtbl_map_node *
@@ -339,6 +403,9 @@ vtbl_map_get_node (tree class_type)
gcc_assert (HAS_DECL_ASSEMBLER_NAME_P (class_type_decl));
class_name = DECL_ASSEMBLER_NAME (class_type_decl);
+ if (strstr (IDENTIFIER_POINTER (class_name), "<anon>") != NULL)
+ class_name = vtbl_find_mangled_name (class_type_decl);
+
key.class_name = class_name;
slot = (struct vtbl_map_node **) vtbl_map_hash->find_slot (&key, NO_INSERT);
if (!slot)
@@ -370,6 +437,10 @@ find_or_create_vtbl_map_node (tree base_class_type)
gcc_assert (HAS_DECL_ASSEMBLER_NAME_P (class_type_decl));
key.class_name = DECL_ASSEMBLER_NAME (class_type_decl);
+
+ if (strstr (IDENTIFIER_POINTER (key.class_name), "<anon>") != NULL)
+ key.class_name = vtbl_find_mangled_name (class_type_decl);
+
slot = (struct vtbl_map_node **) vtbl_map_hash->find_slot (&key, INSERT);
if (*slot)
@@ -482,7 +553,8 @@ extract_object_class_type (tree rhs)
the use chain. */
static bool
-var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth)
+var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth,
+ int *recursion_depth)
{
imm_use_iterator imm_iter;
bool found_vcall = false;
@@ -494,6 +566,14 @@ var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth)
if (*mem_ref_depth > 2)
return false;
+ if (*recursion_depth > 25)
+ /* If we've recursed this far the chances are pretty good that
+ we're not going to find what we're looking for, and that we've
+ gone down a recursion black hole. Time to stop. */
+ return false;
+
+ *recursion_depth = *recursion_depth + 1;
+
/* Iterate through the immediate uses of the current variable. If
it's a virtual function call, we're done. Otherwise, if there's
an LHS for the use stmt, add the ssa var to the work list
@@ -516,7 +596,8 @@ var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth)
{
found_vcall = var_is_used_for_virtual_call_p
(gimple_phi_result (stmt2),
- mem_ref_depth);
+ mem_ref_depth,
+ recursion_depth);
}
else if (is_gimple_assign (stmt2))
{
@@ -538,7 +619,8 @@ var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth)
if (*mem_ref_depth < 3)
found_vcall = var_is_used_for_virtual_call_p
(gimple_assign_lhs (stmt2),
- mem_ref_depth);
+ mem_ref_depth,
+ recursion_depth);
}
else
@@ -595,9 +677,11 @@ verify_bb_vtables (basic_block bb)
tree tmp0;
bool found;
int mem_ref_depth = 0;
+ int recursion_depth = 0;
/* Make sure this vptr field access is for a virtual call. */
- if (!var_is_used_for_virtual_call_p (lhs, &mem_ref_depth))
+ if (!var_is_used_for_virtual_call_p (lhs, &mem_ref_depth,
+ &recursion_depth))
continue;
/* Now we have found the virtual method dispatch and
diff --git a/gcc/vtable-verify.h b/gcc/vtable-verify.h
index dda6f069dba4..178ba3635014 100644
--- a/gcc/vtable-verify.h
+++ b/gcc/vtable-verify.h
@@ -127,6 +127,11 @@ extern bool vtv_debug;
/* The global vector of vtbl_map_nodes. */
extern vec<struct vtbl_map_node *> vtbl_map_nodes_vec;
+/* The global vectors for mangled class names for anonymous classes. */
+extern GTY(()) vec<tree, va_gc> *vtbl_mangled_name_types;
+extern GTY(()) vec<tree, va_gc> *vtbl_mangled_name_ids;
+
+extern void vtbl_register_mangled_name (tree, tree);
extern struct vtbl_map_node *vtbl_map_get_node (tree);
extern struct vtbl_map_node *find_or_create_vtbl_map_node (tree);
extern void vtbl_map_node_class_insert (struct vtbl_map_node *, unsigned);
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog
index d7fd975a5ff8..612c660d668c 100644
--- a/libvtv/ChangeLog
+++ b/libvtv/ChangeLog
@@ -1,3 +1,14 @@
+2015-08-01 Caroline Tice <cmtice@google.com>
+
+ PR 66521
+ * Makefile.am: Update to match latest tree.
+ * Makefile.in: Regenerate.
+ * testsuite/lib/libvtv: Brought up to date.
+ * vtv_malloc.cc (VTV_DEBUG): Update function call to match renamed
+ function (old bug!).
+ * vtv_rts.cc (debug_functions, debug_init, debug_verify_vtable): Update
+ initializations to work correctly with VTV_DEBUG defined.
+
2015-05-13 Michael Haubenwallner <michael.haubenwallner@ssi-schaefer.com>
* Makefile.in: Regenerated with automake-1.11.6.
diff --git a/libvtv/testsuite/Makefile.am b/libvtv/testsuite/Makefile.am
index a2c1e9f4ea31..561b7e25448e 100644
--- a/libvtv/testsuite/Makefile.am
+++ b/libvtv/testsuite/Makefile.am
@@ -1,11 +1,13 @@
-## Process this with automake to create Makefile.in
+## Process this file with automake to produce Makefile.in.
AUTOMAKE_OPTIONS = foreign dejagnu
-EXPECT = `if [ -f ../../expect/expect ] ; then \
- echo ../../expect/expect ; \
- else echo expect ; fi`
+# May be used by various substitution variables.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
-RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \
- echo ${srcdir}/../../dejagnu/runtest ; \
- else echo runtest ; fi`
+EXPECT = $(shell if test -f $(top_builddir)/../expect/expect; then \
+ echo $(top_builddir)/../expect/expect; else echo expect; fi)
+
+_RUNTEST = $(shell if test -f $(top_srcdir)/../dejagnu/runtest; then \
+ echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi)
+RUNTEST = "$(_RUNTEST) $(AM_RUNTESTFLAGS)"
diff --git a/libvtv/testsuite/Makefile.in b/libvtv/testsuite/Makefile.in
index 49f8f713ce08..e19e13e7e5ff 100644
--- a/libvtv/testsuite/Makefile.in
+++ b/libvtv/testsuite/Makefile.in
@@ -217,14 +217,16 @@ top_srcdir = @top_srcdir@
toplevel_builddir = @toplevel_builddir@
toplevel_srcdir = @toplevel_srcdir@
AUTOMAKE_OPTIONS = foreign dejagnu
-EXPECT = `if [ -f ../../expect/expect ] ; then \
- echo ../../expect/expect ; \
- else echo expect ; fi`
-RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \
- echo ${srcdir}/../../dejagnu/runtest ; \
- else echo runtest ; fi`
+# May be used by various substitution variables.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+EXPECT = $(shell if test -f $(top_builddir)/../expect/expect; then \
+ echo $(top_builddir)/../expect/expect; else echo expect; fi)
+_RUNTEST = $(shell if test -f $(top_srcdir)/../dejagnu/runtest; then \
+ echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi)
+
+RUNTEST = "$(_RUNTEST) $(AM_RUNTESTFLAGS)"
all: all-am
.SUFFIXES:
diff --git a/libvtv/testsuite/lib/libvtv.exp b/libvtv/testsuite/lib/libvtv.exp
index c473b0a33576..aefcbd26ef4f 100644
--- a/libvtv/testsuite/lib/libvtv.exp
+++ b/libvtv/testsuite/lib/libvtv.exp
@@ -23,24 +23,28 @@ proc load_gcc_lib { filename } {
}
load_lib dg.exp
-load_gcc_lib file-format.exp
+
+# Required to use gcc-dg.exp - however, the latter should NOT be
+# loaded until ${tool}_target_compile is defined since it uses that
+# to determine default LTO options.
+
+load_gcc_lib prune.exp
+load_gcc_lib target-libpath.exp
+load_gcc_lib wrapper.exp
load_gcc_lib target-supports.exp
-load_gcc_lib target-supports-dg.exp
load_gcc_lib target-utils.exp
+load_gcc_lib gcc-defs.exp
+load_gcc_lib timeout.exp
+load_gcc_lib file-format.exp
+load_gcc_lib target-supports-dg.exp
load_gcc_lib scanasm.exp
load_gcc_lib scandump.exp
load_gcc_lib scanrtl.exp
load_gcc_lib scantree.exp
load_gcc_lib scanipa.exp
-load_gcc_lib prune.exp
-load_gcc_lib target-libpath.exp
-load_gcc_lib wrapper.exp
-load_gcc_lib gcc-defs.exp
-load_gcc_lib torture-options.exp
-load_gcc_lib timeout.exp
load_gcc_lib timeout-dg.exp
+load_gcc_lib torture-options.exp
load_gcc_lib fortran-modules.exp
-load_gcc_lib gcc-dg.exp
set dg-do-what-default run
@@ -143,10 +147,20 @@ proc libvtv_init { args } {
}
lappend ALWAYS_CFLAGS "additional_flags=-I${srcdir}/.."
+ # We use atomic operations in the testcases to validate results.
+ if { ([istarget i?86-*-*] || [istarget x86_64-*-*])
+ && [check_effective_target_ia32] } {
+ lappend ALWAYS_CFLAGS "additional_flags=-march=i486"
+ }
+
if [istarget *-*-darwin*] {
lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc"
}
+ if [istarget sparc*-*-*] {
+ lappend ALWAYS_CFLAGS "additional_flags=-mcpu=v9"
+ }
+
if [info exists TOOL_OPTIONS] {
lappend ALWAYS_CFLAGS "additional_flags=$TOOL_OPTIONS"
}
@@ -155,9 +169,8 @@ proc libvtv_init { args } {
# error-message parsing machinery.
lappend ALWAYS_CFLAGS "additional_flags=-fmessage-length=0"
- # Turn on vtable verification
- lappend ALWAYS_CFLAGS "-fvtable-verify=std"
- # lappend ALWAYS_CFLAGS "ldflags=-lvtv"
+ # Turn on vtable verification.
+ lappend ALWAYS_CFLAGS "additional_flags=-fvtable-verify=std"
}
#
diff --git a/libvtv/vtv_malloc.cc b/libvtv/vtv_malloc.cc
index 4b675f40bdc0..5249248ce82f 100644
--- a/libvtv/vtv_malloc.cc
+++ b/libvtv/vtv_malloc.cc
@@ -145,7 +145,7 @@ change_protections_on_data_chunks (int protection_flag)
}
#ifdef VTV_DEBUG
- VTV_malloc_dump_stats ();
+ __vtv_malloc_dump_stats ();
#endif
}
diff --git a/libvtv/vtv_rts.cc b/libvtv/vtv_rts.cc
index f5344a00687c..7bde2f46e4f3 100644
--- a/libvtv/vtv_rts.cc
+++ b/libvtv/vtv_rts.cc
@@ -201,14 +201,15 @@ unsigned long long verify_vtable_cycles = 0;
debugging/tracing will not be ON on production environments */
static const bool debug_hash = HASHTABLE_STATS;
-static const int debug_functions = 0;
-static const int debug_init = 0;
-static const int debug_verify_vtable = 0;
#ifdef VTV_DEBUG
static const int debug_functions = 1;
static const int debug_init = 1;
static const int debug_verify_vtable = 1;
+#else
+static const int debug_functions = 0;
+static const int debug_init = 0;
+static const int debug_verify_vtable = 0;
#endif
/* Global file descriptor variables for logging, tracing and debugging. */