From db3f4e4eff2e986f8bac9c9fdfe5d8cb21f4b0e5 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 15 Jan 2001 09:30:03 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 8 +++ gcc/cp/pt.c | 61 +++++++++++++------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.old-deja/g++.pt/nontype5.C | 23 ++++++++ 4 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/nontype5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 21ca094f989..0eb13f8801c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2001-01-15 Nathan Sidwell + + * 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 * tree.c: Add defaults.h diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b0f2b560afc..8c492d51f0d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 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; +} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94814bb3044..3ea7b8086e9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-01-15 Nathan Sidwell + + * g++.old-deja/g++.pt/nontype5.C: New test. + 2001-01-15 Neil Booth * gcc.dg/cpp/if-2.c: Comment out occasionally bogus test; we diff --git a/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C b/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C new file mode 100644 index 00000000000..1268f05bcef --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/nontype5.C @@ -0,0 +1,23 @@ +// Build don't link: + +// Copyright (C) 2000 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 10 Jan 2001 + +// Bug 1509. We ICE'd on trying to coerce a non-type template parm +// that wouldn't. + +template +struct A { +typedef int F(); +}; + +template::F f> +struct B { +static int g() { return f(); }; +}; + +int f() { return 0; }; + +int main() { +return B::g(); // ERROR - could not convert arg +}; -- 2.30.2