Hi,
we are getting bug reports (3 so far) about this issue: in C++11 we
reject the below testcase and we say that the virtual function declared
in A is never defined. Without considering more subtle details, the
error appears meaningless because the function is in fact *pure*
virtual. In any case, the testcase is accepted with -fpermissive and the
generated code is in fact Ok at runtime. All in all, I thought we could
simply check DECL_PURE_VIRTUAL_P before emitting the permerror, the
trivial change passes testing.
Thanks,
Paolo.
//////////////////////////
/cp
2015-06-15 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51048
* decl2.c (no_linkage_error): Do not issue a permerror if the DECL
using a local type is pure virtual.
/testsuite
2015-06-15 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51048
* g++.dg/cpp0x/local-type1.C: New.
Index: cp/decl2.c
===================================================================
--- cp/decl2.c (revision 224475)
+++ cp/decl2.c (working copy)
@@ -4221,8 +4221,12 @@ no_linkage_error (tree decl)
TYPE_NAME (t));
}
else if (cxx_dialect >= cxx11)
- permerror (DECL_SOURCE_LOCATION (decl), "%q#D, declared using local type "
- "%qT, is used but never defined", decl, t);
+ {
+ if (TREE_CODE (decl) == VAR_DECL || !DECL_PURE_VIRTUAL_P (decl))
+ permerror (DECL_SOURCE_LOCATION (decl),
+ "%q#D, declared using local type "
+ "%qT, is used but never defined", decl, t);
+ }
else if (TREE_CODE (decl) == VAR_DECL)
warning_at (DECL_SOURCE_LOCATION (decl), 0, "type %qT with no linkage "
"used to declare variable %q#D with linkage", t, decl);
Index: testsuite/g++.dg/cpp0x/local-type1.C
===================================================================
--- testsuite/g++.dg/cpp0x/local-type1.C (revision 0)
+++ testsuite/g++.dg/cpp0x/local-type1.C (working copy)
@@ -0,0 +1,19 @@
+// PR c++/51048
+// { dg-do compile { target c++11 } }
+
+template<typename X>
+struct A {
+ virtual void DoPush(X const& x) = 0;
+ void Push(X const& x) { DoPush(x); }
+};
+
+template<typename X>
+struct B : A<X> {
+ using A<X>::Push;
+ virtual void DoPush(X const&) { }
+};
+
+int main() {
+ enum S { };
+ B<S>().Push(S());
+}