public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
@ 2013-01-08 13:58 Dodji Seketeli
  2013-01-08 16:44 ` Gabriel Dos Reis
  2013-01-08 19:53 ` Jason Merrill
  0 siblings, 2 replies; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-08 13:58 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jason Merrill

Hello,

Consider the example of the problem report

     1	template <typename>
     2	constexpr bool the_truth () { return true; }
     3
     4	template <bool>
     5	  struct Takes_bool { };
     6
     7	template<bool B>
     8	  using Alias = Takes_bool<B>;
     9
    10	template<typename T>
    11	  struct test { using type = Alias<the_truth<T>()>; };
    12
    13	int main () {
    14	  test<int> a;
    15
    16	  return 0;
    17	}

that yields the error:

    test.cc: In substitution of ‘template<bool B> using Alias = Takes_bool<B> [with bool B = the_truth<int>()]’:
    test.cc:11:51:   required from ‘struct test<int>’
    test.cc:14:13:   required from here
    test.cc:11:51: error: integral expression ‘the_truth<int>()’ is not constant
       struct test { using type = Alias<the_truth<T>()>; };

I think the issue happens in the course of instantiating test<int> at
line 14, when we look into instantiating Alias<the_truth<T>()> (at
line 11), with T = int.

There, when we check the argument 'the_truth<int>()' to see if it
actually is a constant expression, in check_instantiated_arg, we fail
to recognize its constexpr-ness b/c we just look at its TREE_CONSTANT.

Would the patch below be ok-ish in testing for the const-ness of that
argument in a general enough way that takes into account its
constexpr-ness?

Bootstapped and tested on x86_64-unknown-linux-gnu against trunk.

gcc/cp/

	PR c++/55663
	* cp-tree.h (cxx_is_constant_expression): Declare ...
	* semantics.c (cxx_is_constant_expression): ... new function.
	* pt.c (check_instantiated_arg): Use the new
	cxx_is_constant_expression in lieu of TREE_CONSTANT.

gcc/testsuite/

	PR c++/55663
	* g++.dg/cpp0x/alias-decl-31.C: New test.
---
 gcc/cp/cp-tree.h                           |  1 +
 gcc/cp/pt.c                                |  2 +-
 gcc/cp/semantics.c                         |  9 +++++++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C | 20 ++++++++++++++++++++
 4 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 810df7d..9d52ba7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5608,6 +5608,7 @@ extern bool potential_rvalue_constant_expression (tree);
 extern bool require_potential_constant_expression (tree);
 extern bool require_potential_rvalue_constant_expression (tree);
 extern tree cxx_constant_value (tree);
+extern bool cxx_is_constant_expression (tree);
 extern tree maybe_constant_value (tree);
 extern tree maybe_constant_init (tree);
 extern bool is_sub_constant_expr (tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 30bafa0..74ccfbf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14426,7 +14426,7 @@ check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain)
      constant.  */
   else if (TREE_TYPE (t)
 	   && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t))
-	   && !TREE_CONSTANT (t))
+	   && !cxx_is_constant_expression (t))
     {
       if (complain & tf_error)
 	error ("integral expression %qE is not constant", t);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 2e02295..e40d48f 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8077,6 +8077,15 @@ cxx_constant_value (tree t)
   return cxx_eval_outermost_constant_expr (t, false);
 }
 
