Hello, Consider this short code snippet:
struct A { virtual void foo(); }; template <typename T> void bar(T x) { A &b = *x; b.foo(); } When we look at b.foo() during the parsing (in cp_parser_postfix_expression), 'b.foo()' is (rightfully) considered non-dependent. So we go on an build the method call expression. Then build_new_method_call wants to know the determine the dynamic type of 'b' and uses fixed_type_or_null for that. fixed_type_or_null goes to look into the initializer of the reference variable 'b', which is dependent; and it crashes while trying to poke at the type of the INDIRECT_REF '*x', which has no type yet (because it's dependent). The patch below makes fixed_type_or_null consider that it cannot determine the dynamic type of a reference variable if its initializer is dependent. Tested on x86_64-unknown-linux-gnu against trunk. gcc/cp/ * class.c (fixed_type_or_null): We cannot determine the dynamic type of a reference variable if its initializer is dependent. gcc/testsuite/ * g++.dg/template/dependent-expr7.C: New test case. --- gcc/cp/class.c | 8 ++++++++ gcc/testsuite/g++.dg/template/dependent-expr7.C | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 0 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/dependent-expr7.C diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b6aebae..d40c11c 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5944,6 +5944,14 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) tree type; void **slot; + if (type_dependent_expression_p (DECL_INITIAL (instance))) + { + /* The initializer is type dependent so we cannot + determine the dynamic type of this reference. */ + if (nonnull) + *nonnull = 0; + return NULL_TREE; + } slot = htab_find_slot (ht, instance, INSERT); *slot = instance; type = RECUR (DECL_INITIAL (instance)); diff --git a/gcc/testsuite/g++.dg/template/dependent-expr7.C b/gcc/testsuite/g++.dg/template/dependent-expr7.C new file mode 100644 index 0000000..b246820 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr7.C @@ -0,0 +1,22 @@ +// Origin PR c++/48574 +// { dg-do compile } + +struct A +{ + virtual void foo(); +}; + +template <typename T> +void +bar(T x) +{ + A &b = *x; + b.foo (); +} + +void +foo() +{ + A a; + bar(&a); +} -- Dodji