diff mbox

PR c++/51143 - Alias template allows class definition

Message ID m3wrash4jm.fsf@redhat.com
State New
Headers show

Commit Message

Dodji Seketeli Nov. 22, 2011, 9:47 a.m. UTC
Hello,

As reminded in the audit trail of this PR, we shouldn't allow a type
definition in an alias template declaration.

Fixed thus, bootstrapped and tested on x86_64-unknown-linux-gnu
against trunk.

gcc/cp

	PR c++/51143
	* parser.c (cp_parser_alias_declaration): Don't allow type
	definition in templates.

gcc/testsuite

	PR c++/51143
	* g++.dg/cpp0x/alias-decl-16.C: New test.
---
 gcc/cp/parser.c                            |   29 ++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C |   26 +++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C

Comments

Jason Merrill Nov. 22, 2011, 2:04 p.m. UTC | #1
Do we have a test for allowing a class definition in a non-template 
alias definition?  If not, please add that too.  OK with that change.

Jason
diff mbox

Patch

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f839112..744ad3f 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14940,6 +14940,7 @@  cp_parser_alias_declaration (cp_parser* parser)
   cp_declarator *declarator;
   cp_decl_specifier_seq decl_specs;
   bool member_p;
+  const char *saved_message = NULL;
 
   /* Look for the `using' keyword.  */
   cp_parser_require_keyword (parser, RID_USING, RT_USING);
@@ -14948,7 +14949,35 @@  cp_parser_alias_declaration (cp_parser* parser)
   attributes = cp_parser_attributes_opt (parser);
   cp_parser_require (parser, CPP_EQ, RT_EQ);
 
+  /* Now we are going to parse the type-id of the declaration.  */
+
+  /*
+    [dcl.type]/3 says:
+
+	"A type-specifier-seq shall not define a class or enumeration
+	 unless it appears in the type-id of an alias-declaration (7.1.3) that
+	 is not the declaration of a template-declaration."
+
+    In other words, if we currently are in an alias template, the
+    type-id should not define a type.
+
+    So let's set parser->type_definition_forbidden_message in that
+    case; cp_parser_check_type_definition (called by
+    cp_parser_class_specifier) will then emit an error if a type is
+    defined in the type-id.  */
+  if (parser->num_template_parameter_lists)
+    {
+      saved_message = parser->type_definition_forbidden_message;
+      parser->type_definition_forbidden_message =
+	G_("types may not be defined in alias template declarations");
+    }
+
   type = cp_parser_type_id (parser);
+
+  /* Restore the error message if need be.  */
+  if (parser->num_template_parameter_lists)
+    parser->type_definition_forbidden_message = saved_message;
+
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
   if (cp_parser_error_occurred (parser))
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C
new file mode 100644
index 0000000..882e27b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C
@@ -0,0 +1,26 @@ 
+// Origin PR c++/51143
+// { dg-options "-std=c++11" }
+
+template<int N>
+using A1 =
+    struct B1 { // { dg-error "types may not be defined in alias template" }
+        static auto constexpr value = N;
+    };
+
+A1<0> a1;
+
+template<class T>
+using A2 =
+    struct B2 {  // { dg-error "types may not be defined in alias template" }
+        void f(T){}
+    };
+
+A2<bool> a2;
+
+template<class T>
+using A3 =
+    enum B3 {b = 0;}; //{ dg-error "types may not be defined in alias template" }
+
+A3<int> a3;
+
+int main() { }