https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81933
--- Comment #5 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Here's what happens.
We get the "flows off" error because:
4151 if (tree init = DECL_INITIAL (r))
4152 {
4153 init = cxx_eval_constant_expression (ctx, init,
4154 false,
4155 non_constant_p,
overflow_p);
4156 /* Don't share a CONSTRUCTOR that might be changed. */
4157 init = unshare_constructor (init);
4158 ctx->values->put (r, init);
4159 }
r's DECL_INITIAL is null and we don't put the CONSTRUCTOR in ctx->values. So
here:
1702 result = *ctx->values->get (slot ? slot : res);
1703 if (result == NULL_TREE && !*non_constant_p)
1704 {
1705 if (!ctx->quiet)
1706 error ("%<constexpr%> call flows off the end "
1707 "of the function");
1708 *non_constant_p = true;
1709 }
result is null -> error.
Why was the DECL_INITIAL null? Because in c++17 we execute the hunk in Comment
4, which puts some additional fields into some classes. This makes a
difference for split_nonconstant_init:
751 if (split_nonconstant_init_1 (dest, init))
752 init = NULL_TREE;
where split_nonconstant_init_1 is true so that means that the DECL_INITIAL will
be null. Why is split_nonconstant_init_1 true? Because it ends up calling
complete_ctor_at_level_p with
6114 return count_type_elements (type, true) == num_elts;
but the count_type_elements result differs between c++14/c++17 precisely
because of the fields added in build_base_field.
But we should only add those fields when initializing aggregates with bases,
which is not what's happening in Comment 2's testcase.