+/* Return TRUE iff E is a constant expression.  */
+
+bool
+cxx_is_constant_expression (tree e)
+{
+  tree t = cxx_constant_value (e);
+  return (t != error_mark_node && t != NULL_TREE);
+}
+
 /* If T is a constant expression, returns its reduced value.
    Otherwise, if T does not have TREE_CONSTANT set, returns T.
    Otherwise, returns a version of T without TREE_CONSTANT.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
new file mode 100644
index 0000000..83eea47
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
@@ -0,0 +1,20 @@
+// Origin: PR c++/55663
+// { dg-do compile { target c++11 } }
+
+template <typename>
+constexpr bool the_truth () { return true; }
+
+template <bool>
+  struct Takes_bool { };
+
+template<bool B>
+  using Alias = Takes_bool<B>;
+
+template<typename T>
+  struct test { using type = Alias<the_truth<T>()>; };
+
+int main () {
+  test<int> a;
+
+  return 0;
+}
-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-08 13:58 [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg Dodji Seketeli
@ 2013-01-08 16:44 ` Gabriel Dos Reis
  2013-01-09 15:31   ` Dodji Seketeli
  2013-01-08 19:53 ` Jason Merrill
  1 sibling, 1 reply; 18+ messages in thread
From: Gabriel Dos Reis @ 2013-01-08 16:44 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: GCC Patches, Jason Merrill

On Tue, Jan 8, 2013 at 7:58 AM, Dodji Seketeli <dodji@redhat.com> wrote:
> Hello,
>
> Consider the example of the problem report
>
>      1  template <typename>
>      2  constexpr bool the_truth () { return true; }
>      3
>      4  template <bool>
>      5    struct Takes_bool { };
>      6
>      7  template<bool B>
>      8    using Alias = Takes_bool<B>;
>      9
>     10  template<typename T>
>     11    struct test { using type = Alias<the_truth<T>()>; };
>     12
>     13  int main () {
>     14    test<int> a;
>     15
>     16    return 0;
>     17  }
>
> that yields the error:
>
>     test.cc: In substitution of ‘template<bool B> using Alias = Takes_bool<B> [with bool B = the_truth<int>()]’:
>     test.cc:11:51:   required from ‘struct test<int>’
>     test.cc:14:13:   required from here
>     test.cc:11:51: error: integral expression ‘the_truth<int>()’ is not constant
>        struct test { using type = Alias<the_truth<T>()>; };
>
> I think the issue happens in the course of instantiating test<int> at
> line 14, when we look into instantiating Alias<the_truth<T>()> (at
> line 11), with T = int.
>
> There, when we check the argument 'the_truth<int>()' to see if it
> actually is a constant expression, in check_instantiated_arg, we fail
> to recognize its constexpr-ness b/c we just look at its TREE_CONSTANT.

Thanks for the detective work!

We already have various predicates  to test for constant
expressions so I am uneasy to add yet another one.

What we do no need -- which I already suggested -- is a
predicate to test valid non-type template arguments.

For example, we already have the predicate verify_constant
and reduced_constant_expression_p, require_potential_constant_expression.

I think reduced_constant_expression_p is what you want.

-- Gaby

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-08 13:58 [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg Dodji Seketeli
  2013-01-08 16:44 ` Gabriel Dos Reis
@ 2013-01-08 19:53 ` Jason Merrill
  2013-01-09 15:03   ` Dodji Seketeli
  1 sibling, 1 reply; 18+ messages in thread
From: Jason Merrill @ 2013-01-08 19:53 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: GCC Patches

On 01/08/2013 08:58 AM, Dodji Seketeli wrote:
> There, when we check the argument 'the_truth<int>()' to see if it
> actually is a constant expression, in check_instantiated_arg, we fail
> to recognize its constexpr-ness b/c we just look at its TREE_CONSTANT.

The problem is that by the time we get to check_instantiated_arg, we 
should have folded the expression into something TREE_CONSTANT. 
convert_template_argument should have done that; don't we ever call that 
function for this template argument?

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-08 19:53 ` Jason Merrill
@ 2013-01-09 15:03   ` Dodji Seketeli
  2013-01-09 16:17     ` Jason Merrill
  0 siblings, 1 reply; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-09 15:03 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

Jason Merrill <jason@redhat.com> writes:

> On 01/08/2013 08:58 AM, Dodji Seketeli wrote:
>> There, when we check the argument 'the_truth<int>()' to see if it
>> actually is a constant expression, in check_instantiated_arg, we fail
>> to recognize its constexpr-ness b/c we just look at its TREE_CONSTANT.
>
> The problem is that by the time we get to check_instantiated_arg, we
> should have folded the expression into something
> TREE_CONSTANT. convert_template_argument should have done that; don't
> we ever call that function for this template argument?

Presumably, you mean that convert_template_argument should call
convert_nontype_argument to do that folding, right?

I guess the reason why it's not doing it is that the call to
convert_nontype_argument is conditional on

      else if (!uses_template_parms (orig_arg) && !uses_template_parms (t))
	/* We used to call digest_init here.  However, digest_init
	   will report errors, which we don't want when complain
	   is zero.  More importantly, digest_init will try too
	   hard to convert things: for example, `0' should not be
	   converted to pointer type at this point according to
	   the standard.  Accepting this is not merely an
	   extension, since deciding whether or not these
	   conversions can occur is part of determining which
	   function template to call, or whether a given explicit
	   argument specification is valid.  */
	val = convert_nontype_argument (t, orig_arg, complain);

As the argument 'the_truth<T>()' we care about is type dependant,
uses_template_parms returns true and so convert_nontype_argument is
never called.

What is your preferred way want to handle this?

-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-08 16:44 ` Gabriel Dos Reis
@ 2013-01-09 15:31   ` Dodji Seketeli
  2013-01-09 16:14     ` Gabriel Dos Reis
  0 siblings, 1 reply; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-09 15:31 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: GCC Patches, Jason Merrill

Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

> We already have various predicates  to test for constant
> expressions so I am uneasy to add yet another one.

I understand.  I got lost in the number of existing predicates to test
for constant expressions, to the point that I thought (wrongly) the one
I wanted wasn't present.  :-)

> I think reduced_constant_expression_p is what you want.

Thanks.  I didn't realize this would work because the comment of
initializer_constant_valid_p (that it uses) says:

    We assume that VALUE has been folded as much as possible

On a side node, as Jason said in the thread, we might not even need to
touch anything here, as check_instantiated_arg also assumes that its arg
has been fully folded.  I guess I'll propose to update the comment of
that function to reflect that assumption.

Thanks.

-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-09 15:31   ` Dodji Seketeli
@ 2013-01-09 16:14     ` Gabriel Dos Reis
  2013-01-10 15:22       ` Dodji Seketeli
  0 siblings, 1 reply; 18+ messages in thread
From: Gabriel Dos Reis @ 2013-01-09 16:14 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: GCC Patches, Jason Merrill

On Wed, Jan 9, 2013 at 9:30 AM, Dodji Seketeli <dodji@redhat.com> wrote:
> Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
>
>> We already have various predicates  to test for constant
>> expressions so I am uneasy to add yet another one.
>
> I understand.  I got lost in the number of existing predicates to test
> for constant expressions,

so am I :-)

