From ed9e19a494a43647159b156737c55bde8ebf3c59 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 10 Dec 2013 10:49:39 +0000 Subject: [PATCH] re PR sanitizer/59437 (ICE in for g++ -S -fvtable-verify=std -fsanitize=null) PR sanitizer/59437 * vtable-verify.c (var_is_used_for_virtual_call_p): Check the return value of gimple_call_fn. Use is_gimple_call/is_gimple_assign instead of gimple_code. testsuite/ * g++.dg/ubsan/pr59437.C: New test. From-SVN: r205854 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/ubsan/pr59437.C | 24 ++++++++++++++++++++++++ gcc/vtable-verify.c | 6 +++--- 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ubsan/pr59437.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f34fb242d7..110c0a033e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-12-10 Marek Polacek + + PR sanitizer/59437 + * vtable-verify.c (var_is_used_for_virtual_call_p): Check the + return value of gimple_call_fn. Use is_gimple_call/is_gimple_assign + instead of gimple_code. + 2013-12-10 Maxim Kuvyrkov * config.gcc (mips*-mti-linux*, mips64*-*-linux*): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 404569ed743..09a1323ca18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-12-09 Marek Polacek + + PR sanitizer/59437 + * g++.dg/ubsan/pr59437.C: New test. + 2013-12-10 Max Ostapenko * c-c++-common/tsan/thread_leak2.c: `dg-skip-if' removed. diff --git a/gcc/testsuite/g++.dg/ubsan/pr59437.C b/gcc/testsuite/g++.dg/ubsan/pr59437.C new file mode 100644 index 00000000000..0e77ccde46e --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr59437.C @@ -0,0 +1,24 @@ +// { dg-do compile } +// { dg-options "-fsanitize=null -fvtable-verify=std" } +// { dg-skip-if "" { *-*-* } { "-flto" } { "" } } + +template < typename T > struct A +{ + T foo (); +}; +template < typename T > struct C: virtual public A < T > +{ + C & operator<< (C & (C &)); +}; +template < typename T > +C < T > &endl (C < int > &c) +{ + c.foo (); + return c; +} +C < int > cout; +void +fn () +{ + cout << endl; +} diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c index dabb77b9d10..af61e930b20 100644 --- a/gcc/vtable-verify.c +++ b/gcc/vtable-verify.c @@ -513,10 +513,10 @@ var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth) { gimple stmt2 = USE_STMT (use_p); - if (gimple_code (stmt2) == GIMPLE_CALL) + if (is_gimple_call (stmt2)) { tree fncall = gimple_call_fn (stmt2); - if (TREE_CODE (fncall) == OBJ_TYPE_REF) + if (fncall && TREE_CODE (fncall) == OBJ_TYPE_REF) found_vcall = true; else return false; @@ -527,7 +527,7 @@ var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth) (gimple_phi_result (stmt2), mem_ref_depth); } - else if (gimple_code (stmt2) == GIMPLE_ASSIGN) + else if (is_gimple_assign (stmt2)) { tree rhs = gimple_assign_rhs1 (stmt2); if (TREE_CODE (rhs) == ADDR_EXPR