Hi,

On 19/01/2018 23:28, Jason Merrill wrote:
On Thu, Jan 18, 2018 at 5:53 PM, Paolo Carlini <paolo.carl...@oracle.com> wrote:
Hi,

I'm finishing testing on x86_64-linux the below - which anyway seems very
unlikely to cause regressions because we aren't really stress testing the
relevant checks in potential_constant_expression_1 much, if at all (surely
stmtexpr19.C tests static).

Anyway, the issue is the following. In 239268 aka "Implement C++17 constexpr
lambda" Jason added some checks to potential_constant_expression_1 covering
static, thread_local and uninitialized var declaration in constexpr function
context. Then extended to constexpr context more generally in 249382 aka
"constexpr and static var in statement-expression", with ext/stmtexpr19.C
covering the static case. Now, it looks like the check for uninitialized
vars in constexpr functions context is more correctly carried out by
check_for_uninitialized_const_var instead, because the simple check in
potential_constant_expression_1 as-is causes the regression pointed out by
this bug. Thus the fix below which just restricts the check in
potential_constant_expression_1, and the testcases, one for this bug proper,
plus one, very similar to stmtexpr19.C, double checking that we are still
diagnosing in the statement-expression context. I also verified under the
debugger how for constexpr-83921.C we are actually running
check_for_uninitialized_const_var on 'f' - which obviously passes.
Seems like this code should either be removed because it's covered by
check_for_uninitialized_const_var, or it should be fixed to check
default_init_uninitialized_part.

So this code is still needed for stmtexpr19.C?  Why doesn't
check_for_... handle that case?
Well, stmtexpr19.C exists to exercise 'static', which definitely check_for_uninitialized_const_var doesn't cover. The same would be true for a testcase exercising 'thread_local'. As regards my new stmtexpr20.C, check_for_uninitialized_const_var can't diagnose anything for a very simple reason:

  if (VAR_P (decl)
      && TREE_CODE (type) != REFERENCE_TYPE
      && (CP_TYPE_CONST_P (type) || var_in_constexpr_fn (decl))
      && !DECL_INITIAL (decl))

thus doesn't do anything for non-const vars outside a constexpr function. On the other hand, !DECL_NONTRIVIALLY_INITIALIZED_P is true for such vars in constexpr context which actually belong to a statement expression (always?). Therefore It seems to me that a way to more cleanly solve the bug would be moving something like || !DECL_NONTRIVIALLY_INITIALIZED_P to the the above check in check_for_uninitialized_const_var, and therefore remove completely the uninitialized case from potential_constant_expression_1, but I'm note sure it would always work because at the moment isn't entirely clear to me how DECL_NONTRIVIALLY_INITIALIZED_P reflects the statement-expression context bit (that explain the conservative slant of my patch) What do you think?

Paolo.

Reply via email to