This patch modifies the behavior of cp_get_virtual_function_decl in gcc/cp/class.c so that it returns NULL if the function declaration cannot be found. The previous behavior was to fail with a segmentation fault. The method-not-found case may occur when Annotalysis uses the function to look up a method, in cases where the static type cannot be accurately determined.
Bootstrapped and passed GCC regression testsuite on x86_64-unknown-linux-gnu. Okay for branches/annotalysis and google/main? -DeLesley 2011-07-06 DeLesley Hutchins <deles...@google.com> * cp_get_virtual_function_decl.c (handle_call_gs): Changes function to return null if the method cannot be found. * thread_annot_lock-79.C: Additional annotalysis test cases Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 175718) +++ gcc/cp/class.c (working copy) @@ -8391,13 +8391,17 @@ cp_get_virtual_function_decl (tree ref, tree known HOST_WIDE_INT i = 0; tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type)); tree fndecl; - - while (i != index) + + while (v && i != index) { i += (TARGET_VTABLE_USES_DESCRIPTORS ? TARGET_VTABLE_USES_DESCRIPTORS : 1); v = TREE_CHAIN (v); } + + /* Return null if the method is not found. */ + if (!v) + return NULL_TREE; fndecl = BV_FN (v); Index: gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C =================================================================== --- gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C (revision 175719) +++ gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-79.C (working copy) @@ -5,8 +5,20 @@ #include "thread_annot_common.h" -class Foo { +class FooBase1 { public: + int dummy; +}; + + +class FooBase2 : public FooBase1 { +public: + virtual ~FooBase2(); +}; + + +class Foo : public FooBase2 { +public: Mutex m; Foo(); @@ -39,6 +51,18 @@ void foo1(void* ptr) reinterpret_cast<Foo*>(ptr)->doSomething(); } +// downcast from structure type with no virtuals +void foo1(FooBase1* ptr) +{ + reinterpret_cast<Foo*>(ptr)->doSomething(); +} + +// downcast from structure type with virtuals +void foo1(FooBase2* ptr) +{ + reinterpret_cast<Foo*>(ptr)->doSomething(); +} + // C-style cast void foo2(int* buf) {