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

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

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

Release:
3.1

Environment:
solaris 2.7

How-To-Repeat:
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 <zack@codesourcery.com>
To: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Cc:  
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:
 
  <scope_ref
     complexity 1
     arg 0 (null)
     arg 1 <identifier_node D>>
 
 We eventually get to this bit (please forgive the length of the
 extract):
 
 	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,
 				   NULL_TREE);
 		  }
 
 		/* 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;
 	      }
 	    else
 	      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;
 		continue;
 	      }
 
 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.
 
 zw

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
From: zack@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: c++/7266
Date: 25 Oct 2002 22:01:45 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Changes by:	zack@gcc.gnu.org	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
 	cp:
 	* decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a
 	SCOPE_REF is not null before dereferencing it.
 	testsuite:
 	* g++.dg/template/typename3.C: New test.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3028&r2=1.3029
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&r1=1.954&r2=1.955
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.2182&r2=1.2183
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/typename3.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
 
Comment 6 Zack Weinberg 2002-10-25 22:11:20 UTC
From: zack@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: c++/7266
Date: 25 Oct 2002 22:11:20 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Branch: 	gcc-3_2-branch
 Changes by:	zack@gcc.gnu.org	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
 	TYPE_SIZE and TYPE_SIZE_UNIT. #undef WALK_SUBTREE_TAIL at end.
 	(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
 	var_mod_type_p.
 	* langhooks-def.h: Default for tree_inlining.var_mod_type_p is
 	hook_tree_bool_false.
 	
 	* 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:
 	* cp-lang.c (cp_var_mod_type_p): New: C++ hook for
 	variably_modified_type_p.
 	* 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.
 	
 	testsuite:
 	* g++.dg/ext/vla1.C, gcc.dg/vla-2.c,
 	g++.dg/template/typename3.C: New tests.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.13152.2.657.2.105&r2=1.13152.2.657.2.106
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/c-objc-common.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.3.2.2.4.1&r2=1.3.2.2.4.2
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/hooks.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.1.10.1&r2=1.1.10.1.2.1
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/hooks.h.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.1.10.1&r2=1.1.10.1.2.1
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/langhooks-def.h.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.8.10.2.2.1&r2=1.8.10.2.2.2
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/langhooks.h.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.15.8.2.2.1&r2=1.15.8.2.2.2
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-inline.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.15.2.3.4.1&r2=1.15.2.3.4.2
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.241.2.1.4.1&r2=1.241.2.1.4.2
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.h.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.308.2.2.4.1&r2=1.308.2.2.4.2
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.2685.2.114.2.33&r2=1.2685.2.114.2.34
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-lang.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.9.10.1.2.2&r2=1.9.10.1.2.3
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.681.2.12.2.8&r2=1.681.2.12.2.9
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.866.2.36.2.8&r2=1.866.2.36.2.9
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/tree.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.268.2.7.2.2&r2=1.268.2.7.2.3
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.1672.2.166.2.39&r2=1.1672.2.166.2.40
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/vla1.C.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=NONE&r2=1.1.2.1
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/typename3.C.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=NONE&r2=1.1.2.1
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/vla-2.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=NONE&r2=1.1.2.1