In this testcase, we delay expanding the VEC_INIT_EXPR until gimplification time, at which point we've already thrown away some constexpr bodies. Since this location doesn't require a constant expression we can safely treat it as a non-constant expression.

Tested x86_64-pc-linux-gnu, applying to 5 branch. On the trunk I want to address the cause of the problem.
commit 3dc40c07723fe4490a49176e7420ba5afe692db1
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Apr 28 22:17:30 2015 -0400

    	PR c++/65876
    	* constexpr.c (cxx_eval_call_expression): Fail gracefully if cgraph
    	threw away DECL_SAVED_TREE.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 0e333aa..5e65f29 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1355,7 +1355,14 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 		     fun = DECL_CHAIN (fun))
 		  if (DECL_SAVED_TREE (fun))
 		    break;
-	      gcc_assert (DECL_SAVED_TREE (fun));
+	      if (!DECL_SAVED_TREE (fun))
+		{
+		  /* cgraph/gimplification have released the DECL_SAVED_TREE
+		     for this function.  Fail gracefully.  */
+		  gcc_assert (ctx->quiet);
+		  *non_constant_p = true;
+		  return t;
+		}
 	      tree parms, res;
 
 	      /* Unshare the whole function body.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array12.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array12.C
new file mode 100644
index 0000000..ec81fff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array12.C
@@ -0,0 +1,33 @@
+// PR c++/65876
+// { dg-do compile { target c++11 } }
+
+template<int>
+struct duration
+{
+    constexpr duration() : r(0) {}
+
+    template<int TPeriod>
+    constexpr duration(duration<TPeriod> x) : r(x.count()) {}
+
+    constexpr int count() { return 0; }
+
+    int r;
+};
+
+struct Config {
+    duration<1> timeout { duration<2>() };
+};
+
+Config make_config()
+{
+    return {};
+}
+
+struct ConfigArray {
+    ConfigArray();
+    Config all_configs[1];
+};
+
+ConfigArray::ConfigArray()
+{
+}

Reply via email to