Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-14 Thread Jason Merrill

OK.

Jason


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-11 Thread Dodji Seketeli
Gabriel Dos Reis g...@integrable-solutions.net writes:

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

 But during the instantiation of the *members* of testint, we try to
 instantiate Aliasthe_truthint, without coercing (and thus without
 folding) the argument {the_truthint}.  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 ja...@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,
+  

Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-11 Thread Dodji Seketeli
Gabriel Dos Reis g...@integrable-solutions.net writes:

 On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli do...@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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-11 Thread Jakub Jelinek
On Fri, Jan 11, 2013 at 11:41:34AM +0100, Dodji Seketeli wrote:
 Gabriel Dos Reis g...@integrable-solutions.net writes:
 
  On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli do...@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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-11 Thread Dodji Seketeli
Jakub Jelinek ja...@redhat.com writes:

 On Fri, Jan 11, 2013 at 11:41:34AM +0100, Dodji Seketeli wrote:
 Gabriel Dos Reis g...@integrable-solutions.net writes:
 
  On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli do...@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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-11 Thread Dodji Seketeli
Jason Merrill ja...@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 000..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 { };
+
+templatebool B
+  using Alias = Takes_boolB;
+
+templatetypename T
+  struct test { 

Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-10 Thread Dodji Seketeli
Gabriel Dos Reis g...@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
 constantness.

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_thruthint 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 ja...@redhat.com writes:

 On 01/09/2013 10:02 AM, Dodji Seketeli wrote:
 As the argument 'the_truthT()' 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 testint 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 testint, we try to
instantiate Aliasthe_truthint, without coercing (and thus without
folding) the argument {the_truthint}.  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)
+   {
+ 

Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-10 Thread Gabriel Dos Reis
On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli do...@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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-10 Thread Gabriel Dos Reis
On Thu, Jan 10, 2013 at 9:22 AM, Dodji Seketeli do...@redhat.com wrote:

 But during the instantiation of the *members* of testint, we try to
 instantiate Aliasthe_truthint, without coercing (and thus without
 folding) the argument {the_truthint}.  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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-10 Thread Jason Merrill

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



Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-09 Thread Dodji Seketeli
Jason Merrill ja...@redhat.com writes:

 On 01/08/2013 08:58 AM, Dodji Seketeli wrote:
 There, when we check the argument 'the_truthint()' 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_truthT()' 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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-09 Thread Dodji Seketeli
Gabriel Dos Reis g...@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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-09 Thread Gabriel Dos Reis
On Wed, Jan 9, 2013 at 9:30 AM, Dodji Seketeli do...@redhat.com wrote:
 Gabriel Dos Reis g...@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 constantness.

-- Gaby


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-09 Thread Jason Merrill

On 01/09/2013 10:02 AM, Dodji Seketeli wrote:

As the argument 'the_truthT()' 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



Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-08 Thread Gabriel Dos Reis
On Tue, Jan 8, 2013 at 7:58 AM, Dodji Seketeli do...@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
  5struct Takes_bool { };
  6
  7  templatebool B
  8using Alias = Takes_boolB;
  9
 10  templatetypename T
 11struct test { using type = Aliasthe_truthT(); };
 12
 13  int main () {
 14testint a;
 15
 16return 0;
 17  }

 that yields the error:

 test.cc: In substitution of ‘templatebool B using Alias = Takes_boolB 
 [with bool B = the_truthint()]’:
 test.cc:11:51:   required from ‘struct testint’
 test.cc:14:13:   required from here
 test.cc:11:51: error: integral expression ‘the_truthint()’ is not 
 constant
struct test { using type = Aliasthe_truthT(); };

 I think the issue happens in the course of instantiating testint at
 line 14, when we look into instantiating Aliasthe_truthT() (at
 line 11), with T = int.

 There, when we check the argument 'the_truthint()' 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


Re: [PATCH] PR c++/55663 - constexpr function templ instantiation considered non-const as alias templ arg

2013-01-08 Thread Jason Merrill

On 01/08/2013 08:58 AM, Dodji Seketeli wrote:

There, when we check the argument 'the_truthint()' 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