re PR c++/53186 ([C++11] missing devirtualization for operators "final")
/cp 2012-05-03 Paolo Carlini <paolo.carlini@oracle.com> PR c++/53186 * call.c (build_over_call): Handle final member functions and class types. (build_new_method_call_1): Do not handle here. /testsuite 2012-05-03 Paolo Carlini <paolo.carlini@oracle.com> PR c++/53186 * g++.dg/other/final2.C: New. From-SVN: r187097
This commit is contained in:
parent
bea966c222
commit
1fa2969ff6
@ -1,3 +1,10 @@
|
||||
2012-05-03 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/53186
|
||||
* call.c (build_over_call): Handle final member functions
|
||||
and class types.
|
||||
(build_new_method_call_1): Do not handle here.
|
||||
|
||||
2012-05-02 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* decl.c (grokdeclarator): Properly check for sizes that
|
||||
|
@ -6550,6 +6550,12 @@ 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. */
|
||||
if (DECL_FINAL_P (fn)
|
||||
|| CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn))))
|
||||
flags |= LOOKUP_NONVIRTUAL;
|
||||
|
||||
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
|
||||
X is called for an object that is not of type X, or of a type
|
||||
derived from X, the behavior is undefined.
|
||||
@ -7418,8 +7424,7 @@ build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
|
||||
/* Optimize away vtable lookup if we know that this function
|
||||
can't be overridden. */
|
||||
if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL)
|
||||
&& (resolves_to_fixed_type_p (instance, 0)
|
||||
|| DECL_FINAL_P (fn) || CLASSTYPE_FINAL (basetype)))
|
||||
&& resolves_to_fixed_type_p (instance, 0))
|
||||
flags |= LOOKUP_NONVIRTUAL;
|
||||
if (explicit_targs)
|
||||
flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-05-03 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/53186
|
||||
* g++.dg/other/final2.C: New.
|
||||
|
||||
2012-05-03 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/ssa-pre-27.c: Remove XFAIL.
|
||||
|
27
gcc/testsuite/g++.dg/other/final2.C
Normal file
27
gcc/testsuite/g++.dg/other/final2.C
Normal file
@ -0,0 +1,27 @@
|
||||
// PR c++/53186
|
||||
// { dg-options "-fdump-tree-original -std=c++11" }
|
||||
|
||||
struct F1
|
||||
{
|
||||
virtual void operator()() final;
|
||||
virtual operator int() final;
|
||||
virtual int operator++() final;
|
||||
};
|
||||
|
||||
struct F2 final
|
||||
{
|
||||
virtual void operator()();
|
||||
virtual operator int();
|
||||
virtual int operator++();
|
||||
};
|
||||
|
||||
void fooF1(F1& a) { a(); int m = a; ++a; }
|
||||
void fooF2(F2& a) { a(); int m = a; ++a; }
|
||||
|
||||
// { dg-final { scan-tree-dump-times "F1::operator\\(\\)" 1 "original" } }
|
||||
// { dg-final { scan-tree-dump-times "F1::operator int" 1 "original" } }
|
||||
// { dg-final { scan-tree-dump-times "F1::operator\\+\\+" 1 "original" } }
|
||||
// { dg-final { scan-tree-dump-times "F2::operator\\(\\)" 1 "original" } }
|
||||
// { dg-final { scan-tree-dump-times "F2::operator int" 1 "original" } }
|
||||
// { dg-final { scan-tree-dump-times "F2::operator\\+\\+" 1 "original" } }
|
||||
// { dg-final { cleanup-tree-dump "original" } }
|
Loading…
Reference in New Issue
Block a user