> to the point that I thought (wrongly) the one I wanted wasn't present.  :-)
>
>> I think reduced_constant_expression_p is what you want.
>
> Thanks.  I didn't realize this would work because the comment of
> initializer_constant_valid_p (that it uses) says:
>
>     We assume that VALUE has been folded as much as possible
>
> On a side node, as Jason said in the thread, we might not even need to
> touch anything here, as check_instantiated_arg also assumes that its arg
> has been fully folded.  I guess I'll propose to update the comment of
> that function to reflect that assumption.

I read your reply.  I am now even more puzzled
than before.  The call to uses_template_parm indicates that
we expect that code to work when are also when processing a template
(e.g. for non-dependent cases inside a template.)
That makes me wonder how it could possibly work for the
cases at hand because for non-type template arguments we need
full instantiation information to determine convertibility and "constant"ness.

-- Gaby

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-09 15:03   ` Dodji Seketeli
@ 2013-01-09 16:17     ` Jason Merrill
  0 siblings, 0 replies; 18+ messages in thread
From: Jason Merrill @ 2013-01-09 16:17 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: GCC Patches

On 01/09/2013 10:02 AM, Dodji Seketeli wrote:
> As the argument 'the_truth<T>()' we care about is type dependant,
> uses_template_parms returns true and so convert_nontype_argument is
> never called.

Right, but we should call it for the instantiated argument, too.  We do 
that for class templates by calling lookup_template_class again, which 
calls coerce_template_parms.  We need to make sure we call 
coerce_template_parms when instantiating alias templates, too.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-09 16:14     ` Gabriel Dos Reis
@ 2013-01-10 15:22       ` Dodji Seketeli
  2013-01-10 16:02         ` Gabriel Dos Reis
  2013-01-10 16:11         ` Gabriel Dos Reis
  0 siblings, 2 replies; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-10 15:22 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: GCC Patches, Jason Merrill

Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

> I read your reply.  I am now even more puzzled
> than before.  The call to uses_template_parm indicates that
> we expect that code to work when are also when processing a template
> (e.g. for non-dependent cases inside a template.)
> That makes me wonder how it could possibly work for the
> cases at hand because for non-type template arguments we need
> full instantiation information to determine convertibility and
> "constant"ness.

I introduced the confusion, sorry.  I overlooked the fact that this is
actually happening while calling instantiate_alias_template on Alias
with the argument the_thruth<int> non folded.  In that code patch, we
didn't even go through convert_template_argument like what I was saying.
More on this below.

Jason Merrill <jason@redhat.com> writes:

> On 01/09/2013 10:02 AM, Dodji Seketeli wrote:
>> As the argument 'the_truth<T>()' we care about is type dependant,
>> uses_template_parms returns true and so convert_nontype_argument is
>> never called.
>
> Right, but we should call it for the instantiated argument, too.  We
> do that for class templates by calling lookup_template_class again,
> which calls coerce_template_parms.  We need to make sure we call
> coerce_template_parms when instantiating alias templates, too.

Indeed.

The problem is happening during the instantiation of test<int> using
instantiate_class_template.  In that case the argument {int} was
previously properly coerced and stored in CLASSTYPE_TI_ARGS by
lookup_class_template, as you are saying.  So instantiate_class_template
always uses coerced arguments.

But during the instantiation of the *members* of test<int>, we try to
instantiate Alias<the_truth<int>>, without coercing (and thus without
folding) the argument {the_truth<int>}.  We do this using
instantiate_alias_template, called from tsubst.

The patch below makes sure instantiate_alias_template coerces the
arguments it uses to instantiate the alias template, like what I
understood you are suggesting.  I have tested it without boostrap and a
full boostrap is currently running.

If this approach looks acceptable, could I replace (part of) the
template argument coercing code in lookup_class_template_1 with the new
coerce_template_parms_all_level I introduced in this patch?

Also, I am not sure if this patch would be appropriate for commit, now
that we are in 'regression-only' mode.  But seeing this alias-template
related thing not working hurts me.  :)  So at worst I'll schedule the
patch for when stage1 opens again.

Thanks.

gcc/cp/

	PR c++/55663
	* pt.c (coerce_template_parms_all_levels): New static function.
	(instantiate_alias_template):  Use it here.

gcc/testsuite/

	PR c++/55663
	* g++.dg/cpp0x/alias-decl-31.C: New test.
---
 gcc/cp/pt.c                                | 64 +++++++++++++++++++++++++++++-
 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C | 20 ++++++++++
 2 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 30bafa0..aadc173 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -130,6 +130,8 @@ static tree tsubst_initializer_list (tree, tree);
 static tree get_class_bindings (tree, tree, tree, tree);
 static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
 				   bool, bool);
