This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix PR c++/20172: Invalid non-type template parameters notdiagnosed


Consider the following code snippet:

  template<typename T> struct A
  {
      template<T> void foo();
  };
  A<void> a;

When instantiating the declarations inside A we don't check whether
non-type template parameters have valid types or not.
Thus we accept the above code although we should reject it.

The following patch fixes that by adding a test when we are substituting
the template parameters.

There's one minor issue with the patch, though. We already issued an
error in the following situation:

  template<typename T> struct A
  {
      template<T> struct X {};
  };
  A<void> a;

Unfortunately with the patch we issue two errors in this situation.
Removing the second test will cause an ICE in g++.old-deja/g++.pt/deduct3.C,
so that's not an option. Personally I'd rather have a duplicate error
message than an accepts-invalid bug.

Bootstrapped and regtested on i686-pc-linux-gnu.
Ok for mainline?

Regards,
Volker


2005-06-10  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/20172
	* pt.c (tsubst_template_parms): Check for invalid non-type parameters.

===================================================================
--- gcc/gcc/cp/pt.c	2005-04-08 21:36:01.000000000 +0200
+++ gcc/gcc/cp/pt.c	2005-06-09 01:13:03.000000000 +0200
@@ -5962,6 +5962,9 @@ tsubst_template_parms (tree parms, tree 
 	  tree parm_decl = TREE_VALUE (tuple);
 
 	  parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
+	  if (TREE_CODE (parm_decl) != TEMPLATE_DECL)
+	    invalid_nontype_parm_type_p (TREE_TYPE (parm_decl), complain);
+
 	  default_value = tsubst_template_arg (default_value, args,
 					       complain, NULL_TREE);
 	  
===================================================================

2005-06-10  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/20172
	* g++.dg/template/nontype12.C : New test.

===================================================================
--- gcc/gcc/testsuite/g++.dg/template/nontype12.C	2005-05-27 23:07:43.900843888 +0200
+++ gcc/gcc/testsuite/g++.dg/template/nontype12.C	2005-06-08 18:07:11.000000000 +0200
@@ -0,0 +1,35 @@
+// PR c++/20172
+// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+template<typename T> struct A
+{
+  template<T> int foo();                        // { dg-error "double" }
+  template<template<T> class> int bar();        // { dg-error "double" }
+  template<T> struct X;                         // { dg-error "double" }
+};
+
+A<char>   a1;
+A<double> a2;                                   // { dg-error "instantiated" }
+
+template<typename T> struct B
+{
+  template<double> int foo();                   // { dg-error "double" }
+  template<template<double> class> int bar();   // { dg-error "double" }
+  template<double> struct X;                    // { dg-error "double" }
+};
+
+template<void> int foo();                       // { dg-error "void" }
+template<template<void> class> int bar();       // { dg-error "void" }
+template<void> struct X;                        // { dg-error "void" }
+
+template<typename T> struct C
+{
+  template<T> int foo();                        // { dg-error "double" }
+};
+
+template<typename T> int baz(T) { C<T> c; }     // { dg-error "instantiated" }
+
+void foobar()
+{
+  baz(1.2);                                     // { dg-error "instantiated" }
+}
===================================================================



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]