public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Dodji Seketeli <dodji@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: Gabriel Dos Reis <gdr@integrable-solutions.net>,
	       GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg
Date: Fri, 11 Jan 2013 16:33:00 -0000	[thread overview]
Message-ID: <877gnjof24.fsf@redhat.com> (raw)
In-Reply-To: <50F01BC3.1030703@redhat.com> (Jason Merrill's message of "Fri,	11 Jan 2013 09:03:47 -0500")

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

  reply	other threads:[~2013-01-11 16:33 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
2013-01-11 14:53             ` Jason Merrill
2013-01-11 16:33               ` Dodji Seketeli [this message]
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=877gnjof24.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).