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:
Caroline Tice 2015-08-01 18:17:39 -07:00 committed by Caroline Tice
parent 68e3e6a259
commit b0cca5ecbb
11 changed files with 186 additions and 33 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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)"

View File

@ -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:

View File

@ -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"
}
#

View File

@ -145,7 +145,7 @@ change_protections_on_data_chunks (int protection_flag)
}
#ifdef VTV_DEBUG
VTV_malloc_dump_stats ();
__vtv_malloc_dump_stats ();
#endif
}

View File

@ -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. */