@@ -13,6 +13,7 @@ Author: Daniel Kroening, kroening@kroening.com
1313
1414#include < util/arith_tools.h>
1515#include < util/c_types.h>
16+ #include < util/config.h>
1617#include < util/cprover_prefix.h>
1718#include < util/expr_initializer.h>
1819#include < util/prefix.h>
@@ -484,6 +485,22 @@ exprt::operandst::const_iterator c_typecheck_baset::do_designated_initializer(
484485 error () << " union member designator found for empty union" << eom;
485486 throw 0 ;
486487 }
488+ else if (init_it != initializer_list.operands ().begin ())
489+ {
490+ if (config.ansi_c .mode == configt::ansi_ct::flavourt::VISUAL_STUDIO)
491+ {
492+ error ().source_location = value.source_location ();
493+ error () << " too many initializers" << eom;
494+ throw 0 ;
495+ }
496+ else
497+ {
498+ warning ().source_location = value.source_location ();
499+ warning () << " excess elements in union initializer" << eom;
500+
501+ return ++init_it;
502+ }
503+ }
487504 else if (index >= components.size ())
488505 {
489506 error ().source_location = value.source_location ();
@@ -494,16 +511,20 @@ exprt::operandst::const_iterator c_typecheck_baset::do_designated_initializer(
494511
495512 const union_typet::componentt &component = components[index];
496513
497- if (dest->id ()==ID_union &&
498- dest->get (ID_component_name)==component.get_name ())
514+ DATA_INVARIANT (
515+ dest->id () == ID_union, " union should be zero initialized" );
516+
517+ if (dest->get (ID_component_name) == component.get_name ())
499518 {
500519 // Already right union component. We can initialize multiple submembers,
501520 // so do not overwrite this.
502521 }
503522 else
504523 {
505- // Note that gcc issues a warning if the union component is switched.
506- // Build a union expression from given component.
524+ // The first component is not the maximum member, which the (default)
525+ // zero initializer prepared. Replace this by a component-specific
526+ // initializer; other bytes have an unspecified value (C Standard
527+ // 6.2.6.1(7)).
507528 const auto zero =
508529 zero_initializer (component.type (), value.source_location (), *this );
509530 if (!zero.has_value ())
0 commit comments