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
next prev 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).