User account creation filtered due to spam.

Bug 7266 - pedantic segfaults on missing typename
Summary: pedantic segfaults on missing typename
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.1
: P3 normal
Target Milestone: ---
Assignee: Zack Weinberg
Keywords: ice-on-invalid-code
Depends on:
Reported: 2002-07-10 12:26 UTC by glisse
Modified: 2005-02-09 02:18 UTC (History)
2 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description glisse 2002-07-10 12:26:00 UTC
If one omits the typename in the following code:
template <class A> struct B {typedef A::C::D E;};
compiled with g++ -pedantic
test.cpp:1: warning: ISO C++ forbids declaration of `D' with no type
test.cpp:1: internal error: Segmentation Fault


solaris 2.7

template <class A> struct B {typedef A::C::D E;};
compiled with g++ -pedantic
Comment 1 Kriang Lerdsuwanakij 2002-07-11 08:24:43 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed.  A regression from 3.0.
Comment 2 Zack Weinberg 2002-10-24 11:56:30 UTC
From: Zack Weinberg <>
Subject: Re: c++/7266 [Candidate fix]
Date: Thu, 24 Oct 2002 11:56:30 -0700

 PR c++/7266 reports a crash on the ill-formed
 template <class A> struct B {typedef A::C::D E;};
 grokdeclarator is called with this declarator:
     complexity 1
     arg 0 (null)
     arg 1 <identifier_node D>>
 We eventually get to this bit (please forgive the length of the
 	case SCOPE_REF:
 	    /* We have converted type names to NULL_TREE if the
 	       name was bogus, or to a _TYPE node, if not.
 	       The variable CTYPE holds the type we will ultimately
 	       resolve to.  The code here just needs to build
 	       up appropriate member types.  */
 	    tree sname = TREE_OPERAND (declarator, 1);
 	    tree t;
 	    /* Destructors can have their visibilities changed as well.  */
 	    if (TREE_CODE (sname) == BIT_NOT_EXPR)
 	      sname = TREE_OPERAND (sname, 0);
 	    if (TREE_COMPLEXITY (declarator) == 0)
 	      /* This needs to be here, in case we are called
 		 multiple times.  */ ;
 	    else if (TREE_COMPLEXITY (declarator) == -1)
 	      /* Namespace member.  */
 	      pop_decl_namespace ();
 	    else if (friendp && (TREE_COMPLEXITY (declarator) < 2))
 	      /* Don't fall out into global scope. Hides real bug? --eichin */ ;
 	    else if (! IS_AGGR_TYPE_CODE
 ***		     (TREE_CODE (TREE_OPERAND (declarator, 0))))
 	    else if (TREE_COMPLEXITY (declarator) == current_class_depth)
 		/* Resolve any TYPENAME_TYPEs from the decl-specifier-seq
 		   that refer to ctype.  They couldn't be resolved earlier
 		   because we hadn't pushed into the class yet.
 		   Example: resolve 'B<T>::type' in
 		   'B<typename B<T>::type> B<T>::f () { }'.  */
 		if (current_template_parms
 		    && uses_template_parms (type)
 		    && uses_template_parms (current_class_type))
 		    tree args = current_template_args ();
 		    type = tsubst (type, args, tf_error | tf_warning,
 		/* This pop_nested_class corresponds to the
                    push_nested_class used to push into class scope for
                    parsing the argument list of a function decl, in
                    qualified_id.  */
 		pop_nested_class ();
 		TREE_COMPLEXITY (declarator) = current_class_depth;
 	      abort ();
 @@@	    if (TREE_OPERAND (declarator, 0) == NULL_TREE)
 		/* We had a reference to a global decl, or
 		   perhaps we were given a non-aggregate typedef,
 		   in which case we cleared this out, and should just
 		   keep going as though it wasn't there.  */
 		declarator = sname;
 The crash happens at the starred line.  TREE_OPERAND (declarator, 0)
 is NULL, so attempting to take TREE_CODE of it naturally segfaults.
 Note the block below marked with at-signs.  Moving it above the series
 of tests on TREE_COMPLEXITY makes the crash go away.  Furthermore,
 what that block does to a SCOPE_REF with null first operand makes
 some sense for this situation.  So that's a candidate fix for the bug.
 However, I'm not confident that the rest of the code fragment here is
 correct.  What's a test of IS_AGGR_TYPE_CODE doing in the middle of
 checks of the TREE_COMPLEXITY of the declarator, anyway?
 current_class_depth is 1; should we have had a chance to execute the
 block for TREE_COMPLEXITY (declarator) == current_class_depth before
 we "just keep going as though it wasn't there"?  Or the other way
 around?  Why does that block set TREE_COMPLEXITY (declarator) to the
 value it presumably already has?
 C++ folks, thoughts would be appreciated.

Comment 3 Zack Weinberg 2002-10-24 12:01:26 UTC
Responsible-Changed-From-To: unassigned->zack
Responsible-Changed-Why: Working on a fix.
Comment 4 Zack Weinberg 2002-10-25 15:15:51 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Fixed in 3.2.1 and 3.3.
Comment 5 Zack Weinberg 2002-10-25 22:01:45 UTC
Subject: c++/7266
Date: 25 Oct 2002 22:01:45 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Changes by:	2002-10-25 15:01:44
 Modified files:
 	gcc/cp         : ChangeLog decl.c 
 	gcc/testsuite  : ChangeLog 
 Added files:
 	gcc/testsuite/g++.dg/template: typename3.C 
 Log message:
 	PR c++/7266
 	* decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a
 	SCOPE_REF is not null before dereferencing it.
 	* g++.dg/template/typename3.C: New test.
Comment 6 Zack Weinberg 2002-10-25 22:11:20 UTC
Subject: c++/7266
Date: 25 Oct 2002 22:11:20 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Branch: 	gcc-3_2-branch
 Changes by:	2002-10-25 15:11:19
 Modified files:
 	gcc            : ChangeLog c-objc-common.c hooks.c hooks.h 
 	                 langhooks-def.h langhooks.h tree-inline.c 
 	                 tree.c tree.h 
 	gcc/cp         : ChangeLog cp-lang.c cp-tree.h decl.c tree.c 
 	gcc/testsuite  : ChangeLog 
 Added files:
 	gcc/testsuite/g++.dg/ext: vla1.C 
 	gcc/testsuite/g++.dg/template: typename3.C 
 	gcc/testsuite/gcc.dg: vla-2.c 
 Log message:
 	PR middle-end/6994
 	* c-objc-common.c (inline_forbidden_p): Can not inline
 	functions containing structures or unions containing VLAs.
 	* tree-inline.c (walk_tree): For all class 't' nodes, walk
 	(copy_tree_r): Copy types if they are variably modified.
 	* hooks.c (hook_tree_bool_false): New.
 	* hooks.h: Prototype it.
 	* langhooks.h (struct lang_hooks_for_tree_inlining): Add
 	* langhooks-def.h: Default for tree_inlining.var_mod_type_p is
 	* tree.c (variably_modified_type_p): Moved here from
 	cp/tree.c.  Use lang_hooks.tree_inlining.var_mod_type_p for
 	language-specific cases.  Due to this, must weaken some 'if
 	and only if' checks to merely 'if'.
 	* tree.h: Prototype variably_modified_type_p.
 	* cp-lang.c (cp_var_mod_type_p): New: C++ hook for
 	* cp-tree.h: Remove prototype of variably_modified_type_p.
 	* tree.c (variably_modified_type_p): Remove; now implemented
 	in language-independent code.
 	PR c++/7266
 	* decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a
 	SCOPE_REF is not null before dereferencing it.
 	* g++.dg/ext/vla1.C, gcc.dg/vla-2.c,
 	g++.dg/template/typename3.C: New tests.