diff mbox

[C++] PR 58980

Message ID 52DE6C3E.4030708@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Jan. 21, 2014, 12:46 p.m. UTC
Hi,

in this relatively serious ICE on invalid regression (we don't emit any 
sensible diagnostic before ICE-ing) the problem is that is_ancestor 
simply asserts that the second argument can be only a NAMESPACE_DECL or 
a CLASS_TYPE_P, whereas in the erroneous input at issue it's a 
TYPENAME_TYPE. Thus the idea of not calling is_ancestor at all in this 
case + adjusting the two error_at calls to use %qT instead of %qD 
(dump_type can handle a NAMESPACE_DECL whereas dump_type can't handle a 
TYPENAME_TYPE).

Tested x86_64-linux.

Thanks,
Paolo.

//////////////////////////////
/cp
2014-01-21  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58980
	* parser.c (cp_parser_enum_specifier): Handle TYPENAME_TYPE as
	nested_name_specifier.

/testsuite
2014-01-21  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58980
	* g++.dg/parse/enum11.C: New.

Comments

Jason Merrill Jan. 21, 2014, 2:55 p.m. UTC | #1
I think I would prefer to change the "child" assert to be 
MAYBE_CLASS_TYPE_P rather than CLASS_TYPE_P.

Jason
Jason Merrill Jan. 22, 2014, 5:13 p.m. UTC | #2
On 01/21/2014 09:55 AM, Jason Merrill wrote:
> I think I would prefer to change the "child" assert to be
> MAYBE_CLASS_TYPE_P rather than CLASS_TYPE_P.

On second thought, no, I think we do want to specifically handle 
TYPENAME_TYPE.  But I think we want a different error message; getting a 
TYPENAME_TYPE here means that B has not been declared.  The current 
scope is irrelevant.  So we want to check for TYPENAME_TYPE before we 
think about checking prev_scope.

Jason
diff mbox

Patch

Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 206875)
+++ cp/parser.c	(working copy)
@@ -15471,16 +15471,19 @@  cp_parser_enum_specifier (cp_parser* parser)
 
 	  /* If that scope does not contain the scope in which the
 	     class was originally declared, the program is invalid.  */
-	  if (prev_scope && !is_ancestor (prev_scope, nested_name_specifier))
+	  if (prev_scope
+	      && (TREE_CODE (nested_name_specifier) == TYPENAME_TYPE
+		  || !is_ancestor (prev_scope, nested_name_specifier)))
 	    {
 	      if (at_namespace_scope_p ())
 		error_at (type_start_token->location,
 			  "declaration of %qD in namespace %qD which does not "
-			  "enclose %qD",
+			  "enclose %qT",
 			  type, prev_scope, nested_name_specifier);
 	      else
 		error_at (type_start_token->location,
-			  "declaration of %qD in %qD which does not enclose %qD",
+			  "declaration of %qD in %qD which does not "
+			  "enclose %qT",
 			  type, prev_scope, nested_name_specifier);
 	      type = error_mark_node;
 	    }
Index: testsuite/g++.dg/parse/enum11.C
===================================================================
--- testsuite/g++.dg/parse/enum11.C	(revision 0)
+++ testsuite/g++.dg/parse/enum11.C	(working copy)
@@ -0,0 +1,6 @@ 
+// PR c++/58980
+
+template<typename> struct A
+{ 
+  enum A::B::C {};   // { dg-error "does not enclose" }
+};