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

login
register
mail settings
Submitter Dodji Seketeli
Date Nov. 22, 2011, 4:40 p.m.
Message ID <m3obw4glfj.fsf@redhat.com>
Download mbox | patch
Permalink /patch/127127/
State New
Headers show

Comments

Dodji Seketeli - Nov. 22, 2011, 4:40 p.m.
Jason Merrill <jason@redhat.com> writes:

> Do we have a test for allowing a class definition in a non-template
> alias definition?  If not, please add that too.

Good catch.  I have a test for that in the test file.

>  OK with that change.

Thanks.  Below is what I have tested and checked in.

From: Dodji Seketeli <dodji@redhat.com>
Date: Mon, 21 Nov 2011 22:31:10 +0100
Subject: [PATCH] PR c++/51143 - Alias template allows class definition

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/ChangeLog                           |    6 +++++
 gcc/cp/parser.c                            |   29 ++++++++++++++++++++++++++++
 gcc/testsuite/ChangeLog                    |    5 ++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C |   28 +++++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C

Patch

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c083144..290538c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@ 
+2011-11-22  Dodji Seketeli  <dodji@redhat.com>
+
+	PR c++/51143
+	* parser.c (cp_parser_alias_declaration): Don't allow type
+	definition in templates.
+
 2011-11-20  Jason Merrill  <jason@redhat.com>
 
 	* pt.c (tsubst_pack_expansion): Fix SFINAE.
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/ChangeLog b/gcc/testsuite/ChangeLog
index 5c1fb00..8d6f16a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2011-11-22  Dodji Seketeli  <dodji@redhat.com>
+
+	PR c++/51143
+	* g++.dg/cpp0x/alias-decl-16.C: New test.
+
 2011-11-20  Joey Ye  <joey.ye@arm.com>
 
 	* gcc.dg/volatile-bitfields-1.c: New.
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..d66660a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C
@@ -0,0 +1,28 @@ 
+// Origin PR c++/51143
+// { dg-options "-std=c++11" }
+
+using A0 = struct B0 { void f() {} };
+
+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() { }