re PR bootstrap/66521 (xgcc: cc1plus segfaults when compiling libstdc++-v3/src/c++11/ostream-inst.cc)
Fix PR 66521 libvtv/ChangeLog 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. gcc/ChangeLog: 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. gcc/cp/ChangeLog: 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. From-SVN: r226471
This commit is contained in:
parent
68e3e6a259
commit
b0cca5ecbb
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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)"
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
}
|
||||
|
||||
#
|
||||
|
@ -145,7 +145,7 @@ change_protections_on_data_chunks (int protection_flag)
|
||||
}
|
||||
|
||||
#ifdef VTV_DEBUG
|
||||
VTV_malloc_dump_stats ();
|
||||
__vtv_malloc_dump_stats ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user