re PR c++/29733 (ICE on initialization of function type)
authorMark Mitchell <mark@codesourcery.com>
Mon, 4 Dec 2006 18:08:11 +0000 (18:08 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 4 Dec 2006 18:08:11 +0000 (18:08 +0000)
PR c++/29733
* pt.c (tsubst_decl): Disallow variables of function type.
PR c++/29733
* g++.dg/template/crash61.C: New test.

From-SVN: r119500

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/crash61.C [new file with mode: 0644]

index a4c1a1132627e8ac72fb95d42ba2cc814c0facae..f0f93c0e40c4d791fed38303be6216578d6e59da 100644 (file)
@@ -1,5 +1,8 @@
 2006-12-04  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/29733
+       * pt.c (tsubst_decl): Disallow variables of function type.
+
        PR c++/29632
        * call.c (add_builtin_candidate): Do not permit NULL pointer
        constants to be compared with template parameters.
index 0b8eecac3ff4cd16ada73a383a58613c112991ea..acaf6bce00f75cf29f4ca8243f74e43e93e8514e 100644 (file)
@@ -6954,6 +6954,27 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            if (type == error_mark_node)
              return error_mark_node;
+           if (TREE_CODE (type) == FUNCTION_TYPE)
+             {
+               /* It may seem that this case cannot occur, since:
+
+                    typedef void f();
+                    void g() { f x; }
+
+                  declares a function, not a variable.  However:
+      
+                    typedef void f();
+                    template <typename T> void g() { T t; }
+                    template void g<f>();
+
+                  is an attempt to declare a variable with function
+                  type.  */
+               error ("variable %qD has function type",
+                      /* R is not yet sufficiently initialized, so we
+                         just use its name.  */
+                      DECL_NAME (r));
+               return error_mark_node;
+             }
            type = complete_type (type);
            DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
              = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
index 3e0e6412e4fffc4031bdbb541c2ef2afdd02be78..0d558084d4a1157991948972a39127d20f605439 100644 (file)
@@ -1,5 +1,8 @@
 2006-12-04  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/29733
+       * g++.dg/template/crash61.C: New test. 
+
        PR c++/29632
        * g++.dg/template/error23.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/template/crash61.C b/gcc/testsuite/g++.dg/template/crash61.C
new file mode 100644 (file)
index 0000000..1f70bcb
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/29733
+
+template<typename T> void foo()
+{
+  T t = 0; // { dg-error "function type" }
+}
+
+void bar()
+{
+  foo<int()>();
+}