@@ -256,9 +256,7 @@ void c_typecheck_baset::designator_enter(
256256 const typet &type,
257257 designatort &designator)
258258{
259- designatort::entryt entry;
260- entry.type =type;
261- entry.index =0 ;
259+ designatort::entryt entry (type);
262260
263261 const typet &full_type=follow (type);
264262
@@ -268,6 +266,8 @@ void c_typecheck_baset::designator_enter(
268266
269267 entry.size =struct_type.components ().size ();
270268 entry.subtype .make_nil ();
269+ // only a top-level struct may end with a variable-length array
270+ entry.vla_permitted =designator.empty ();
271271
272272 for (struct_typet::componentst::const_iterator
273273 it=struct_type.components ().begin ();
@@ -351,12 +351,16 @@ void c_typecheck_baset::designator_enter(
351351
352352// / \param pre:initialized result, designator
353353// / \return sets result
354- void c_typecheck_baset::do_designated_initializer (
354+ exprt::operandst::const_iterator c_typecheck_baset::do_designated_initializer (
355355 exprt &result,
356356 designatort &designator,
357- const exprt &value,
357+ const exprt &initializer_list,
358+ exprt::operandst::const_iterator init_it,
358359 bool force_constant)
359360{
361+ // copy the value, we may need to adjust it
362+ exprt value=*init_it;
363+
360364 assert (!designator.empty ());
361365
362366 if (value.id ()==ID_designated_initializer)
@@ -370,8 +374,10 @@ void c_typecheck_baset::do_designated_initializer(
370374
371375 assert (!designator.empty ());
372376
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;
375381 }
376382
377383 exprt *dest=&result;
@@ -503,7 +509,7 @@ void c_typecheck_baset::do_designated_initializer(
503509
504510 assert (full_type==follow (dest->type ()));
505511
506- return ; // done
512+ return ++init_it ; // done
507513 }
508514
509515 // union? The component in the zero initializer might
@@ -537,7 +543,7 @@ void c_typecheck_baset::do_designated_initializer(
537543 if (value.id ()==ID_initializer_list)
538544 {
539545 *dest=do_initializer_rec (value, type, force_constant);
540- return ; // done
546+ return ++init_it ; // done
541547 }
542548 else if (value.id ()==ID_string_constant)
543549 {
@@ -549,7 +555,7 @@ void c_typecheck_baset::do_designated_initializer(
549555 follow (full_type.subtype ()).id ()==ID_unsignedbv))
550556 {
551557 *dest=do_initializer_rec (value, type, force_constant);
552- return ; // done
558+ return ++init_it ; // done
553559 }
554560 }
555561 else if (follow (value.type ())==full_type)
@@ -562,7 +568,7 @@ void c_typecheck_baset::do_designated_initializer(
562568 full_type.id ()==ID_vector)
563569 {
564570 *dest=value;
565- return ; // done
571+ return ++init_it ; // done
566572 }
567573 }
568574
@@ -574,21 +580,49 @@ void c_typecheck_baset::do_designated_initializer(
574580 // we are initializing a compound type, and enter it!
575581 // this may change the type, full_type might not be valid any more
576582 const typet dest_type=full_type;
583+ const bool vla_permitted=designator.back ().vla_permitted ;
577584 designator_enter (type, designator);
578585
586+ // GCC permits (though issuing a warning with -Wall) composite
587+ // types built from flat initializer lists
579588 if (dest->operands ().empty ())
580589 {
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+ }
586618 }
587619
588620 dest=&(dest->op0 ());
589621
590622 // we run into another loop iteration
591623 }
624+
625+ return ++init_it;
592626}
593627
594628void c_typecheck_baset::increment_designator (designatort &designator)
@@ -651,8 +685,7 @@ designatort c_typecheck_baset::make_designator(
651685 forall_operands (it, src)
652686 {
653687 const exprt &d_op=*it;
654- designatort::entryt entry;
655- entry.type =type;
688+ designatort::entryt entry (type);
656689 const typet &full_type=follow (entry.type );
657690
658691 if (full_type.id ()==ID_array)
@@ -856,10 +889,12 @@ exprt c_typecheck_baset::do_initializer_list(
856889
857890 designator_enter (type, current_designator);
858891
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
860895 {
861- do_designated_initializer (
862- result, current_designator, * it, force_constant);
896+ it= do_designated_initializer (
897+ result, current_designator, value, it, force_constant);
863898
864899 // increase designator -- might go up
865900 increment_designator (current_designator);
0 commit comments