+static tree coerce_template_parms_all_levels (tree, tree, tree, tsubst_flags_t,
+					      bool, bool);
 static void tsubst_enum	(tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
@@ -6742,6 +6744,58 @@ coerce_template_parms (tree parms,
   return new_inner_args;
 }
 
+/* Like coerce_template_parms.  If PARMS represents all template
+   parameters levels, this function returns a vector of vectors
+   representing all the resulting argument levels.  Note that in this
+   case, only the innermost arguments are coerced because the
+   outermost ones are supposed to have been coerced already.
+
+   Otherwise, if PARMS represents only (the innermost) vectors of
+   parameters, returns a vector containing just the innermost
+   resulting arguments.  */
+
+static tree
+coerce_template_parms_all_levels (tree parms,
+				  tree args,
+				  tree in_decl,
+				  tsubst_flags_t complain,
+				  bool require_all_args,
+				  bool use_default_args)
+{
+  int parms_depth = TMPL_PARMS_DEPTH (parms);
+  int args_depth = TMPL_ARGS_DEPTH (args);
+  tree coerced_args;
+
+  if (parms_depth > 1)
+    {
+      coerced_args = make_tree_vec (parms_depth);
+      tree level;
+      int cur_depth;
+
+      for (level = parms, cur_depth = parms_depth;
+	   parms_depth > 0 && level != NULL_TREE;
+	   level = TREE_CHAIN (level), --cur_depth)
+	{
+	  tree l;
+	  if (cur_depth == args_depth)
+	    l = coerce_template_parms (TREE_VALUE (level),
+				       args, in_decl, complain,
+				       require_all_args,
+				       use_default_args);
+	  else
+	    l = TMPL_ARGS_LEVEL (args, cur_depth);
+
+	  SET_TMPL_ARGS_LEVEL (coerced_args, cur_depth, l);
+	}
+    }
+  else
+    coerced_args = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parms),
+					  args, in_decl, complain,
+					  require_all_args,
+					  use_default_args);
+  return coerced_args;
+}
+
 /* Returns 1 if template args OT and NT are equivalent.  */
 
 static int
@@ -14637,7 +14691,15 @@ instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain)
       ggc_free (tinst);
       return error_mark_node;
     }
-  tree r = instantiate_template (tmpl, args, complain);
+
+  tree coerced_args =
+    coerce_template_parms_all_levels (DECL_TEMPLATE_PARMS (tmpl),
+				      args, tmpl, complain,
+				      /*require_all_args=*/true,
+				      /*use_default_args=*/true);
+
+  tree r = instantiate_template (tmpl, coerced_args, complain);
+
   pop_tinst_level ();
   /* We can't free this if a pending_template entry or last_error_tinst_level
      is pointing at it.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
new file mode 100644
index 0000000..83eea47
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
@@ -0,0 +1,20 @@
+// Origin: PR c++/55663
+// { dg-do compile { target c++11 } }
+
+template <typename>
+constexpr bool the_truth () { return true; }
+
+template <bool>
+  struct Takes_bool { };
+
+template<bool B>
+  using Alias = Takes_bool<B>;
+
+template<typename T>
+  struct test { using type = Alias<the_truth<T>()>; };
+
+int main () {
+  test<int> a;
+
+  return 0;
+}
-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-10 15:22       ` Dodji Seketeli
@ 2013-01-10 16:02         ` Gabriel Dos Reis
  2013-01-11 10:41           ` Dodji Seketeli
  2013-01-10 16:11         ` Gabriel Dos Reis
  1 sibling, 1 reply; 18+ messages in thread
From: Gabriel Dos Reis @ 2013-01-10 16:02 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: GCC Patches, Jason Merrill

On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli <dodji@redhat.com> wrote:
>
> Also, I am not sure if this patch would be appropriate for commit, now
> that we are in 'regression-only' mode.  But seeing this alias-template
> related thing not working hurts me.  :)  So at worst I'll schedule the
> patch for when stage1 opens again.

It is certainly a blocker for some people here using both constexpr
and template alias.  (The code uses a technique documented in the
upcoming 4th edition of TC++PL which is due anytime now.  It would be
embarrassing if GCC-4.8 didn't accept it.)

-- Gaby

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-10 15:22       ` Dodji Seketeli
  2013-01-10 16:02         ` Gabriel Dos Reis
@ 2013-01-10 16:11         ` Gabriel Dos Reis
  2013-01-10 17:01           ` Jason Merrill
  2013-01-11 10:38           ` Dodji Seketeli
  1 sibling, 2 replies; 18+ messages in thread
From: Gabriel Dos Reis @ 2013-01-10 16:11 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: GCC Patches, Jason Merrill

On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli <dodji@redhat.com> wrote:

> But during the instantiation of the *members* of test<int>, we try to
> instantiate Alias<the_truth<int>>, without coercing (and thus without
> folding) the argument {the_truth<int>}.  We do this using
> instantiate_alias_template, called from tsubst.
>
> The patch below makes sure instantiate_alias_template coerces the
> arguments it uses to instantiate the alias template, like what I
> understood you are suggesting.  I have tested it without boostrap and a
> full boostrap is currently running.

Hmm, is it necessary to coerce all levels as opposed to just the
innermost arguments?

-- Gaby

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-10 16:11         ` Gabriel Dos Reis
@ 2013-01-10 17:01           ` Jason Merrill
  2013-01-11 10:38           ` Dodji Seketeli
  1 sibling, 0 replies; 18+ messages in thread
From: Jason Merrill @ 2013-01-10 17:01 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Dodji Seketeli, GCC Patches

On 01/10/2013 11:11 AM, Gabriel Dos Reis wrote:
> Hmm, is it necessary to coerce all levels as opposed to just the
> innermost arguments?

No.  But if you read the code, it's really only coercing the innermost 
level.  Just the name is misleading.

> If this approach looks acceptable, could I replace (part of) the
> template argument coercing code in lookup_class_template_1 with the new
> coerce_template_parms_all_level I introduced in this patch?

Yes.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-10 16:11         ` Gabriel Dos Reis
  2013-01-10 17:01           ` Jason Merrill
@ 2013-01-11 10:38           ` Dodji Seketeli
  2013-01-11 14:53             ` Jason Merrill
  1 sibling, 1 reply; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-11 10:38 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: GCC Patches, Jason Merrill

Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

> On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli <dodji@redhat.com> wrote:
>
>> But during the instantiation of the *members* of test<int>, we try to
>> instantiate Alias<the_truth<int>>, without coercing (and thus without
>> folding) the argument {the_truth<int>}.  We do this using
>> instantiate_alias_template, called from tsubst.
>>
>> The patch below makes sure instantiate_alias_template coerces the
>> arguments it uses to instantiate the alias template, like what I
>> understood you are suggesting.  I have tested it without boostrap and a
>> full boostrap is currently running.
>
> Hmm, is it necessary to coerce all levels as opposed to just the
> innermost arguments?
>
> -- Gaby

Jason Merrill <jason@redhat.com> writes:

> On 01/10/2013 11:11 AM, Gabriel Dos Reis wrote:
>> Hmm, is it necessary to coerce all levels as opposed to just the
>> innermost arguments?
>
> No.  But if you read the code, it's really only coercing the innermost
> level.

Correct.  I even documented that in the descriptive comment of the
function.  But ...

>  Just the name is misleading.

... as the name seems to be confusing, I have changed it to
coerce_innermost_template_parms.  I hope that is less confusing.

>> If this approach looks acceptable, could I replace (part of) the
>> template argument coercing code in lookup_class_template_1 with the new
>> coerce_template_parms_all_level I introduced in this patch?
>
> Yes.

OK.  I have done that in the patch below that passed bootstrap and
regression testing on x86_64-unknown-linux-gnu against trunk.

If nothing else, I'd need your opinion on this; in the template argument
coercing code in lookup_template_1 does this:

	      /* We temporarily reduce the length of the ARGLIST so
		 that coerce_template_parms will see only the arguments
		 corresponding to the template parameters it is
		 examining.  */
	      TREE_VEC_LENGTH (arglist)--;

