Patchwork C++ PATCH for c++/48745 (ICE with list-initialization in SFINAE context)

login
register
mail settings
Submitter Jason Merrill
Date May 11, 2011, 9:21 p.m.
Message ID <4DCAFDCF.2080507@redhat.com>
Download mbox | patch
Permalink /patch/95192/
State New
Headers show

Comments

Jason Merrill - May 11, 2011, 9:21 p.m.
Here we just needed to handle CONSTRUCTOR in value_dependent_expression_p.

It is also the case that a lot of crashes have been happening because 
build_non_dependent_expr calls null_ptr_cst_p, which wants to try to get 
a constant value for any expression.  That's not actually necessary for 
semantics, so we can remove it.  But it has been helpful for finding 
bugs, so I'm going to leave in the call to maybe_constant_value when 
ENABLE_CHECKING is defined.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 05a558e5467af165052855f290f11b20e7009450
Author: Jason Merrill <jason@redhat.com>
Date:   Tue May 10 16:40:54 2011 -0400

    	PR c++/48745
    	* pt.c (value_dependent_expr_p): Handle CONSTRUCTOR.

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5e24977..74d4cbf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18273,6 +18273,16 @@  value_dependent_expression_p (tree expression)
 	 type-dependent.  */
       return type_dependent_expression_p (expression);
 
+    case CONSTRUCTOR:
+      {
+	unsigned ix;
+	tree val;
+	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expression), ix, val)
+	  if (value_dependent_expression_p (val))
+	    return true;
+	return false;
+      }
+
     default:
       /* A constant expression is value-dependent if any subexpression is
 	 value-dependent.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae22.C b/gcc/testsuite/g++.dg/cpp0x/sfinae22.C
new file mode 100644
index 0000000..1c3efd2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae22.C
@@ -0,0 +1,23 @@ 
+// PR c++/48745
+// { dg-options -std=c++0x }
+
+template<class T>
+struct add_rval_ref {
+  typedef T&& type;
+};
+
+template<>
+struct add_rval_ref<void> {
+  typedef void type;
+};
+
+template<class T>
+typename add_rval_ref<T>::type create();
+
+template<class T, class... Args>
+decltype(T{create<Args>()...}, char()) f(int);
+
+template<class, class...>
+char (&f(...))[2];
+
+static_assert(sizeof(f<int, void>(0)) != 1, "Error"); // #

commit 98b2007f0a05f07cf79711c1d29cc228cb5e9946
Author: Jason Merrill <jason@redhat.com>
Date:   Tue May 10 16:42:31 2011 -0400

    	* pt.c (build_non_dependent_expr): Don't check null_ptr_cst_p,
    	do call maybe_constant_value in C++0x mode.
    	* semantics.c (cxx_eval_constant_expression): Handle TEMPLATE_DECL.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 74d4cbf..4b32ce9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18871,10 +18871,13 @@  build_non_dependent_expr (tree expr)
 {
   tree inner_expr;
 
-  /* Preserve null pointer constants so that the type of things like
-     "p == 0" where "p" is a pointer can be determined.  */
-  if (null_ptr_cst_p (expr))
-    return expr;
+#ifdef ENABLE_CHECKING
+  /* Try to get a constant value for all non-type-dependent expressions in
+      order to expose bugs in *_dependent_expression_p and constexpr.  */
+  if (cxx_dialect >= cxx0x)
+    maybe_constant_value (fold_non_dependent_expr (expr));
+#endif
+
   /* Preserve OVERLOADs; the functions must be available to resolve
      types.  */
   inner_expr = expr;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0ba0370..bfe233e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6911,6 +6911,7 @@  cxx_eval_constant_expression (const constexpr_call *call, tree t,
       break;
 
     case FUNCTION_DECL:
+    case TEMPLATE_DECL:
     case LABEL_DECL:
       return t;