diff mbox

[C++] Fix ICE in build_value_init (PR c++/51369)

Message ID 20111206194819.GT27242@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Dec. 6, 2011, 7:48 p.m. UTC
Hi!

On this testcase we ICE, because cxx_eval_array_reference calls
build_value_init with ARRAY_TYPE (to get initializer for x[0]).
build_value_init seems to work for arrays of scalars (or arrays of arrays of
scalars etc.) apparently just fine even when processing_template_decl,
if I understand the comment, is it just about the stuff build_value_init
does for CLASS_TYPE_P before calling build_value_init_noctor.
Of course array of classes would be an issue, but we'd still ICE on it
even with the patch, as for ARRAY_TYPE we call build_value_init on its
TREE_TYPE.  And constexprs in that case apparently have all array entries
filled in.

Alternatively, perhaps we could move this gcc_assert down into the if
(CLASS_TYPE_P (type)) { block and change it into just gcc_assert
(!processing_template_decl).

2011-12-06  Jakub Jelinek  <jakub@redhat.com>

	PR c++/51369
	* init.c (build_value_init): Allow array types even when
	processing_template_decl.

	* g++.dg/cpp0x/constexpr-51369.C: New test.


	Jakub

Comments

Jason Merrill Dec. 7, 2011, 3:10 p.m. UTC | #1
On 12/06/2011 02:48 PM, Jakub Jelinek wrote:
> -  gcc_assert (!processing_template_decl || SCALAR_TYPE_P (type));
> +  gcc_assert (!processing_template_decl
> +	      || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));

How about SCALAR_TYPE_P (strip_array_types (type))?  OK with that change.

Jason
Jakub Jelinek Dec. 7, 2011, 3:18 p.m. UTC | #2
On Wed, Dec 07, 2011 at 10:10:08AM -0500, Jason Merrill wrote:
> On 12/06/2011 02:48 PM, Jakub Jelinek wrote:
> >-  gcc_assert (!processing_template_decl || SCALAR_TYPE_P (type));
> >+  gcc_assert (!processing_template_decl
> >+	      || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
> 
> How about SCALAR_TYPE_P (strip_array_types (type))?  OK with that change.

That would be readable, but expensive - SCALAR_TYPE_P evaluates
its argument 11 times.

	Jakub
Jason Merrill Dec. 7, 2011, 3:27 p.m. UTC | #3
On 12/07/2011 10:18 AM, Jakub Jelinek wrote:
> On Wed, Dec 07, 2011 at 10:10:08AM -0500, Jason Merrill wrote:
>> On 12/06/2011 02:48 PM, Jakub Jelinek wrote:
>>> -  gcc_assert (!processing_template_decl || SCALAR_TYPE_P (type));
>>> +  gcc_assert (!processing_template_decl
>>> +	      || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
>>
>> How about SCALAR_TYPE_P (strip_array_types (type))?  OK with that change.
>
> That would be readable, but expensive - SCALAR_TYPE_P evaluates
> its argument 11 times.

Good point.  Your patch is OK, then.

Jasno
diff mbox

Patch

--- gcc/cp/init.c.jj	2011-11-28 17:58:00.000000000 +0100
+++ gcc/cp/init.c	2011-12-06 20:23:25.288799336 +0100
@@ -333,7 +333,8 @@  build_value_init (tree type, tsubst_flag
      constructor.  */
 
   /* The AGGR_INIT_EXPR tweaking below breaks in templates.  */
-  gcc_assert (!processing_template_decl || SCALAR_TYPE_P (type));
+  gcc_assert (!processing_template_decl
+	      || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
 
   if (CLASS_TYPE_P (type))
     {
--- gcc/testsuite/g++.dg/cpp0x/constexpr-51369.C.jj	2011-12-06 20:24:54.542241075 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-51369.C	2011-12-06 20:24:19.000000000 +0100
@@ -0,0 +1,12 @@ 
+// PR c++/51369
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+constexpr int x[2][2] = {};
+
+template<int>
+void
+foo ()
+{
+  x[0][0];
+}