diff mbox

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

Message ID 574B7203.7060101@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 29, 2016, 10:49 p.m. UTC
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.

//////////////////////////
/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.

Comments

Jason Merrill May 30, 2016, 2:21 p.m. UTC | #1
OK.

On Sun, May 29, 2016 at 6:49 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> 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.
>
> //////////////////////////
diff mbox

Patch

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" }