@@ -256,9 +256,7 @@ void c_typecheck_baset::designator_enter(
256
256
const typet &type,
257
257
designatort &designator)
258
258
{
259
- designatort::entryt entry;
260
- entry.type =type;
261
- entry.index =0 ;
259
+ designatort::entryt entry (type);
262
260
263
261
const typet &full_type=follow (type);
264
262
@@ -268,6 +266,8 @@ void c_typecheck_baset::designator_enter(
268
266
269
267
entry.size =struct_type.components ().size ();
270
268
entry.subtype .make_nil ();
269
+ // only a top-level struct may end with a variable-length array
270
+ entry.vla_permitted =designator.empty ();
271
271
272
272
for (struct_typet::componentst::const_iterator
273
273
it=struct_type.components ().begin ();
@@ -351,12 +351,16 @@ void c_typecheck_baset::designator_enter(
351
351
352
352
// / \param pre:initialized result, designator
353
353
// / \return sets result
354
- void c_typecheck_baset::do_designated_initializer (
354
+ exprt::operandst::const_iterator c_typecheck_baset::do_designated_initializer (
355
355
exprt &result,
356
356
designatort &designator,
357
- const exprt &value,
357
+ const exprt &initializer_list,
358
+ exprt::operandst::const_iterator init_it,
358
359
bool force_constant)
359
360
{
361
+ // copy the value, we may need to adjust it
362
+ exprt value=*init_it;
363
+
360
364
assert (!designator.empty ());
361
365
362
366
if (value.id ()==ID_designated_initializer)
@@ -370,8 +374,10 @@ void c_typecheck_baset::do_designated_initializer(
370
374
371
375
assert (!designator.empty ());
372
376
373
- return do_designated_initializer (
374
- result, designator, value.op0 (), force_constant);
377
+ // discard the return value
378
+ do_designated_initializer (
379
+ result, designator, value, value.operands ().begin (), force_constant);
380
+ return ++init_it;
375
381
}
376
382
377
383
exprt *dest=&result;
@@ -503,7 +509,7 @@ void c_typecheck_baset::do_designated_initializer(
503
509
504
510
assert (full_type==follow (dest->type ()));
505
511
506
- return ; // done
512
+ return ++init_it ; // done
507
513
}
508
514
509
515
// union? The component in the zero initializer might
@@ -537,7 +543,7 @@ void c_typecheck_baset::do_designated_initializer(
537
543
if (value.id ()==ID_initializer_list)
538
544
{
539
545
*dest=do_initializer_rec (value, type, force_constant);
540
- return ; // done
546
+ return ++init_it ; // done
541
547
}
542
548
else if (value.id ()==ID_string_constant)
543
549
{
@@ -549,7 +555,7 @@ void c_typecheck_baset::do_designated_initializer(
549
555
follow (full_type.subtype ()).id ()==ID_unsignedbv))
550
556
{
551
557
*dest=do_initializer_rec (value, type, force_constant);
552
- return ; // done
558
+ return ++init_it ; // done
553
559
}
554
560
}
555
561
else if (follow (value.type ())==full_type)
@@ -562,7 +568,7 @@ void c_typecheck_baset::do_designated_initializer(
562
568
full_type.id ()==ID_vector)
563
569
{
564
570
*dest=value;
565
- return ; // done
571
+ return ++init_it ; // done
566
572
}
567
573
}
568
574
@@ -574,21 +580,49 @@ void c_typecheck_baset::do_designated_initializer(
574
580
// we are initializing a compound type, and enter it!
575
581
// this may change the type, full_type might not be valid any more
576
582
const typet dest_type=full_type;
583
+ const bool vla_permitted=designator.back ().vla_permitted ;
577
584
designator_enter (type, designator);
578
585
586
+ // GCC permits (though issuing a warning with -Wall) composite
587
+ // types built from flat initializer lists
579
588
if (dest->operands ().empty ())
580
589
{
581
- err_location (value);
582
- error () << " cannot initialize type `"
583
- << to_string (dest_type) << " ' using value `"
584
- << to_string (value) << " '" << eom;
585
- throw 0 ;
590
+ warning ().source_location =value.find_source_location ();
591
+ warning () << " initialisation of " << full_type.id ()
592
+ << " requires initializer list, found "
593
+ << value.id () << " instead" << eom;
594
+
595
+ // in case of a variable-length array consume all remaining
596
+ // initializer elements
597
+ if (vla_permitted &&
598
+ dest_type.id ()==ID_array &&
599
+ (to_array_type (dest_type).size ().is_zero () ||
600
+ to_array_type (dest_type).size ().is_nil ()))
601
+ {
602
+ value.id (ID_initializer_list);
603
+ value.operands ().clear ();
604
+ for ( ; init_it!=initializer_list.operands ().end (); ++init_it)
605
+ value.copy_to_operands (*init_it);
606
+ *dest=do_initializer_rec (value, dest_type, force_constant);
607
+
608
+ return init_it;
609
+ }
610
+ else
611
+ {
612
+ err_location (value);
613
+ error () << " cannot initialize type `"
614
+ << to_string (dest_type) << " ' using value `"
615
+ << to_string (value) << " '" << eom;
616
+ throw 0 ;
617
+ }
586
618
}
587
619
588
620
dest=&(dest->op0 ());
589
621
590
622
// we run into another loop iteration
591
623
}
624
+
625
+ return ++init_it;
592
626
}
593
627
594
628
void c_typecheck_baset::increment_designator (designatort &designator)
@@ -651,8 +685,7 @@ designatort c_typecheck_baset::make_designator(
651
685
forall_operands (it, src)
652
686
{
653
687
const exprt &d_op=*it;
654
- designatort::entryt entry;
655
- entry.type =type;
688
+ designatort::entryt entry (type);
656
689
const typet &full_type=follow (entry.type );
657
690
658
691
if (full_type.id ()==ID_array)
@@ -856,10 +889,12 @@ exprt c_typecheck_baset::do_initializer_list(
856
889
857
890
designator_enter (type, current_designator);
858
891
859
- forall_operands (it, value)
892
+ const exprt::operandst &operands=value.operands ();
893
+ for (exprt::operandst::const_iterator it=operands.begin ();
894
+ it!=operands.end (); ) // no ++it
860
895
{
861
- do_designated_initializer (
862
- result, current_designator, * it, force_constant);
896
+ it= do_designated_initializer (
897
+ result, current_designator, value, it, force_constant);
863
898
864
899
// increase designator -- might go up
865
900
increment_designator (current_designator);
0 commit comments