aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-01-15 09:30:03 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-01-15 09:30:03 +0000
commitdb3f4e4eff2e986f8bac9c9fdfe5d8cb21f4b0e5 (patch)
tree6af14d88765d4932617eb76dc22f4f1303827f49 /gcc
parenteeb9ab559d1835646f8bfb83f4f2f7adda206332 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/pt.c61
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/nontype5.C23
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
+};