pt.c (check_nontype_parm): New function.

cp:
	* pt.c (check_nontype_parm): New function.
	(process_template_parm): Use it.
	(convert_template_argument): Use it.
	(convert_nontype_argument, RECORD_TYPE): Assert it's a ptr to
	member.
testsuite:
	* g++.old-deja/g++.pt/nontype5.C: New test.

From-SVN: r39034
This commit is contained in:
Nathan Sidwell 2001-01-15 09:30:03 +00:00 committed by Nathan Sidwell
parent eeb9ab559d
commit db3f4e4eff
4 changed files with 74 additions and 22 deletions

View File

@ -1,3 +1,11 @@
2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
* pt.c (check_nontype_parm): New function.
(process_template_parm): Use it.
(convert_template_argument): Use it.
(convert_nontype_argument, RECORD_TYPE): Assert it's a ptr to
member.
2001-01-14 Jeffrey Oldham <oldham@codesourcery.com>
* tree.c: Add defaults.h

View File

@ -169,6 +169,7 @@ static tree for_each_template_parm_r PARAMS ((tree *, int *, void *));
static tree instantiate_clone PARAMS ((tree, tree));
static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
static void copy_default_args_to_explicit_spec PARAMS ((tree));
static int check_nontype_parm PARAMS ((tree, int));
/* Called once to initialize pt.c. */
@ -1933,21 +1934,8 @@ process_template_parm (list, next)
/* A template parameter is not modifiable. */
TREE_READONLY (parm) = 1;
if (IS_AGGR_TYPE (TREE_TYPE (parm))
&& TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM
&& TREE_CODE (TREE_TYPE (parm)) != TYPENAME_TYPE)
{
cp_error ("`%#T' is not a valid type for a template constant parameter",
TREE_TYPE (parm));
if (DECL_NAME (parm) == NULL_TREE)
error (" a template type parameter must begin with `class' or `typename'");
TREE_TYPE (parm) = void_type_node;
}
else if (pedantic
&& (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE
|| TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE))
cp_pedwarn ("`%T' is not a valid type for a template constant parameter",
TREE_TYPE (parm));
if (check_nontype_parm (TREE_TYPE (parm), 1))
TREE_TYPE (parm) = void_type_node;
decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
DECL_INITIAL (parm) = DECL_INITIAL (decl)
= build_template_parm_index (idx, processing_template_decl,
@ -3134,13 +3122,7 @@ convert_nontype_argument (type, expr)
case RECORD_TYPE:
{
if (!TYPE_PTRMEMFUNC_P (type))
/* This handles templates like
template<class T, T t> void f();
when T is substituted with any class. The second template
parameter becomes invalid and the template candidate is
rejected. */
return error_mark_node;
my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 20010112);
/* For a non-type template-parameter of type pointer to member
function, no conversions apply. If the template-argument
@ -3435,6 +3417,9 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
{
tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
if (check_nontype_parm (t, complain))
return error_mark_node;
if (processing_template_decl)
arg = maybe_fold_nontype_arg (arg);
@ -10316,3 +10301,35 @@ current_instantiation ()
{
return current_tinst_level;
}
/* [temp.param] Check that template non-type parm TYPE is of an allowable
type. Return zero for ok, non-zero for disallowed. If COMPLAIN is
non-zero, then complain. */
static int
check_nontype_parm (type, complain)
tree type;
int complain;
{
if (INTEGRAL_TYPE_P (type))
return 0;
else if (POINTER_TYPE_P (type))
return 0;
else if (TYPE_PTRMEM_P (type))
return 0;
else if (TYPE_PTRMEMFUNC_P (type))
return 0;
else if (!pedantic && TREE_CODE (type) == REAL_TYPE)
return 0; /* GNU extension */
else if (!pedantic && TREE_CODE (type) == COMPLEX_TYPE)
return 0; /* GNU extension */
else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
return 0;
else if (TREE_CODE (type) == TYPENAME_TYPE)
return 0;
if (complain)
cp_error ("`%#T' is not a valid type for a template constant parameter",
type);
return 1;
}

View File

@ -1,3 +1,7 @@
2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.pt/nontype5.C: New test.
2001-01-15 Neil Booth <neil@daikokuya.demon.co.uk>
* gcc.dg/cpp/if-2.c: Comment out occasionally bogus test; we

View File

@ -0,0 +1,23 @@
// Build don't link:
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 10 Jan 2001 <nathan@codesourcery.com>
// Bug 1509. We ICE'd on trying to coerce a non-type template parm
// that wouldn't.
template<class T>
struct A {
typedef int F();
};
template<class T, A<T>::F f>
struct B {
static int g() { return f(); };
};
int f() { return 0; };
int main() {
return B<int,&f>::g(); // ERROR - could not convert arg
};