[C++ Patch] PR 71109 ("Misleading diagnostic message with 'virtual' used in out-of-line definitions of class template member functions")

Paolo Carlini paolo.carlini@oracle.com
Mon May 30 08:23:00 GMT 2016


Hi,

submitter noticed that for wrong uses of 'virtual' outside of template 
classes (B in the testcase) vs plain classes (A) we wrongly emit the 
"templates may not be %<virtual%>" error message. Simply checking 
current_class_type seems enough to solve the problem. Case C in the 
extended testcase double checks that we still give the "templates may 
not be %<virtual%>" error message when appropriate. Tested x86_64-linux.

Thanks,
Paolo.

//////////////////////////
-------------- next part --------------
/cp
2016-05-30  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71099
	* parser.c (cp_parser_function_specifier_opt): Use current_class_type
	to improve the diagnostic about wrong uses of 'virtual'.

/testsuite
2016-05-30  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71099
	* g++.dg/parse/virtual1.C: New.
-------------- next part --------------
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 236863)
+++ cp/parser.c	(working copy)
@@ -12888,7 +12888,8 @@ cp_parser_function_specifier_opt (cp_parser* parse
       /* 14.5.2.3 [temp.mem]
 
 	 A member function template shall not be virtual.  */
-      if (PROCESSING_REAL_TEMPLATE_DECL_P ())
+      if (PROCESSING_REAL_TEMPLATE_DECL_P ()
+	  && current_class_type)
 	error_at (token->location, "templates may not be %<virtual%>");
       else
 	set_and_check_decl_spec_loc (decl_specs, ds_virtual, token);
Index: testsuite/g++.dg/parse/virtual1.C
===================================================================
--- testsuite/g++.dg/parse/virtual1.C	(revision 0)
+++ testsuite/g++.dg/parse/virtual1.C	(working copy)
@@ -0,0 +1,25 @@
+// PR c++/71099
+
+struct A {
+  virtual void foo();
+};
+
+virtual void A::foo() {}  // { dg-error "'virtual' outside class" }
+
+template<typename>
+struct B {
+  virtual void foo();
+};
+
+template<typename T>
+virtual void B<T>::foo() {}  // { dg-error "'virtual' outside class" }
+
+template<typename>
+struct C {
+  template<typename>
+  virtual void foo();  // { dg-error "templates may not be 'virtual'" }
+};
+
+template<typename T>
+template<typename>
+virtual void C<T>::foo() {}  // { dg-error "'virtual' outside class" }


More information about the Gcc-patches mailing list