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());
+}

Reply via email to