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
--- /dev/null
+// 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};
+}