[C++ PATCH] [PR13810] ICE on default argument for template template parameter (3.4/3.5 regression)

Giovanni Bajo giovannibajo@libero.it
Fri Jan 23 12:48:00 GMT 2004


Hello,

cp_parser_id_expression sometimes performs name lookup, sometimes it does not.
This is a little confusing, because user code must always check whether it
needs to do lookup or not. If it forgets to do it, we can run into ICEs, like
the one shown here. This is a quick and safe fix for the issue. I wonder if, in
the longer run, we want to have cp_parser_id_expression always performs the
lookup (or at least, add a new boolean parameter such as do_lookup for the
cases when we want to do the lookup immediatly). It'd make things more
orthogonal.

Moreover, check_template_template_default_arg was accepting TYPE_DECL as a
valid default argument. I can't see how that could have ever been correct. I
fixed it and also provided more detailed diagnostics for common cases.

Tested on i686-pc-linux-gnu, no new regressions. OK for mainline? OK for 3.4
(assuming it passes testing there as well)?

Giovanni Bajo


2004-01-23  Giovanni Bajo  <giovannibajo at gcc dot gnu dot org>

 PR c++/13810
 * parser.c (cp_parser_type_parameter): When cp_parser_id_expression
 returns a TYPE_DECL. no further lookup is required.
 * semantics.c (check_template_template_default_arg): A TYPE_DECL
 is invalid. Rework to give better diagnostics.

2004-01-23  Giovanni Bajo  <giovannibajo at gcc dot gnu dot org>

 PR c++/13810
 * g++.dg/template/ttp7.C: New test.


Index: parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.160
diff -c -3 -p -r1.160 parser.c
*** parser.c 21 Jan 2004 07:41:49 -0000 1.160
--- parser.c 23 Jan 2004 11:12:34 -0000
*************** cp_parser_type_parameter (cp_parser* par
*** 7708,7720 ****
        /*check_dependency_p=*/true,
        /*template_p=*/&is_template,
        /*declarator_p=*/false);
!      /* Look up the name.  */
!      default_argument
!        = cp_parser_lookup_name (parser, default_argument,
!            /*is_type=*/false,
!            /*is_template=*/is_template,
!            /*is_namespace=*/false,
!            /*check_dependency=*/true);
       /* See if the default argument is valid.  */
       default_argument
         = check_template_template_default_arg (default_argument);
--- 7708,7726 ----
        /*check_dependency_p=*/true,
        /*template_p=*/&is_template,
        /*declarator_p=*/false);
!      if (TREE_CODE (default_argument) == TYPE_DECL)
!        /* If the id-expression was a template-id that refers to
!    a template-class, we already have the declaration here,
!    so no further lookup is needed.  */
!        ;
!      else
!        /* Look up the name.  */
!        default_argument
!   = cp_parser_lookup_name (parser, default_argument,
!      /*is_type=*/false,
!      /*is_template=*/is_template,
!      /*is_namespace=*/false,
!      /*check_dependency=*/true);
       /* See if the default argument is valid.  */
       default_argument
         = check_template_template_default_arg (default_argument);
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.382
diff -c -3 -p -r1.382 semantics.c
*** semantics.c 19 Jan 2004 20:33:22 -0000 1.382
--- semantics.c 23 Jan 2004 11:12:39 -0000
*************** check_template_template_default_arg (tre
*** 1942,1951 ****
  {
    if (TREE_CODE (argument) != TEMPLATE_DECL
        && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
-       && TREE_CODE (argument) != TYPE_DECL
        && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
      {
!       error ("invalid default template argument");
        return error_mark_node;
      }

--- 1942,1967 ----
  {
    if (TREE_CODE (argument) != TEMPLATE_DECL
        && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
        && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
      {
!       if (TREE_CODE (argument) == TYPE_DECL)
!  {
!    tree t = TREE_TYPE (argument);
!
!    /* Try to emit a slightly smarter error message if we detect
!       that the user is using a template instantiation.  */
!    if (CLASSTYPE_TEMPLATE_INFO (t)
!        && CLASSTYPE_TEMPLATE_INSTANTIATION (t))
!      error ("`%D' is a template instantiation and cannot be used as a "
!      "default argument for a template template parameter",
!      argument);
!    else
!      error ("`%D' is not a template class and cannot be used as a "
!      "default argument for a template template parameter",
!      argument);
!  }
!       else
!  error ("invalid default argument for a template template parameter");
        return error_mark_node;
      }




// { dg-do compile }
// Contributed by Andrew Pinski <pinskia at gcc dot gnu dot org>
// PR c++/13810: ICE while parsing invalid default argument for a
//   template template parameter.

struct X;
template<int> struct A {};

template<template<int> class = X > struct B1 {};     // { dg-error "is not a
template class" }
template<template<int> class = A<0> > struct B2 {};  // { dg-error "is a
template instantiation" }





More information about the Gcc-patches mailing list