public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Dodji Seketeli <dodji@redhat.com>
To: Gabriel Dos Reis <gdr@integrable-solutions.net>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>, Jason Merrill <jason@redhat.com>
Subject: Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
Date: Fri, 11 Jan 2013 10:38:00 -0000	[thread overview]
Message-ID: <87fw28ovh5.fsf@redhat.com> (raw)
In-Reply-To: <CAAiZkiApGZ3_ZU+b6ARhko=4PPsgc86sC_Xqg9GbfDw=PZHLLg@mail.gmail.com>	(Gabriel Dos Reis's message of "Thu, 10 Jan 2013 10:11:43 -0600")

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

  parent reply	other threads:[~2013-01-11 10:38 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-08 13:58 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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87fw28ovh5.fsf@redhat.com \
    --to=dodji@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gdr@integrable-solutions.net \
    --cc=jason@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).