but when I read the code, it looks like this is not necessary.  Am I
missing something?  In any case, I haven't put that code in the new
coerce_innermost_template_parms.  Is that OK?

Thanks.

gcc/cp/

	PR c++/55663
	* pt.c (coerce_innermost_template_parms): New static function.
	(instantiate_alias_template):  Use it here.
	(lookup_template_class_1): Use it here too, for ease of
	maintenance's sake.

gcc/testsuite/

	PR c++/55663
	* g++.dg/cpp0x/alias-decl-31.C: New test.
---
 gcc/cp/pt.c                                | 130 ++++++++++++++++-------------
 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C |  20 +++++
 2 files changed, 93 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 30bafa0..67e6c97 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -130,6 +130,8 @@ static tree tsubst_initializer_list (tree, tree);
 static tree get_class_bindings (tree, tree, tree, tree);
 static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
 				   bool, bool);
+static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t,
+					      bool, bool);
 static void tsubst_enum	(tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
@@ -6742,6 +6744,61 @@ coerce_template_parms (tree parms,
   return new_inner_args;
 }
 
+/* Like coerce_template_parms.  If PARMS represents all template
+   parameters levels, this function returns a vector of vectors
+   representing all the resulting argument levels.  Note that in this
+   case, only the innermost arguments are coerced because the
+   outermost ones are supposed to have been coerced already.
+
+   Otherwise, if PARMS represents only (the innermost) vector of
+   parameters, this function returns a vector containing just the
+   innermost resulting arguments.  */
+
+static tree
+coerce_innermost_template_parms (tree parms,
+				  tree args,
+				  tree in_decl,
+				  tsubst_flags_t complain,
+				  bool require_all_args,
+				  bool use_default_args)
+{
+  int parms_depth = TMPL_PARMS_DEPTH (parms);
+  int args_depth = TMPL_ARGS_DEPTH (args);
+  tree coerced_args;
+
+  if (parms_depth > 1)
+    {
+      coerced_args = make_tree_vec (parms_depth);
+      tree level;
+      int cur_depth;
+
+      for (level = parms, cur_depth = parms_depth;
+	   parms_depth > 0 && level != NULL_TREE;
+	   level = TREE_CHAIN (level), --cur_depth)
+	{
+	  tree l;
+	  if (cur_depth == args_depth)
+	    l = coerce_template_parms (TREE_VALUE (level),
+				       args, in_decl, complain,
+				       require_all_args,
+				       use_default_args);
+	  else
+	    l = TMPL_ARGS_LEVEL (args, cur_depth);
+
+	  if (l == error_mark_node)
+	    return error_mark_node;
+
+	  SET_TMPL_ARGS_LEVEL (coerced_args, cur_depth, l);
+	}
+    }
+  else
+    coerced_args = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parms),
+					  args, in_decl, complain,
+					  require_all_args,
+					  use_default_args);
+  return coerced_args;
+}
+
 /* Returns 1 if template args OT and NT are equivalent.  */
 
 static int
@@ -7169,63 +7226,14 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
       /* From here on, we're only interested in the most general
 	 template.  */
 
