diff mbox series

C++ PATCH for c++/85136, ICE with designated init in template

Message ID CADzB+2msqBRRuSNOuff6gOV-K4DV3k6hB5WvDR3GCt_CzS=8Pw@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/85136, ICE with designated init in template | expand

Commit Message

Jason Merrill April 5, 2018, 7:38 p.m. UTC
The issue here was that check_array_designated_initializer did
constant folding to produce a constant index, but then left the
un-folded value behind to confuse complete_array_type.  Fixed by
updating ce->value with the folded value.  We should also use
fold_non_dependent_expr, and handle dependent designators.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox series

Patch

commit 095a2dc5c8523e01367d9604f1e47849f7b4dcd9
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Apr 5 13:10:01 2018 -0400

            PR c++/85136 - ICE with designated init in template.
    
            * decl.c (maybe_deduce_size_from_array_init): Handle dependent
            designated initializer.
            (check_array_designated_initializer): Update ce->index with the
            constant value.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 489dcc0a8ed..86251f51eb4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5415,12 +5415,15 @@  check_array_designated_initializer (constructor_elt *ce,
 						  ce->index, true);
       if (ce_index
 	  && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (ce_index))
-	  && (TREE_CODE (ce_index = maybe_constant_value (ce_index))
+	  && (TREE_CODE (ce_index = fold_non_dependent_expr (ce_index))
 	      == INTEGER_CST))
 	{
 	  /* A C99 designator is OK if it matches the current index.  */
 	  if (wi::to_wide (ce_index) == index)
-	    return true;
+	    {
+	      ce->index = ce_index;
+	      return true;
+	    }
 	  else
 	    sorry ("non-trivial designated initializers not supported");
 	}
@@ -5463,8 +5466,12 @@  maybe_deduce_size_from_array_init (tree decl, tree init)
 	  constructor_elt *ce;
 	  HOST_WIDE_INT i;
 	  FOR_EACH_VEC_SAFE_ELT (v, i, ce)
-	    if (!check_array_designated_initializer (ce, i))
-	      failure = 1;
+	    {
+	      if (instantiation_dependent_expression_p (ce->index))
+		return;
+	      if (!check_array_designated_initializer (ce, i))
+		failure = 1;
+	    }
 	}
 
       if (failure)
diff --git a/gcc/testsuite/g++.dg/ext/desig11.C b/gcc/testsuite/g++.dg/ext/desig11.C
new file mode 100644
index 00000000000..34bfbe1044e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/desig11.C
@@ -0,0 +1,15 @@ 
+// PR c++/85136
+// { dg-options "" }
+
+enum { e };
+
+template<int I> void f()
+{
+  const int x[] = { [e] = 0 };
+  const int y[] = { [I] = 0 };
+}
+
+int main()
+{
+  f<0>();
+}