Patch for empty template argument bug
Kriang Lerdsuwanakij
lerdsuwa@scf-fs.usc.edu
Thu Feb 19 00:25:00 GMT 1998
Hi
There were a couple report about the internal compiler error caused by
empty template argument like X<>. The code that trigger the seg fault
is template template param code in coerce_template_parm -- it tries to
determine whether is_tmpl_parm should be set. The patch below changes
the design by passing the is_tmpl_parm to coerce_template_parm
directly. I also clean up the condition inside if's a bit. The is_type
code should be more readable now. :)
Kriang
============================================================================
* pt.c (coerce_template_parms) Add a new parameter, is_tmpl_parm,
all callers changed. Rely on the new parameter instead of arg
being a TREE_LIST when determine whether we are working inside
template template parameter. Clean up is_type test.
diff -rNpc gcc-old/cp/pt.c gcc/cp/pt.c
*** gcc-old/cp/pt.c Wed Feb 18 16:24:03 1998
--- gcc/cp/pt.c Wed Feb 18 22:54:58 1998
*************** static tree tsubst_expr_values PROTO((tr
*** 78,84 ****
static int comp_template_args PROTO((tree, tree));
static int list_eq PROTO((tree, tree));
static tree get_class_bindings PROTO((tree, tree, tree));
! static tree coerce_template_parms PROTO((tree, tree, tree, int, int));
static tree tsubst_enum PROTO((tree, tree, int, tree *));
static tree add_to_template_args PROTO((tree, tree));
static int type_unification_real PROTO((tree, tree *, tree, tree,
int*,
--- 78,84 ----
static int comp_template_args PROTO((tree, tree));
static int list_eq PROTO((tree, tree));
static tree get_class_bindings PROTO((tree, tree, tree));
! static tree coerce_template_parms PROTO((tree, tree, tree, int, int,
int));
static tree tsubst_enum PROTO((tree, tree, int, tree *));
static tree add_to_template_args PROTO((tree, tree));
static int type_unification_real PROTO((tree, tree *, tree, tree,
int*,
*************** convert_nontype_argument (type, expr)
*** 1726,1744 ****
If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be
provided in ARGLIST, or else trailing parameters must have default
values. If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument
! deduction for any unspecified trailing arguments. */
static tree
coerce_template_parms (parms, arglist, in_decl,
complain,
! require_all_arguments)
tree parms, arglist;
tree in_decl;
int complain;
int require_all_arguments;
{
int nparms, nargs, i, lost = 0;
- int is_tmpl_parm = 0;
tree vec = NULL_TREE;
if (arglist == NULL_TREE)
--- 1726,1749 ----
If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be
provided in ARGLIST, or else trailing parameters must have default
values. If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument
! deduction for any unspecified trailing arguments.
!
! If IS_TMPL_PARM is non-zero, we will coercing parameters of
template
! template arguments. In this case, ARGLIST is a chain of TREE_LIST
! nodes containing TYPE_DECL, TEMPLATE_DECL or PARM_DECL. */
static tree
coerce_template_parms (parms, arglist, in_decl,
complain,
! require_all_arguments,
! is_tmpl_parm)
tree parms, arglist;
tree in_decl;
int complain;
int require_all_arguments;
+ int is_tmpl_parm;
{
int nparms, nargs, i, lost = 0;
tree vec = NULL_TREE;
if (arglist == NULL_TREE)
*************** coerce_template_parms (parms, arglist, i
*** 1772,1781 ****
vec = copy_node (arglist);
else
{
- /* We can arrive here with arglist being a TREE_VEC when a
- template with some default arguments is used as template
- template argument. */
- is_tmpl_parm = TREE_CODE (arglist) == TREE_VEC;
vec = make_tree_vec (nparms);
for (i = 0; i < nparms; i++)
--- 1777,1782 ----
*************** coerce_template_parms (parms, arglist, i
*** 1819,1824 ****
--- 1820,1835 ----
tree val = 0;
int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
+ if (is_tmpl_parm && i < nargs)
+ {
+ /* In case we are checking arguments inside a template template
+ parameter, ARG that does not come from default argument is
+ also a TREE_LIST node. Note that ARG can also be a TREE_LIST
+ in other cases such as overloaded functions. */
+ if (arg != NULL_TREE && arg != error_mark_node)
+ arg = TREE_VALUE (arg);
+ }
+
if (arg == NULL_TREE)
/* We're out of arguments. */
{
*************** coerce_template_parms (parms, arglist, i
*** 1845,1858 ****
arg = TREE_VALUE (arg);
TREE_TYPE (arg) = unknown_type_node;
}
- else if (TREE_CODE (arg) == TREE_LIST && ! is_overloaded_fn
(arg))
- {
- /* In case we are checking arguments inside a template template
- parameter, ARG that does not come from default argument is
- also a TREE_LIST node */
- is_tmpl_parm = 1;
- arg = TREE_VALUE (arg);
- }
requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
requires_type = TREE_CODE (parm) == TYPE_DECL
--- 1856,1861 ----
*************** coerce_template_parms (parms, arglist, i
*** 1873,1882 ****
arg = TYPE_STUB_DECL (arg);
else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
arg = CLASSTYPE_TI_TEMPLATE (arg);
!
! is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't'
! || is_tmpl_type
! || (is_tmpl_parm && TREE_CODE (arg) == TYPE_DECL);
if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
--- 1876,1886 ----
arg = TYPE_STUB_DECL (arg);
else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
arg = CLASSTYPE_TI_TEMPLATE (arg);
!
! if (is_tmpl_parm && i < nargs)
! is_type = TREE_CODE (arg) == TYPE_DECL || is_tmpl_type;
! else
! is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't' || is_tmpl_type;
if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
*************** coerce_template_parms (parms, arglist, i
*** 1949,1955 ****
template <class T, class Allcator = allocator>
class vector. */
! val = coerce_template_parms (argparm, parmparm, in_decl, 1, 1);
if (val != error_mark_node)
val = arg;
--- 1953,1959 ----
template <class T, class Allcator = allocator>
class vector. */
! val = coerce_template_parms (argparm, parmparm, in_decl, 1, 1,
1);
if (val != error_mark_node)
val = arg;
*************** lookup_template_class (d1, arglist, in_d
*** 2304,2310 ****
CLASSTYPE_GOT_SEMICOLON (parm) = 1;
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
! arglist2 = coerce_template_parms (parmlist, arglist, template,
1, 1);
if (arglist2 == error_mark_node)
return error_mark_node;
--- 2308,2314 ----
CLASSTYPE_GOT_SEMICOLON (parm) = 1;
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
! arglist2 = coerce_template_parms (parmlist, arglist, template,
1, 1, 0);
if (arglist2 == error_mark_node)
return error_mark_node;
*************** lookup_template_class (d1, arglist, in_d
*** 2321,2327 ****
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
arglist = coerce_template_parms (parmlist, arglist, template,
! 1, 1);
if (arglist == error_mark_node)
return error_mark_node;
if (uses_template_parms (arglist))
--- 2325,2331 ----
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
arglist = coerce_template_parms (parmlist, arglist, template,
! 1, 1, 0);
if (arglist == error_mark_node)
return error_mark_node;
if (uses_template_parms (arglist))
*************** type_unification (tparms, targs, parms,
*** 4732,4738 ****
{
tree arg_vec;
arg_vec = coerce_template_parms (tparms, targs_in, NULL_TREE, 0,
! 0);
if (arg_vec == error_mark_node)
return 1;
--- 4736,4742 ----
{
tree arg_vec;
arg_vec = coerce_template_parms (tparms, targs_in, NULL_TREE, 0,
! 0, 0);
if (arg_vec == error_mark_node)
return 1;
*************** unify (tparms, targs, ntparms, parm, arg
*** 5016,5022 ****
template <class T, class Allcator = allocator>
class vector. */
! if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 1, 1)
== error_mark_node)
return 1;
--- 5020,5026 ----
template <class T, class Allcator = allocator>
class vector. */
! if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 1, 1,
0)
== error_mark_node)
return 1;
diff -rNpc gcc-old/testsuite/g++.old-deja/g++.pt/defarg2.C
gcc/testsuite/g++.old-deja/g++.pt/defarg2.C
*** gcc-old/testsuite/g++.old-deja/g++.pt/defarg2.C Wed Dec 31 16:00:00
1969
--- gcc/testsuite/g++.old-deja/g++.pt/defarg2.C Wed Feb 18 23:43:13 1998
***************
*** 0 ****
--- 1,17 ----
+ template <int S=0, class T=int>
+ struct X
+ {};
+
+ template <>
+ struct X<0,int>
+ {};
+
+ template <int S>
+ struct X<S,int>
+ : X<>
+ {};
+
+ int main()
+ {
+ X<1,int> x;
+ }
More information about the Gcc-bugs
mailing list