-      /* Calculate the BOUND_ARGS.  These will be the args that are
-	 actually tsubst'd into the definition to create the
-	 instantiation.  */
-      if (parm_depth > 1)
-	{
-	  /* We have multiple levels of arguments to coerce, at once.  */
-	  int i;
-	  int saved_depth = TMPL_ARGS_DEPTH (arglist);
-
-	  tree bound_args = make_tree_vec (parm_depth);
-
-	  for (i = saved_depth,
-		 t = DECL_TEMPLATE_PARMS (gen_tmpl);
-	       i > 0 && t != NULL_TREE;
-	       --i, t = TREE_CHAIN (t))
-	    {
-	      tree a;
-	      if (i == saved_depth)
-		a = coerce_template_parms (TREE_VALUE (t),
-					   arglist, gen_tmpl,
-					   complain,
-					   /*require_all_args=*/true,
-					   /*use_default_args=*/true);
-	      else
-		/* Outer levels should have already been coerced.  */
-		a = TMPL_ARGS_LEVEL (arglist, i);
-
-	      /* Don't process further if one of the levels fails.  */
-	      if (a == error_mark_node)
-		{
-		  /* Restore the ARGLIST to its full size.  */
-		  TREE_VEC_LENGTH (arglist) = saved_depth;
-		  return error_mark_node;
-		}
-
-	      SET_TMPL_ARGS_LEVEL (bound_args, i, a);
-
-	      /* We temporarily reduce the length of the ARGLIST so
-		 that coerce_template_parms will see only the arguments
-		 corresponding to the template parameters it is
-		 examining.  */
-	      TREE_VEC_LENGTH (arglist)--;
-	    }
-
-	  /* Restore the ARGLIST to its full size.  */
-	  TREE_VEC_LENGTH (arglist) = saved_depth;
-
-	  arglist = bound_args;
-	}
-      else
-	arglist
-	  = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
-				   INNERMOST_TEMPLATE_ARGS (arglist),
-				   gen_tmpl,
-				   complain,
-				   /*require_all_args=*/true,
-				   /*use_default_args=*/true);
+      /* Convert the innermost template arguments to their appropriate
+	 types.  These will be the arguments that are actually
+	 tsubst'd into the definition to create the instantiation.  */
+      arglist =
+	coerce_innermost_template_parms (parmlist, arglist,
+					 gen_tmpl, complain,
+					 /*require_all_args=*/true,
+					 /*use_default_args=*/true);
 
       if (arglist == error_mark_node)
 	/* We were unable to bind the arguments.  */
@@ -14637,7 +14645,15 @@ instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain)
       ggc_free (tinst);
       return error_mark_node;
     }
+
+  args =
+    coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl),
+				     args, tmpl, complain,
+				     /*require_all_args=*/true,
+				     /*use_default_args=*/true);
+
   tree r = instantiate_template (tmpl, args, complain);
