diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2001-01-15 09:30:03 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2001-01-15 09:30:03 +0000 |
commit | db3f4e4eff2e986f8bac9c9fdfe5d8cb21f4b0e5 (patch) | |
tree | 6af14d88765d4932617eb76dc22f4f1303827f49 /gcc | |
parent | eeb9ab559d1835646f8bfb83f4f2f7adda206332 (diff) | |
download | gcc-db3f4e4eff2e986f8bac9c9fdfe5d8cb21f4b0e5.zip gcc-db3f4e4eff2e986f8bac9c9fdfe5d8cb21f4b0e5.tar.gz gcc-db3f4e4eff2e986f8bac9c9fdfe5d8cb21f4b0e5.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 61 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/nontype5.C | 23 |
4 files changed, 74 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 21ca094..0eb13f8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b0f2b56..8c492d5 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<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; +} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94814bb..3ea7b80 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 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 0000000..1268f05 --- /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 <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 +}; |