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.