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.
Thanks, Paolo.
////////////////////////
/cp
2018-01-18 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/83921
* constexpr.c (potential_constant_expression_1): Do not handle
uninitialized vars in constexpr function here.
/testsuite
2018-01-18 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/83921
* g++.dg/cpp1y/constexpr-83921.C: New.
* g++.dg/ext/stmtexpr20.C: Likewise.
Index: cp/constexpr.c
===================================================================
--- cp/constexpr.c (revision 256865)
+++ cp/constexpr.c (working copy)
@@ -5708,7 +5708,9 @@ potential_constant_expression_1 (tree t, bool want
"%<thread_local%> in %<constexpr%> context", tmp);
return false;
}
- else if (!DECL_NONTRIVIALLY_INITIALIZED_P (tmp))
+ else if (!DECL_NONTRIVIALLY_INITIALIZED_P (tmp)
+ /* Handled in check_for_uninitialized_const_var. */
+ && !var_in_constexpr_fn (tmp))
{
if (flags & tf_error)
error_at (DECL_SOURCE_LOCATION (tmp), "uninitialized "
Index: testsuite/g++.dg/cpp1y/constexpr-83921.C
===================================================================
--- testsuite/g++.dg/cpp1y/constexpr-83921.C (nonexistent)
+++ testsuite/g++.dg/cpp1y/constexpr-83921.C (working copy)
@@ -0,0 +1,7 @@
+// PR c++/83921
+// { dg-do compile { target c++14 } }
+
+struct Foo {};
+constexpr void test() {
+ Foo f;
+}
Index: testsuite/g++.dg/ext/stmtexpr20.C
===================================================================
--- testsuite/g++.dg/ext/stmtexpr20.C (nonexistent)
+++ testsuite/g++.dg/ext/stmtexpr20.C (working copy)
@@ -0,0 +1,15 @@
+// PR c++/83921
+// { dg-options "" }
+// { dg-do compile { target c++11 } }
+
+struct test { const int *addr; };
+
+const test* setup()
+{
+ static constexpr test atest =
+ {
+ ({ int inner; &inner; }) // { dg-error "uninitialized" }
+ };
+
+ return &atest;
+}