This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][RFC] Fix PR c++/31923: Storage class with explicit template specialization


Attached is a proposed small patch to add an error report for explicit template
specializations that specify a storage class.  Such specifications are
apparently not permitted by the C++ standard.

Also included is a new test in the testsuite for this error.


gcc/cp/ChangeLog
2007-05-29  Simon Baldwin <simonb@google.com>

	PR c++/31923
	* parser.c (cp_parser_single_declaration): Added check for storage
	class other than sc_none in parsed declaration, and a flag to indicate
	if the call is part of an explicit template specialization parse.
	* (cp_parser_explicit_specialization): Specialization check flag added
	to call to cp_parser_single_declaration(), set true.
	* (cp_parser_template_declaration_after_export): Specialization check
	flag added to call to cp_parser_single_declaration(), set false.

gcc/testsuite/ChangeLog
2007-05-29  Simon Baldwin <simonb@google.com>

	PR c++/31923
	* g++.dg/template/error25.C: New.


diff -Nrcp3 gcc_orig/cp/parser.c gcc/cp/parser.c
*** gcc_orig/cp/parser.c	Fri May 25 13:36:47 2007
--- gcc/cp/parser.c	Tue May 29 14:52:16 2007
*************** static void cp_parser_template_declarati
*** 1912,1918 ****
  static void cp_parser_perform_template_parameter_access_checks
    (VEC (deferred_access_check,gc)*);
  static tree cp_parser_single_declaration
!   (cp_parser *, VEC (deferred_access_check,gc)*, bool, bool *);
  static tree cp_parser_functional_cast
    (cp_parser *, tree);
  static tree cp_parser_save_member_function_body
--- 1912,1918 ----
  static void cp_parser_perform_template_parameter_access_checks
    (VEC (deferred_access_check,gc)*);
  static tree cp_parser_single_declaration
!   (cp_parser *, VEC (deferred_access_check,gc)*, bool, bool, bool *);
  static tree cp_parser_functional_cast
    (cp_parser *, tree);
  static tree cp_parser_save_member_function_body
*************** cp_parser_explicit_specialization (cp_pa
*** 10216,10221 ****
--- 10216,10222 ----
      cp_parser_single_declaration (parser,
  				  /*checks=*/NULL,
  				  /*member_p=*/false,
+                                   /*explicit_specialization_p=*/true,
  				  /*friend_p=*/NULL);
    /* We're done with the specialization.  */
    end_specialization ();
*************** cp_parser_template_declaration_after_exp
*** 16498,16503 ****
--- 16499,16505 ----
        decl = cp_parser_single_declaration (parser,
  					   checks,
  					   member_p,
+                                            /*explicit_specialization_p=*/false,
  					   &friend_p);
        pop_deferring_access_checks ();
  
*************** static tree
*** 16563,16568 ****
--- 16565,16571 ----
  cp_parser_single_declaration (cp_parser* parser,
  			      VEC (deferred_access_check,gc)* checks,
  			      bool member_p,
+                               bool explicit_specialization_p,
  			      bool* friend_p)
  {
    int declares_class_or_enum;
*************** cp_parser_single_declaration (cp_parser*
*** 16636,16648 ****
    if (!decl
        && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
  	  || decl_specifiers.type != error_mark_node))
!     decl = cp_parser_init_declarator (parser,
! 				      &decl_specifiers,
! 				      checks,
! 				      /*function_definition_allowed_p=*/true,
! 				      member_p,
! 				      declares_class_or_enum,
! 				      &function_definition_p);
  
    pop_deferring_access_checks ();
  
--- 16639,16665 ----
    if (!decl
        && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
  	  || decl_specifiers.type != error_mark_node))
!     {
!       decl = cp_parser_init_declarator (parser,
! 				        &decl_specifiers,
! 				        checks,
! 				        /*function_definition_allowed_p=*/true,
! 				        member_p,
! 				        declares_class_or_enum,
! 				        &function_definition_p);
! 
!     /* 7.1.1-1 [dcl.stc]
! 
!        A storage-class-specifier shall not be specified in an explicit
!        specialization...  */
!     if (decl
!         && explicit_specialization_p
!         && decl_specifiers.storage_class != sc_none)
!       {
!         error ("explicit template specialization cannot have a storage class");
!         decl = error_mark_node;
!       }
!     }
  
    pop_deferring_access_checks ();
  
diff -Nrcp3 gcc_orig/testsuite/g++.dg/template/error25.C gcc/testsuite/g++.dg/template/error25.C
*** gcc_orig/testsuite/g++.dg/template/error25.C	Wed Dec 31 16:00:00 1969
--- gcc/testsuite/g++.dg/template/error25.C	Tue May 29 14:52:16 2007
***************
*** 0 ****
--- 1,16 ----
+ // PR c++/31923
+ 
+ template<class T>
+ static void f1 ();
+ 
+ template<>
+ static void f1<void> ();  // { dg-error "explicit template specialization cannot have a storage class" }
+ 
+ template<class T>
+ extern void f2 ();
+ 
+ template<>
+ extern void f2<void> ();  // { dg-error "explicit template specialization cannot have a storage class" }
+ 
+ export template<class T>  // { dg-warning "keyword 'export' not implemented" }
+ static void* f3 ();


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]