diff mbox

[C++] PR 58882

Message ID 548DB21B.8070102@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Dec. 14, 2014, 3:51 p.m. UTC
Hi,

in order to handle correctly the testcase, thus do not ICE on it, I 
think we have simply to replace the existing gcc_unreachable with a 
normal error call. Additionally, I noticed that we aren't handling 
correctly things like constexpr user-defined type-conversion operators, 
thus I added the kind of build_expr_type_conversion / 
maybe_constant_value massaging which we are already using elsewhere. 
Finally, we have got an accepts-invalid issue with scoped enumerations, 
thus the INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P check.

Tested x86_64-linux.

Thanks,
Paolo.

////////////////////////////
/cp
2014-12-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58882
	* decl.c (check_array_designated_initializer): Diagnose gracefully
	C99 designators which aren't integral constant-expressions; allow
	constexpr user-defined type conversion operators.

/testsuite
2014-12-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58882
	* g++.dg/ext/desig8.C: New.
	* g++.dg/cpp0x/desig1.C: Likewise.

Comments

Jason Merrill Dec. 15, 2014, 2:43 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 218716)
+++ cp/decl.c	(working copy)
@@ -4996,18 +4996,22 @@  check_array_designated_initializer (constructor_el
 	  return false;
 	}
 
-      ce->index = cxx_constant_value (ce->index);
-
-      if (TREE_CODE (ce->index) == INTEGER_CST)
+      tree ce_index = build_expr_type_conversion (WANT_INT | WANT_ENUM,
+						  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))
+	      == INTEGER_CST))
 	{
 	  /* A C99 designator is OK if it matches the current index.  */
-	  if (wi::eq_p (ce->index, index))
+	  if (wi::eq_p (ce_index, index))
 	    return true;
 	  else
 	    sorry ("non-trivial designated initializers not supported");
 	}
       else
-	gcc_unreachable ();
+	error ("C99 designator %qE is not an integral constant-expression",
+	       ce->index);
 
       return false;
     }
Index: testsuite/g++.dg/cpp0x/desig1.C
===================================================================
--- testsuite/g++.dg/cpp0x/desig1.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/desig1.C	(working copy)
@@ -0,0 +1,27 @@ 
+// PR c++/58882
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  constexpr operator int() const { return 0; }
+};
+
+int a[] = { [A()] = 0 };
+
+enum E { e0 };
+
+struct B
+{
+  constexpr operator E() const { return E::e0; }
+};
+
+int b[] = { [B()] = 0 };
+
+enum class SE { se0 };
+
+struct C
+{
+  constexpr operator SE() const { return SE::se0; }
+};
+
+int c[] = { [C()] = 0 }; // { dg-error "integral constant-expression" }
Index: testsuite/g++.dg/ext/desig8.C
===================================================================
--- testsuite/g++.dg/ext/desig8.C	(revision 0)
+++ testsuite/g++.dg/ext/desig8.C	(working copy)
@@ -0,0 +1,3 @@ 
+// PR c++/58882
+
+int a[] = { [0.] = 0 }; // { dg-error "integral constant-expression" }