1212#include " c_typecheck_base.h"
1313
1414#include < util/arith_tools.h>
15+ #include < util/byte_operators.h>
1516#include < util/c_types.h>
1617#include < util/config.h>
1718#include < util/cprover_prefix.h>
@@ -520,13 +521,15 @@ exprt::operandst::const_iterator c_typecheck_baset::do_designated_initializer(
520521 {
521522 // Already right union component. We can initialize multiple submembers,
522523 // so do not overwrite this.
524+ dest = &(to_union_expr (*dest).op ());
523525 }
524526 else
525527 {
526528 // The first component is not the maximum member, which the (default)
527529 // zero initializer prepared. Replace this by a component-specific
528530 // initializer; other bytes have an unspecified value (C Standard
529- // 6.2.6.1(7)).
531+ // 6.2.6.1(7)). In practice, objects of static lifetime are fully zero
532+ // initialized.
530533 const auto zero =
531534 zero_initializer (component.type (), value.source_location (), *this );
532535 if (!zero.has_value ())
@@ -536,12 +539,23 @@ exprt::operandst::const_iterator c_typecheck_baset::do_designated_initializer(
536539 << to_string (component.type ()) << " '" << eom;
537540 throw 0 ;
538541 }
539- union_exprt union_expr (component.get_name (), *zero, type);
540- union_expr.add_source_location ()=value.source_location ();
541- *dest=union_expr;
542- }
543542
544- dest = &(to_union_expr (*dest).op ());
543+ if (current_symbol.is_static_lifetime )
544+ {
545+ byte_update_exprt byte_update{
546+ byte_update_id (), *dest, from_integer (0 , index_type ()), *zero};
547+ byte_update.add_source_location () = value.source_location ();
548+ *dest = std::move (byte_update);
549+ dest = &(to_byte_update_expr (*dest).op2 ());
550+ }
551+ else
552+ {
553+ union_exprt union_expr (component.get_name (), *zero, type);
554+ union_expr.add_source_location () = value.source_location ();
555+ *dest = std::move (union_expr);
556+ dest = &(to_union_expr (*dest).op ());
557+ }
558+ }
545559 }
546560 else
547561 UNREACHABLE;
0 commit comments