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.