re PR c++/65498 (ICE in cxx_eval_call_expression when using __func__ inside dependent...
authorJason Merrill <jason@redhat.com>
Tue, 24 Mar 2015 19:38:28 +0000 (15:38 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 24 Mar 2015 19:38:28 +0000 (15:38 -0400)
PR c++/65498
* pt.c (get_mostly_instantiated_function_type): Just return the
type of the partially instantiated template in DECL_TI_TEMPLATE.

From-SVN: r221641

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/constexpr-targ2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C

index 9bc6337991bf7d59468cecde0381e43ecc8b4223..3f948fd18e10d5ca0f3b00390521d786410cabae 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-24  Jason Merrill  <jason@redhat.com>
+
+       PR c++/65498
+       * pt.c (get_mostly_instantiated_function_type): Just return the
+       type of the partially instantiated template in DECL_TI_TEMPLATE.
+
 2015-03-20  Marek Polacek  <polacek@redhat.com>
 
        PR c++/65398
index ea826211996f19dc45ded05b8d0e57a9f4164a0d..c649cad75bd61973b9daeda7dba0726b396b23d7 100644 (file)
@@ -20748,62 +20748,8 @@ tsubst_enum (tree tag, tree newtag, tree args)
 tree
 get_mostly_instantiated_function_type (tree decl)
 {
-  tree fn_type;
-  tree tmpl;
-  tree targs;
-  tree tparms;
-  int parm_depth;
-
-  tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
-  targs = DECL_TI_ARGS (decl);
-  tparms = DECL_TEMPLATE_PARMS (tmpl);
-  parm_depth = TMPL_PARMS_DEPTH (tparms);
-
-  /* There should be as many levels of arguments as there are levels
-     of parameters.  */
-  gcc_assert (parm_depth == TMPL_ARGS_DEPTH (targs));
-
-  fn_type = TREE_TYPE (tmpl);
-
-  if (parm_depth == 1)
-    /* No substitution is necessary.  */
-    ;
-  else
-    {
-      int i;
-      tree partial_args;
-
-      /* Replace the innermost level of the TARGS with NULL_TREEs to
-        let tsubst know not to substitute for those parameters.  */
-      partial_args = make_tree_vec (TREE_VEC_LENGTH (targs));
-      for (i = 1; i < TMPL_ARGS_DEPTH (targs); ++i)
-       SET_TMPL_ARGS_LEVEL (partial_args, i,
-                            TMPL_ARGS_LEVEL (targs, i));
-      SET_TMPL_ARGS_LEVEL (partial_args,
-                          TMPL_ARGS_DEPTH (targs),
-                          make_tree_vec (DECL_NTPARMS (tmpl)));
-
-      /* Make sure that we can see identifiers, and compute access
-        correctly.  */
-      push_access_scope (decl);
-
-      ++processing_template_decl;
-      /* Now, do the (partial) substitution to figure out the
-        appropriate function type.  */
-      fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE);
-      --processing_template_decl;
-
-      /* Substitute into the template parameters to obtain the real
-        innermost set of parameters.  This step is important if the
-        innermost set of template parameters contains value
-        parameters whose types depend on outer template parameters.  */
-      TREE_VEC_LENGTH (partial_args)--;
-      tparms = tsubst_template_parms (tparms, partial_args, tf_error);
-
-      pop_access_scope (decl);
-    }
-
-  return fn_type;
+  /* For a function, DECL_TI_TEMPLATE is partially instantiated.  */
+  return TREE_TYPE (DECL_TI_TEMPLATE (decl));
 }
 
 /* Return truthvalue if we're processing a template different from
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-targ2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-targ2.C
new file mode 100644 (file)
index 0000000..285d6c9
--- /dev/null
@@ -0,0 +1,40 @@
+// PR c++/65498
+// { dg-do compile { target c++11 } }
+
+template <typename, typename>
+struct is_same
+{
+  enum { value = false };
+  constexpr bool operator()() const noexcept { return value; }
+};
+
+template <typename T>
+struct is_same<T, T>
+{
+  enum { value = true };
+  constexpr bool operator()() const noexcept { return value; }
+};
+
+template <bool, typename = void>
+struct enable_if { };
+
+template <typename T>
+struct enable_if<true, T> { typedef T type; };
+
+struct A;
+
+template <typename, typename = void>
+struct F { };
+
+template <typename X>
+struct F<X, typename enable_if<is_same<X, A>{}()>::type> {
+    template <typename MakeDependent>
+    F(MakeDependent) {
+        auto ICE_HERE = __func__;
+        (void)ICE_HERE; // avoid -Wunused-variable
+    }
+};
+
+int main() {
+    F<A>{1};
+}
index 2b1a605acd00277d67f7aff6d9697b32d088bd00..01fe3f66cf4bee53422ccebe5c759052b06c38ef 100644 (file)
@@ -20,5 +20,5 @@ void bar ()
   c.foo (1);
 }
 
-// { dg-final { scan-assembler "_ZN8functionC1IZN1CIiE3fooIiEEvT_S_Ed_UlvE_EET_" } }
+// { dg-final { scan-assembler "_ZN8functionC1IZN1CIiE3fooIiEEvT_S_Ed_UlvE_EES4_" } }
 // { dg-final { scan-assembler-not "_ZZN1CIiE3fooIiEEvT_8functionEd_NKUlvE_clEv" } }