From 26f8363d85fd386430ddb612a2e70624715c2ac3 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 5 Jul 2019 18:03:05 +0000 Subject: [PATCH] PR c++/67184 (again) /cp 2019-07-05 Paolo Carlini PR c++/67184 (again) PR c++/69445 * call.c (build_over_call): Devirtualize user-defined operators coming from a base too. (build_new_method_call_1): Do not devirtualize here. /testsuite 2019-07-05 Paolo Carlini PR c++/67184 (again) PR c++/69445 * g++.dg/other/final4.C: New. From-SVN: r273147 --- gcc/cp/ChangeLog | 11 ++++++++++- gcc/cp/call.c | 24 ++++++++++-------------- gcc/testsuite/ChangeLog | 9 ++++++++- gcc/testsuite/g++.dg/other/final4.C | 16 ++++++++++++++++ 4 files changed, 44 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/other/final4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f24a096..05e4555 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,7 +1,16 @@ +2019-07-05 Paolo Carlini + + PR c++/67184 (again) + PR c++/69445 + * call.c (build_over_call): Devirtualize user-defined operators + coming from a base too. + (build_new_method_call_1): Do not devirtualize here. + 2019-07-04 Marek Polacek DR 1813 - PR c++/83374 - __is_standard_layout wrong for a class with repeated bases. + PR c++/83374 - __is_standard_layout wrong for a class with repeated + bases. * class.c (check_bases): Set CLASSTYPE_NON_STD_LAYOUT for a class if CLASSTYPE_REPEATED_BASE_P is true. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0709325..90116f4 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8241,10 +8241,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) return error_mark_node; } - /* See if the function member or the whole class type is declared - final and the call can be devirtualized. */ + /* Optimize away vtable lookup if we know that this + function can't be overridden. We need to check if + the context and the type where we found fn are the same, + actually FN might be defined in a different class + type because of a using-declaration. In this case, we + do not want to perform a non-virtual call. Note that + resolves_to_fixed_type_p checks CLASSTYPE_FINAL too. */ if (DECL_FINAL_P (fn) - || CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)))) + || (resolves_to_fixed_type_p (arg, 0) + && same_type_ignoring_top_level_qualifiers_p + (DECL_CONTEXT (fn), BINFO_TYPE (cand->conversion_path)))) flags |= LOOKUP_NONVIRTUAL; /* [class.mfct.nonstatic]: If a nonstatic member function of a class @@ -9845,17 +9852,6 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, if (call != error_mark_node) { - /* Optimize away vtable lookup if we know that this - function can't be overridden. We need to check if - the context and the type where we found fn are the same, - actually FN might be defined in a different class - type because of a using-declaration. In this case, we - do not want to perform a non-virtual call. */ - if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL) - && same_type_ignoring_top_level_qualifiers_p - (DECL_CONTEXT (fn), BINFO_TYPE (binfo)) - && resolves_to_fixed_type_p (instance, 0)) - flags |= LOOKUP_NONVIRTUAL; if (explicit_targs) flags |= LOOKUP_EXPLICIT_TMPL_ARGS; /* Now we know what function is being called. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 98ad880..33645b1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,7 +1,14 @@ +2019-07-05 Paolo Carlini + + PR c++/67184 (again) + PR c++/69445 + * g++.dg/other/final4.C: New. + 2019-07-04 Marek Polacek DR 1813 - PR c++/83374 - __is_standard_layout wrong for a class with repeated bases. + PR c++/83374 - __is_standard_layout wrong for a class with repeated + bases. * g++.dg/ext/is_std_layout3.C: New test. * g++.dg/ext/is_std_layout4.C: New test. diff --git a/gcc/testsuite/g++.dg/other/final4.C b/gcc/testsuite/g++.dg/other/final4.C new file mode 100644 index 0000000..867ef38 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/final4.C @@ -0,0 +1,16 @@ +// PR c++/67184 +// { dg-do compile { target c++11 } } +// { dg-options "-fdump-tree-original" } + +struct B +{ + virtual void operator()(); + virtual operator int(); + virtual int operator++(); +}; + +struct D final : B { }; + +void foo(D& d) { d(); int t = d; ++d; } + +// { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "original" } } -- 2.7.4