+
   pop_tinst_level ();
   /* We can't free this if a pending_template entry or last_error_tinst_level
      is pointing at it.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
new file mode 100644
index 0000000..83eea47
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
@@ -0,0 +1,20 @@
+// Origin: PR c++/55663
+// { dg-do compile { target c++11 } }
+
+template <typename>
+constexpr bool the_truth () { return true; }
+
+template <bool>
+  struct Takes_bool { };
+
+template<bool B>
+  using Alias = Takes_bool<B>;
+
+template<typename T>
+  struct test { using type = Alias<the_truth<T>()>; };
+
+int main () {
+  test<int> a;
+
+  return 0;
+}
-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-10 16:02         ` Gabriel Dos Reis
@ 2013-01-11 10:41           ` Dodji Seketeli
  2013-01-11 10:47             ` Jakub Jelinek
  0 siblings, 1 reply; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-11 10:41 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: GCC Patches, Jason Merrill

Gabriel Dos Reis <gdr@integrable-solutions.net> writes:

> On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli <dodji@redhat.com> wrote:
>>
>> Also, I am not sure if this patch would be appropriate for commit, now
>> that we are in 'regression-only' mode.  But seeing this alias-template
>> related thing not working hurts me.  :)  So at worst I'll schedule the
>> patch for when stage1 opens again.
>
> It is certainly a blocker for some people here using both constexpr
> and template alias.  (The code uses a technique documented in the
> upcoming 4th edition of TC++PL which is due anytime now.  It would be
> embarrassing if GCC-4.8 didn't accept it.)

/me nods.

Hopefully when the review is done, we can ask our friendly release
managers to consider interceding for us in this matter.  :-)

-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-11 10:41           ` Dodji Seketeli
@ 2013-01-11 10:47             ` Jakub Jelinek
  2013-01-11 11:31               ` Dodji Seketeli
  0 siblings, 1 reply; 18+ messages in thread
From: Jakub Jelinek @ 2013-01-11 10:47 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: Gabriel Dos Reis, GCC Patches, Jason Merrill

On Fri, Jan 11, 2013 at 11:41:34AM +0100, Dodji Seketeli wrote:
> Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
> 
> > On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli <dodji@redhat.com> wrote:
> >>
> >> Also, I am not sure if this patch would be appropriate for commit, now
> >> that we are in 'regression-only' mode.  But seeing this alias-template
> >> related thing not working hurts me.  :)  So at worst I'll schedule the
> >> patch for when stage1 opens again.
> >
> > It is certainly a blocker for some people here using both constexpr
> > and template alias.  (The code uses a technique documented in the
> > upcoming 4th edition of TC++PL which is due anytime now.  It would be
> > embarrassing if GCC-4.8 didn't accept it.)
> 
> /me nods.
> 
> Hopefully when the review is done, we can ask our friendly release
> managers to consider interceding for us in this matter.  :-)

This is ok for 4.8 from RM POV.

	Jakub

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-11 10:47             ` Jakub Jelinek
@ 2013-01-11 11:31               ` Dodji Seketeli
  0 siblings, 0 replies; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-11 11:31 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Gabriel Dos Reis, GCC Patches, Jason Merrill

Jakub Jelinek <jakub@redhat.com> writes:

> On Fri, Jan 11, 2013 at 11:41:34AM +0100, Dodji Seketeli wrote:
>> Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
>> 
>> > On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli <dodji@redhat.com> wrote:
>> >>
>> >> Also, I am not sure if this patch would be appropriate for commit, now
>> >> that we are in 'regression-only' mode.  But seeing this alias-template
>> >> related thing not working hurts me.  :)  So at worst I'll schedule the
>> >> patch for when stage1 opens again.
>> >
>> > It is certainly a blocker for some people here using both constexpr
>> > and template alias.  (The code uses a technique documented in the
>> > upcoming 4th edition of TC++PL which is due anytime now.  It would be
>> > embarrassing if GCC-4.8 didn't accept it.)
>> 
>> /me nods.
>> 
>> Hopefully when the review is done, we can ask our friendly release
>> managers to consider interceding for us in this matter.  :-)
>
> This is ok for 4.8 from RM POV.

Thank you!

-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-11 10:38           ` Dodji Seketeli
@ 2013-01-11 14:53             ` Jason Merrill
  2013-01-11 16:33               ` Dodji Seketeli
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Merrill @ 2013-01-11 14:53 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: Gabriel Dos Reis, GCC Patches

On 01/11/2013 05:38 AM, Dodji Seketeli wrote:
> but when I read the code, it looks like this is not necessary.  Am I
> missing something?  In any case, I haven't put that code in the new
> coerce_innermost_template_parms.  Is that OK?

I agree that it seems unnecessary.  But to be safe, let's leave 
lookup_template_class_1 alone until after 4.8 branches.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-11 14:53             ` Jason Merrill
@ 2013-01-11 16:33               ` Dodji Seketeli
  2013-01-14 14:09                 ` Jason Merrill
  0 siblings, 1 reply; 18+ messages in thread
From: Dodji Seketeli @ 2013-01-11 16:33 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Gabriel Dos Reis, GCC Patches

Jason Merrill <jason@redhat.com> writes:

> On 01/11/2013 05:38 AM, Dodji Seketeli wrote:
>> but when I read the code, it looks like this is not necessary.  Am I
>> missing something?  In any case, I haven't put that code in the new
>> coerce_innermost_template_parms.  Is that OK?
>
> I agree that it seems unnecessary.  But to be safe, let's leave
> lookup_template_class_1 alone until after 4.8 branches.

OK, here are the patches I am proposing then.  The first one is the one
I'd like to commit to 4.8 and the second one would be scheduled for 4.9
when its branch opens.

Is that OK?

gcc/cp/

	PR c++/55663
	* pt.c (coerce_innermost_template_parms): New static function.
	(instantiate_alias_template):  Use it here.

gcc/testsuite/

	PR c++/55663
	* g++.dg/cpp0x/alias-decl-31.C: New test.
---
 gcc/cp/pt.c                                | 64 ++++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C | 20 ++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6d78dd2..62fa2d9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -130,6 +130,8 @@ static tree tsubst_initializer_list (tree, tree);
 static tree get_class_bindings (tree, tree, tree, tree);
 static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
 				   bool, bool);
+static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t,
+					      bool, bool);
 static void tsubst_enum	(tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
@@ -6742,6 +6744,61 @@ coerce_template_parms (tree parms,
   return new_inner_args;
 }
 
+/* Like coerce_template_parms.  If PARMS represents all template
+   parameters levels, this function returns a vector of vectors
+   representing all the resulting argument levels.  Note that in this
+   case, only the innermost arguments are coerced because the
+   outermost ones are supposed to have been coerced already.
+
+   Otherwise, if PARMS represents only (the innermost) vector of
+   parameters, this function returns a vector containing just the
+   innermost resulting arguments.  */
+
+static tree
+coerce_innermost_template_parms (tree parms,
+				  tree args,
+				  tree in_decl,
+				  tsubst_flags_t complain,
+				  bool require_all_args,
+				  bool use_default_args)
+{
+  int parms_depth = TMPL_PARMS_DEPTH (parms);
+  int args_depth = TMPL_ARGS_DEPTH (args);
+  tree coerced_args;
+
+  if (parms_depth > 1)
+    {
+      coerced_args = make_tree_vec (parms_depth);
+      tree level;
+      int cur_depth;
+
+      for (level = parms, cur_depth = parms_depth;
+	   parms_depth > 0 && level != NULL_TREE;
+	   level = TREE_CHAIN (level), --cur_depth)
+	{
+	  tree l;
+	  if (cur_depth == args_depth)
+	    l = coerce_template_parms (TREE_VALUE (level),
+				       args, in_decl, complain,
+				       require_all_args,
+				       use_default_args);
+	  else
+	    l = TMPL_ARGS_LEVEL (args, cur_depth);
+
+	  if (l == error_mark_node)
+	    return error_mark_node;
+
+	  SET_TMPL_ARGS_LEVEL (coerced_args, cur_depth, l);
+	}
+    }
+  else
+    coerced_args = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parms),
+					  args, in_decl, complain,
+					  require_all_args,
+					  use_default_args);
+  return coerced_args;
+}
+
 /* Returns 1 if template args OT and NT are equivalent.  */
 
 static int
