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

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