Then check_initializer is invoked to verify the initializers. Here argument flags is 0.
4463 static tree
4464 check_initializer (tree decl, tree init, int flags, tree *cleanup) in decl.c
4465 {
4466 tree type = TREE_TYPE (decl);
4467 tree init_code = NULL;
4468
4469 /* If `start_decl' didn't like having an initialization, ignore it now. */
4470 if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE)
4471 init = NULL_TREE;
4472
4473 /* If an initializer is present, DECL_INITIAL has been
4474 error_mark_node, to indicate that an as-of-yet unevaluated
4475 initialization will occur. From now on, DECL_INITIAL reflects
4476 the static initialization -- if any -- of DECL. */
4477 DECL_INITIAL (decl) = NULL_TREE;
4478
4479 /* Things that are going to be initialized need to have complete
4480 type. */
4481 TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl));
4482
4483 if (type == error_mark_node)
4484 /* We will have already complained. */
4485 init = NULL_TREE;
4486 else if (init && COMPLETE_TYPE_P (type)
4487 && !TREE_CONSTANT (TYPE_SIZE (type)))
4488 {
4489 error ("variable-sized object `%D' may not be initialized", decl);
4490 init = NULL_TREE;
4491 }
4492 else if (TREE_CODE (type) == ARRAY_TYPE
4493 && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
4494 {
4495 error ("elements of array `%#D' have incomplete type", decl);
4496 init = NULL_TREE;
4497 }
4498 else if (TREE_CODE (type) != ARRAY_TYPE && !COMPLETE_TYPE_P (type))
4499 {
4500 error ("`%D' has incomplete type", decl);
4501 TREE_TYPE (decl) = error_mark_node;
4502 init = NULL_TREE;
4503 }
4504
4505 if (TREE_CODE (decl) == CONST_DECL)
4506 {
4507 my_friendly_assert (TREE_CODE (decl) != REFERENCE_TYPE, 148);
4508
4509 DECL_INITIAL (decl) = init;
4510
4511 my_friendly_assert (init != NULL_TREE, 149);
4512 init = NULL_TREE;
4513 }
4514 else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)
4515 init = grok_reference_init (decl, type, init, cleanup);
4516 else if (init)
4517 {
4518 if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
4519 {
4520 /* [dcl.init] paragraph 13,
4521 If T is a scalar type, then a declaration of the form
4522 T x = { a };
4523 is equivalent to
4524 T x = a;
4525
4526 reshape_init will complain about the extra braces,
4527 and doesn't do anything useful in the case where TYPE is
4528 scalar, so just don't call it. */
4529 if (CP_AGGREGATE_TYPE_P (type))
4530 init = reshape_init (type, &init);
4531
4532 if ((*targetm .vector_opaque_p) (type))
4533 {
4534 error ("opaque vector types cannot be initialized");
4535 init = error_mark_node;
4536 }
4537 }
One of clause of [dcl.init.aggr] of C++ standard specifies that:
All implicit type conversions (clause 4) are considered when initializing the aggregate member with an initializer from an initializer-list. If the initializer can initialize a member, the member is initialized. Otherwise, if the member is itself a non-empty subaggregate, brace elision is assumed and the initializer is considered for the initialization of the first member of the subaggregate. For example:
struct A {
int i;
operator int();
};
struct B {
A a1, a2;
int z;
};
A a;
B b = { 4, a, a };
Braces are elided around the initializer for b.a1.i. b.a1.i is initialized with 4, b.a2 is initialized with a, b.z is initialized with whatever a.operator int() returns.
Routine reshape_init is invoked to transform the initializers list in form of {4, a, a } into the form of { {4, a}, a}. The rear one is what expected by the front-end.
Here for our example, the VAR_DECL is the array of vtable_entry_type and initp refers to the CONSTRUCTOR node for the initializers, which is deliberately created with empty type. So code in block at line 4289 is executed. CONSTRUCTOR_ELTS returns the inits generated in above. These initializers are treated as if enclosed by braces.
4267 static tree
4268 reshape_init (tree type, tree *initp) in decl.c
4269 {
4270 tree inits;
4271 tree old_init;
4272 tree old_init_value;
4273 tree new_init;
4274 bool brace_enclosed_p;
4275 bool string_init_p;
4276
4277 old_init = *initp;
4278 old_init_value = (TREE_CODE (*initp) == TREE_LIST
4279 ? TREE_VALUE (*initp) : old_init);
4280
4281 my_friendly_assert (old_init_value, 20030723);
4282
4283 /* If the initializer is brace-enclosed, pull initializers from the
4284 enclosed elements. Advance past the brace-enclosed initializer
4285 now. */
4286 if (TREE_CODE (old_init_value) == CONSTRUCTOR
4287 && TREE_TYPE (old_init_value) == NULL_TREE
4288 && TREE_HAS_CONSTRUCTOR (old_init_value))
4289 {
4290 *initp = TREE_CHAIN (old_init);
4291 TREE_CHAIN (old_init) = NULL_TREE;
4292 inits = CONSTRUCTOR_ELTS (old_init_value);
4293 initp = &inits;
4294 brace_enclosed_p = true;
4295 }
4296 else
4297 {
4298 inits = NULL_TREE;
4299 brace_enclosed_p = false;
4300 }
4301
4302 /* A non-aggregate type is always initialized with a single
4303 initializer. */
4304 if (!CP_AGGREGATE_TYPE_P (type))
4305 {
4306 *initp = TREE_CHAIN (old_init);
4307 TREE_CHAIN (old_init) = NULL_TREE;
4308 /* It is invalid to initialize a non-aggregate type with a
4309 brace-enclosed initializer. */
4310 if (brace_enclosed_p)
4311 {
4312 error ("brace-enclosed initializer used to initialize `%T'",
4313 type);
4314 if (TREE_CODE (old_init) == TREE_LIST)
4315 TREE_VALUE (old_init) = error_mark_node;
4316 else
4317 old_init = error_mark_node;
4318 }
4319
4320 return old_init;
4321 }
4322
4323 /* [dcl.init.aggr]
4324
4325 All implicit type conversions (clause _conv_) are considered when
4326 initializing the aggregate member with an initializer from an
4327 initializer-list. If the initializer can initialize a member,
4328 the member is initialized. Otherwise, if the member is itself a
4329 non-empty subaggregate, brace elision is assumed and the
4330 initializer is considered for the initialization of the first
4331 member of the subaggregate. */
4332 if (!brace_enclosed_p
4333 && can_convert_arg (type, TREE_TYPE (old_init_value), old_init_value))
4334 {
4335 *initp = TREE_CHAIN (old_init);
4336 TREE_CHAIN (old_init) = NULL_TREE;
4337 return old_init;
4338 }
4339
4340 string_init_p = false;
4341 if (TREE_CODE (old_init_value) == STRING_CST
4342 && TREE_CODE (type) == ARRAY_TYPE
4343 && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
4344 {
…
4356 }
4357 else
4358 {
4359 /* Build a CONSTRUCTOR to hold the contents of the aggregate. */
4360 new_init = build_constructor (type, NULL_TREE);
4361 TREE_HAS_CONSTRUCTOR (new_init) = 1;
4362
4363 if (CLASS_TYPE_P (type))
4364 {
…
4419 }
4420 else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
4421 {
4422 tree max_index;
4423
4424 /* If the bound of the array is known, take no more initializers
4425 than are allowed. */
4426 max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))
4427 ? array_type_nelts (type) : NULL_TREE);
4428 if (!reshape_init_array (TREE_TYPE (type), max_index,
4429 initp, new_init))
4430 return error_mark_node;
4431 }
4432 else
4433 abort ();
4434
4435 /* The initializers were placed in reverse order in the
4436 CONSTRUCTOR. */
4437 CONSTRUCTOR_ELTS (new_init) = nreverse (CONSTRUCTOR_ELTS (new_init));
4438
4439 if (TREE_CODE (old_init) == TREE_LIST)
4440 new_init = build_tree_list (TREE_PURPOSE (old_init), new_init);
4441 }
4442
4443 /* If there are more initializers than necessary, issue a
4444 diagnostic. */
4445 if (*initp)
4446 {
4447 if (brace_enclosed_p)
4448 error ("too many initializers for `%T'", type);
4449 else if (warn_missing_braces && !string_init_p)
4450 warning ("missing braces around initializer");
4451 }
4452
4453 return new_init;
4454 }
See for aggregate member, line 4333 verifies that type of the initializer can be converted to that of member. For array, below reshape_init_array iterates every element by reshape_init to verify and reshape the initializer. For non-aggregate member, the initializer is just returned.
4203 static bool
4204 reshape_init_array (tree elt_type, tree max_index, in decl.c
4205 tree *initp, tree new_init)
4206 {
4207 bool sized_array_p = (max_index != NULL_TREE);
4208 unsigned HOST_WIDE_INT max_index_cst = 0;
4209 unsigned HOST_WIDE_INT index;
4210
4211 if (sized_array_p)
4212 {
4213 if (host_integerp (max_index, 1))
4214 max_index_cst = tree_low_cst (max_index, 1);
4215 /* sizetype is sign extended, not zero extended. */
4216 else
4217 max_index_cst = tree_low_cst (convert (size_type_node, max_index), 1);
4218 }
4219
4220 /* Loop until there are no more initializers. */
4221 for (index = 0;
4222 *initp && (!sized_array_p || index <= max_index_cst);
4223 ++index)
4224 {
4225 tree element_init;
4226 tree designated_index;
4227
4228 element_init = reshape_init (elt_type, initp);
4229 if (element_init == error_mark_node)
4230 return false;
4231 TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
4232 CONSTRUCTOR_ELTS (new_init) = element_init;
4233 designated_index = TREE_PURPOSE (element_init);
4234 if (designated_index)
4235 {
4236 /* Handle array designated initializers (GNU extension). */
4237 if (TREE_CODE (designated_index) == IDENTIFIER_NODE)
4238 {
4239 error ("name `%D' used in a GNU-style designated "
4240 "initializer for an array", designated_index);
4241 TREE_PURPOSE (element_init) = NULL_TREE;
4242 }
4243 else
4244 abort ();
4245 }
4246 }
4247
4248 return true;
4259 }
Here TREE_PURPOSE of every initializer of our example is empty (TREE_PURPOSE is used for designated initializer, IBM’s XL C supports this feature, detail see here . See that the new CONSTRUCTOR generated has type assigned when compared with former one.
Then in check_initializer at line 4532, under x86 machine, vector_opaque_p hook in targetm always returns false. And below maybe_deduce_size_from_array_init sets the size field in the node of array, for example: int a[] = { 1, 2, 3}; the function should set the size of 3 into the node.
check_initializer (continue)
4539 /* If DECL has an array type without a specific bound, deduce the
4540 array size from the initializer. */
4541 maybe_deduce_size_from_array_init (decl, init);
4542 type = TREE_TYPE (decl);
4543 if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
4544 TREE_TYPE (init) = type;
4545
4546 if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
4547 {
…
4579 }
4580 else
4581 {
4582 dont_use_constructor:
4583 if (TREE_CODE (init) != TREE_VEC)
4584 {
4585 init_code = store_init_value (decl, init);
4586 init = NULL;
4587 }
4588 }
4589 }
4590 else if (DECL_EXTERNAL (decl))
4591 ;
4592 else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type))
4593 goto initialize_aggr;
4594 else if (IS_AGGR_TYPE (type))
4595 {
4596 tree core_type = strip_array_types (type);
4597
4598 if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type))
4599 error ("structure `%D' with uninitialized const members", decl);
4600 if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))
4601 error ("structure `%D' with uninitialized reference members",
4602 decl);
4603
4604 check_for_uninitialized_const_var (decl);
4605 }
4606 else
4607 check_for_uninitialized_const_var (decl);
4608
4609 if (init && init != error_mark_node)
4610 init_code = build (INIT_EXPR, type, decl, init);
4611
4612 return init_code;
4613 }
Type of decl is vtbl_type_node which is ARRAY_TYPE of vtable_entry_type which in turn is a pointer of certain function type; of course no constructor is defined for this ARRAY_TYPE. So condition at line 4546 is false for type .
410 tree
411 store_init_value (tree decl, tree init) in typeck2.c
412 {
413 tree value, type;
414
415 /* If variable's type was invalidly declared, just ignore it. */
416
417 type = TREE_TYPE (decl);
418 if (TREE_CODE (type) == ERROR_MARK)
419 return NULL_TREE;
420
421 if (IS_AGGR_TYPE (type))
422 {
…
432 }
433 else if (TREE_CODE (init) == TREE_LIST
434 && TREE_TYPE (init) != unknown_type_node)
435 {
…
448 }
449
450 /* Digest the specified initializer into an expression. */
451 value = digest_init (type, init, (tree *) 0);
452 /* If the initializer is not a constant, fill in DECL_INITIAL with
453 the bits that are constant, and then return an expression that
454 will perform the dynamic initialization. */
455 if (value != error_mark_node
456 && (! TREE_CONSTANT (value)
457 || ! initializer_constant_valid_p (value, TREE_TYPE (value))))
458 return split_nonconstant_init (decl, value);
459 /* If the value is a constant, just put it in DECL_INITIAL. If DECL
460 is an automatic variable, the middle end will turn this into a
461 dynamic initialization later. */
462 DECL_INITIAL (decl) = value;
463 return NULL_TREE;
464 }
Here argument type is the type of the VAR_DECL. Initializers needsn’t be the same type as corresponding member as long as appropriate convertor is found. The purpose of digest_init is to find the applicable convertor and generate necessary code for this conversion, if type and init can’t match exactly.
476 tree
477 digest_init (tree type, tree init, tree* tail) in typeck2.c
478 {
479 enum tree_code code = TREE_CODE (type);
480 tree element = NULL_TREE;
481 tree old_tail_contents = NULL_TREE;
482 /* Nonzero if INIT is a braced grouping. */
483 int raw_constructor;
484
485 /* By default, assume we use one element from a list.
486 We correct this later in the sole case where it is not true. */
487
488 if (tail)
489 {
490 old_tail_contents = *tail;
491 *tail = TREE_CHAIN (*tail);
492 }
493
494 if (init == error_mark_node || (TREE_CODE (init) == TREE_LIST
495 && TREE_VALUE (init) == error_mark_node))
496 return error_mark_node;
497
498 if (TREE_CODE (init) == ERROR_MARK)
499 /* __PRETTY_FUNCTION__'s initializer is a bogus expression inside
500 a template function. This gets substituted during instantiation. */
501 return init;
502
503 /* We must strip the outermost array type when completing the type,
504 because the its bounds might be incomplete at the moment. */
505 if (!complete_type_or_else (TREE_CODE (type) == ARRAY_TYPE
506 ? TREE_TYPE (type) : type, NULL_TREE))
507 return error_mark_node;
508
509 /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
510 if (TREE_CODE (init) == NON_LVALUE_EXPR)
511 init = TREE_OPERAND (init, 0);
512
513 raw_constructor = (TREE_CODE (init) == CONSTRUCTOR
514 && TREE_HAS_CONSTRUCTOR (init));
515
516 if (raw_constructor
517 && CONSTRUCTOR_ELTS (init) != 0
518 && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)
519 {
520 element = TREE_VALUE (CONSTRUCTOR_ELTS (init));
521 /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
522 if (element && TREE_CODE (element) == NON_LVALUE_EXPR)
523 element = TREE_OPERAND (element, 0);
524 if (element == error_mark_node)
525 return element;
526 }
527
528 /* Initialization of an array of chars from a string constant
529 optionally enclosed in braces. */
530
531 if (code == ARRAY_TYPE)
532 {
533 tree typ1;
534
535 if (TREE_CODE (init) == TREE_LIST)
536 {
537 error ("initializing array with parameter list");
538 return error_mark_node;
539 }
540
541 typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
542 if (char_type_p (typ1)
543 && ((init && TREE_CODE (init) == STRING_CST)
544 || (element && TREE_CODE (element) == STRING_CST)))
545 {
…
577 }
578 }
579
580 /* Handle scalar types, including conversions,
581 and signature pointers and references. */
582
583 if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
584 || code == ENUMERAL_TYPE || code == REFERENCE_TYPE
585 || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
586 || TYPE_PTR_TO_MEMBER_P (type))
587 {
588 if (raw_constructor)
589 {
590 if (element == 0)
591 {
592 error ("initializer for scalar variable requires one element");
593 return error_mark_node;
594 }
595 init = element;
596 }
597 while (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
598 {
599 pedwarn ("braces around scalar initializer for `%T'", type);
600 init = CONSTRUCTOR_ELTS (init);
601 if (TREE_CHAIN (init))
602 pedwarn ("ignoring extra initializers for `%T'", type);
603 init = TREE_VALUE (init);
604 }
605
606 return convert_for_initialization (0, type, init, LOOKUP_NORMAL,
607 "initialization", NULL_TREE, 0);
608 }
609
610 /* Come here only for records and arrays (and unions with constructors). */
611
612 if (COMPLETE_TYPE_P (type) && ! TREE_CONSTANT (TYPE_SIZE (type)))
613 {
614 error ("variable-sized object of type `%T' may not be initialized",
615 type);
616 return error_mark_node;
617 }
618
619 if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))
620 {
621 if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)
622 && TREE_HAS_CONSTRUCTOR (init))
623 {
624 error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
625 type, init);
626 return error_mark_node;
627 }
628 else if (raw_constructor)
629 return process_init_constructor (type, init, (tree *)0);
…
649 }
650
651 error ("invalid initializer");
652 return error_mark_node;
653 }
For the initializers of our example, at line 513, raw_constructor is nonzero; and code is ARRAY_TYPE. Then argument init is passed to process_init_constructor for handling.
670 static tree
671 process_init_constructor (tree type, tree init, tree* elts) in typeck2.c
672 {
673 tree tail;
674 /* List of the elements of the result constructor,
675 i n reverse order. */
676 tree members = NULL;
677 tree next1;
678 tree result;
679 int allconstant = 1;
680 int allsimple = 1;
681 int erroneous = 0;
682
683 /* Make TAIL be the list of elements to use for the initialization,
684 no matter how the data was given to us. */
685
686 if (elts)
687 {
688 if (warn_missing_braces )
689 warning ("aggregate has a partly bracketed initializer");
690 tail = *elts;
691 }
692 else
693 tail = CONSTRUCTOR_ELTS (init);
694
695 /* Gobble as many elements as needed, and make a constructor or initial value
696 for each element of this aggregate. Chain them together in result.
697 If there are too few, use 0 for each scalar ultimate component. */
698
699 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
700 {
701 long len;
702 int i;
703
704 if (TREE_CODE (type) == ARRAY_TYPE)
705 {
706 tree domain = TYPE_DOMAIN (type);
707 if (domain)
708 len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))
709 - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
710 + 1);
711 else
712 len = -1; /* Take as many as there are. */
713 }
714 else
715 {
716 /* Vectors are like simple fixed-size arrays. */
717 len = TYPE_VECTOR_SUBPARTS (type);
718 }
719
720 for (i = 0; len < 0 || i < len; i++)
721 {
722 if (tail)
723 {
724 if (TREE_PURPOSE (tail)
725 && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
726 || compare_tree_int (TREE_PURPOSE (tail), i) != 0))
727 sorry ("non-trivial labeled initializers");
728
729 if (TREE_VALUE (tail) != 0)
730 {
731 tree tail1 = tail;
732 next1 = digest_init (TREE_TYPE (type),
733 TREE_VALUE (tail), &tail1);
734 if (next1 == error_mark_node)
735 return next1;
736 my_friendly_assert
737 (same_type_ignoring_top_level_qualifiers_p
738 (TREE_TYPE (type), TREE_TYPE (next1)),
739 981123);
740 my_friendly_assert (tail1 == 0
741 || TREE_CODE (tail1) == TREE_LIST, 319);
742 if (tail == tail1 && len < 0)
743 {
744 error ("non-empty initializer for array of empty elements");
745 /* Just ignore what we were supposed to use. */
746 tail1 = NULL_TREE;
747 }
748 tail = tail1;
749 }
750 else
751 {
752 next1 = error_mark_node;
753 tail = TREE_CHAIN (tail);
754 }
755 }
756 else if (len < 0)
757 /* We're done. */
758 break ;
759 else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
760 {
…
771 }
772 else if (! zero_init_p (TREE_TYPE (type)))
773 next1 = build_zero_init (TREE_TYPE (type),
774 /*nelts=*/ NULL_TREE,
775 /*static_storage_p=*/ false);
776 else
777 /* The default zero-initialization is fine for us; don't
778 add anything to the CONSTRUCTOR. */
779 break ;
780
781 if (next1 == error_mark_node)
782 erroneous = 1;
783 else if (!TREE_CONSTANT (next1))
784 allconstant = 0;
785 else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1)))
786 allsimple = 0;
787 members = tree_cons (size_int (i), next1, members);
788 }
789 }
790 else if (TREE_CODE (type) == RECORD_TYPE)
791 {
…
908 }
909 else if (TREE_CODE (type) == UNION_TYPE
910 /* If the initializer was empty, use default zero initialization. */
911 && tail)
912 {
…
977 }
978
979 /* If arguments were specified as a list, just remove the ones we used. */
980 if (elts)
981 *elts = tail;
982 /* If arguments were specified as a constructor,
983 complain unless we used all the elements of the constructor. */
984 else if (tail)
985 pedwarn ("excess elements in aggregate initializer");
986
987 if (erroneous)
988 return error_mark_node;
989
990 result = build_constructor (type, nreverse (members));
991 if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
992 complete_array_type (type, result, /*do_default=*/ 0);
993 if (init)
994 TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);
995 if (allconstant) TREE_CONSTANT (result) = 1;
996 if (allconstant && allsimple) TREE_STATIC (result) = 1;
997 return result;
998 }
Not surprising, for each element of ARRAY_TYPE, digest_init is recursed. Note that in this invocation, argument tail is the initializers. If digest_init can process part of initializers successfully. This part will be removed from the list of initializers. At line 606, convert_for_initialization is invoked to do the possible conversion. Here in our example, no conversion is expected as we prepare init of type vtable_entry_type before hand. As a result, the function returns init as returned value.
Exitting convert_for_initialization gets out of digest_init immediately, which means this (part) initializer is verified. At line 787, this returned value is chained into members . Next at line 990, new version CONSTRUCTOR is created. See that all elements of vtable should be constant. And this CONSTRUCTOR allocates static storage (i.e, initializes static member). Then at line 4902 in cp_finish_decl , store_init_value returns NULL
cp_finish_decl (continue)
4953 /* Add this declaration to the statement-tree. This needs to happen
4954 after the call to check_initializer so that the DECL_STMT for a
4955 reference temp is added before the DECL_STMT for the reference itself. */
4956 if (at_function_scope_p ())
4957 add_decl_stmt (decl);
4958
4959 if (TREE_CODE (decl) == VAR_DECL)
4960 layout_var_decl (decl);
4961
4962 /* Output the assembler code and/or RTL code for variables and functions,
4963 unless the type is an undefined structure or union.
4964 If not, it will get done when the type is completed. */
4965 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
4966 {
4967 if (TREE_CODE (decl) == VAR_DECL)
4968 maybe_commonize_var (decl);
4969
4970 make_rtl_for_nonlocal_decl (decl, init, asmspec);
4971
4972 if (TREE_CODE (type) == FUNCTION_TYPE
4973 || TREE_CODE (type) == METHOD_TYPE)
4974 abstract_virtuals_error (decl,
4975 strip_array_types (TREE_TYPE (type)));
4976 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
4977 {
4978 /* If it's either a pointer or an array type, strip through all
4979 of them but the last one. If the last is an array type, issue
4980 an error if the element type is abstract. */
4981 while (POINTER_TYPE_P (TREE_TYPE (type))
4982 || TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
4983 type = TREE_TYPE (type);
4984 if (TREE_CODE (type) == ARRAY_TYPE)
4985 abstract_virtuals_error (decl, TREE_TYPE (type));
4986 }
4987 else
4988 abstract_virtuals_error (decl, type);
4989
4990 if (TREE_CODE (decl) == FUNCTION_DECL
4991 || TREE_TYPE (decl) == error_mark_node)
4992 /* No initialization required. */
4993 ;
4994 else if (DECL_EXTERNAL (decl)
4995 && ! (DECL_LANG_SPECIFIC (decl)
4996 && DECL_NOT_REALLY_EXTERN (decl)))
4997 {
4998 if (init)
4999 DECL_INITIAL (decl) = init;
5000 }
5001 else
5002 {
5003 /* A variable definition. */
5004 if (DECL_FUNCTION_SCOPE_P (decl))
5005 {
5006 /* This is a local declaration. */
5007 maybe_inject_for_scope_var (decl);
5008 /* Initialize the local variable. */
5009 if (processing_template_decl )
5010 {
5011 if (init || DECL_INITIAL (decl) == error_mark_node)
5012 DECL_INITIAL (decl) = init;
5013 }
5014 else if (!TREE_STATIC (decl))
5015 initialize_local_var (decl, init);
5016 }
5017
5018 /* If a variable is defined, and then a subsequent
5019 definintion with external linkage is encountered, we will
5020 get here twice for the same variable. We want to avoid
5021 calling expand_static_init more than once. For variables
5022 that are not static data members, we can call
5023 expand_static_init only when we actually process the
5024 initializer. It is not legal to redeclare a static data
5025 member, so this issue does not arise in that case. */
5026 if (var_definition_p && TREE_STATIC (decl))
5027 expand_static_init (decl, init);
5028 }
5029 finish_end0:
5030
5031 /* Undo call to `pushclass' that was done in `start_decl'
5032 due to initialization of qualified member variable.
5033 I.e., Foo::x = 10; */
5034 {
5035 tree context = CP_DECL_CONTEXT (decl);
5036 if (context
5037 && TYPE_P (context)
5038 && (TREE_CODE (decl) == VAR_DECL
5039 /* We also have a pushclass done that we need to undo here
5040 if we're at top level and declare a method. */
5041 || TREE_CODE (decl) == FUNCTION_DECL)
5042 /* If size hasn't been set, we're still defining it,
5043 and therefore inside the class body; don't pop
5044 the binding level.. */
5045 && COMPLETE_TYPE_P (context)
5046 && context == current_class_type )
5047 pop_nested_class ();
5048 }
5049 }
5050
5051 /* If a CLEANUP_STMT was created to destroy a temporary bound to a
5052 reference, insert it in the statement-tree now. */
5053 if (cleanup)
5054 add_stmt (cleanup);
5055
5056 finish_end:
5057
5058 if (was_readonly)
5059 TREE_READONLY (decl) = 1;
5060
5061 /* If this was marked 'used', be sure it will be output. */
5062 if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
5063 mark_referenced (DECL_ASSEMBLER_NAME (decl));
5064 }
As in initialize_array at line 6809, context of decl is temperarily cleaned, at_function_scope_p at line 4956 returns false. Then maybe_commonize_var at line 4968 handles the situation in which a local static variable is declared in an inline function, or we have a weak definition, for which the compile must endeavor to create only one instance of the variable at link-time.
Then back cp_finish_decl , at line 4970, within make_rtl_for_nonlocal_decl , the local variable defer_p is set as true at line 4658 as this VAR_DECL has flag DECL_VIRTUAL_P set; further at invocation, asmspec is NULL. So nothing non-trivial is done in this function.
Next, as var_definition_p is true at line 5026, expand_static_init is invoked, however, as the ARRAY_TYPE of the vtable hasn’t flag TYPE_NEEDS_CONSTRUCTING set, the function exits immediately.
At last, cleanup at line 5053 may be not NULL if we are handling referecne (here it is NULL). Exitting from cp_finish_decl , we go back finish_struct_1 in below.