@@ -14642,6 +14699,13 @@ instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain)
       ggc_free (tinst);
       return error_mark_node;
     }
+
+  args =
+    coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl),
+				     args, tmpl, complain,
+				     /*require_all_args=*/true,
+				     /*use_default_args=*/true);
+
   tree r = instantiate_template (tmpl, args, complain);
   pop_tinst_level ();
   /* We can't free this if a pending_template entry or last_error_tinst_level
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
new file mode 100644
index 0000000..83eea47
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-31.C
@@ -0,0 +1,20 @@
+// Origin: PR c++/55663
+// { dg-do compile { target c++11 } }
+
+template <typename>
+constexpr bool the_truth () { return true; }
+
+template <bool>
+  struct Takes_bool { };
+
+template<bool B>
+  using Alias = Takes_bool<B>;
+
+template<typename T>
+  struct test { using type = Alias<the_truth<T>()>; };
+
+int main () {
+  test<int> a;
+
+  return 0;
+}
-- 
1.7.11.7


gcc/cp/

	* pt.c (lookup_template_class_1): Use coerce_inner_template_parms
	here for the sake of ease of maintenance.
---
 gcc/cp/pt.c | 65 ++++++++-----------------------------------------------------
 1 file changed, 8 insertions(+), 57 deletions(-)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 62fa2d9..3c63407 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7226,63 +7226,14 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
       /* From here on, we're only interested in the most general
 	 template.  */
 
-      /* Calculate the BOUND_ARGS.  These will be the args that are
-	 actually tsubst'd into the definition to create the
-	 instantiation.  */
-      if (parm_depth > 1)
-	{
-	  /* We have multiple levels of arguments to coerce, at once.  */
-	  int i;
-	  int saved_depth = TMPL_ARGS_DEPTH (arglist);
-
-	  tree bound_args = make_tree_vec (parm_depth);
-
-	  for (i = saved_depth,
-		 t = DECL_TEMPLATE_PARMS (gen_tmpl);
-	       i > 0 && t != NULL_TREE;
-	       --i, t = TREE_CHAIN (t))
-	    {
-	      tree a;
-	      if (i == saved_depth)
-		a = coerce_template_parms (TREE_VALUE (t),
-					   arglist, gen_tmpl,
-					   complain,
-					   /*require_all_args=*/true,
-					   /*use_default_args=*/true);
-	      else
-		/* Outer levels should have already been coerced.  */
-		a = TMPL_ARGS_LEVEL (arglist, i);
-
-	      /* Don't process further if one of the levels fails.  */
-	      if (a == error_mark_node)
-		{
-		  /* Restore the ARGLIST to its full size.  */
-		  TREE_VEC_LENGTH (arglist) = saved_depth;
-		  return error_mark_node;
-		}
-
-	      SET_TMPL_ARGS_LEVEL (bound_args, i, a);
-
-	      /* We temporarily reduce the length of the ARGLIST so
-		 that coerce_template_parms will see only the arguments
-		 corresponding to the template parameters it is
-		 examining.  */
-	      TREE_VEC_LENGTH (arglist)--;
-	    }
-
-	  /* Restore the ARGLIST to its full size.  */
-	  TREE_VEC_LENGTH (arglist) = saved_depth;
-
-	  arglist = bound_args;
-	}
-      else
-	arglist
-	  = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
-				   INNERMOST_TEMPLATE_ARGS (arglist),
-				   gen_tmpl,
-				   complain,
-				   /*require_all_args=*/true,
-				   /*use_default_args=*/true);
+      /* Convert the innermost template arguments to their appropriate
+	 types.  These will be the arguments that are actually
+	 tsubst'd into the definition to create the instantiation.  */
+      arglist =
+	coerce_innermost_template_parms (parmlist, arglist,
+					 gen_tmpl, complain,
+					 /*require_all_args=*/true,
+					 /*use_default_args=*/true);
 
       if (arglist == error_mark_node)
 	/* We were unable to bind the arguments.  */
-- 
1.7.11.7


-- 
		Dodji

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
  2013-01-11 16:33               ` Dodji Seketeli
@ 2013-01-14 14:09                 ` Jason Merrill
  0 siblings, 0 replies; 18+ messages in thread
From: Jason Merrill @ 2013-01-14 14:09 UTC (permalink / raw)
  To: Dodji Seketeli; +Cc: Gabriel Dos Reis, GCC Patches

OK.

Jason

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2013-01-14 14:09 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-08 13:58 [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg Dodji Seketeli
2013-01-08 16:44 ` Gabriel Dos Reis
2013-01-09 15:31   ` Dodji Seketeli
2013-01-09 16:14     ` Gabriel Dos Reis
2013-01-10 15:22       ` Dodji Seketeli
2013-01-10 16:02         ` Gabriel Dos Reis
2013-01-11 10:41           ` Dodji Seketeli
2013-01-11 10:47             ` Jakub Jelinek
2013-01-11 11:31               ` Dodji Seketeli
2013-01-10 16:11         ` Gabriel Dos Reis
2013-01-10 17:01           ` Jason Merrill
2013-01-11 10:38           ` Dodji Seketeli
2013-01-11 14:53             ` Jason Merrill
2013-01-11 16:33               ` Dodji Seketeli
2013-01-14 14:09                 ` Jason Merrill
2013-01-08 19:53 ` Jason Merrill
2013-01-09 15:03   ` Dodji Seketeli
2013-01-09 16:17     ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).