Hi,
On 20/01/2018 02:59, Paolo Carlini wrote:
Hi again,
On 19/01/2018 23:55, Paolo Carlini wrote:
...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, ...
Of course this doesn't work. check_for_uninitialized_const would
really need to know that the VAR_DECL appears in a statement
expression which is initializing a constexpr variable, nothing to do
with DECL_NONTRIVIALLY_INITIALIZED_P. I'll give the issue more thought
over the we, but removing completely the check from
potential_constant_expression_1 seems very tough to me, assuming of
course we really care about diagnosing the uninitialized inner in
stmtexpr20.C, which is my invention, isn't in the testsuite yet ;)
Thus the below, carefully tested over the we, would be a change
completely removing the problematic error_at call, plus some testcases
checking that we would still do the right thing in a few cases (bug
submitter added constexpr-83921-2.C). The updated stmtexpr20.C shows
that we would reject anyway a statement expression using an
uninitialized inner, simply because the whole initializer would still be
flagged as non const. ICC does the same. CLANG diagnoses the
uninitialized inner but then actually accepts something using 'static
const int inner = 1' whereas we don't anyway, we (and ICC) don't accept
anything similar to stmtexpr20.C. So, I would say this kind of change
may actually make sense...
Thanks,
Paolo.
//////////////////////.
Index: cp/constexpr.c
===================================================================
--- cp/constexpr.c (revision 256939)
+++ cp/constexpr.c (working copy)
@@ -5707,13 +5707,6 @@ potential_constant_expression_1 (tree t, bool want
"%<thread_local%> in %<constexpr%> context", tmp);
return false;
}
- else if (!DECL_NONTRIVIALLY_INITIALIZED_P (tmp))
- {
- if (flags & tf_error)
- error_at (DECL_SOURCE_LOCATION (tmp), "uninitialized "
- "variable %qD in %<constexpr%> context", tmp);
- return false;
- }
}
return RECUR (tmp, want_rval);
Index: testsuite/g++.dg/cpp1y/constexpr-83921-1.C
===================================================================
--- testsuite/g++.dg/cpp1y/constexpr-83921-1.C (nonexistent)
+++ testsuite/g++.dg/cpp1y/constexpr-83921-1.C (working copy)
@@ -0,0 +1,5 @@
+// PR c++/83921
+// { dg-do compile { target c++14 } }
+
+struct Foo { };
+constexpr void test() { Foo f; }
Index: testsuite/g++.dg/cpp1y/constexpr-83921-2.C
===================================================================
--- testsuite/g++.dg/cpp1y/constexpr-83921-2.C (nonexistent)
+++ testsuite/g++.dg/cpp1y/constexpr-83921-2.C (working copy)
@@ -0,0 +1,5 @@
+// PR c++/83921
+// { dg-do compile { target c++14 } }
+
+struct Foo { Foo() = default; };
+constexpr void test() { Foo f; }
Index: testsuite/g++.dg/cpp1y/constexpr-83921-3.C
===================================================================
--- testsuite/g++.dg/cpp1y/constexpr-83921-3.C (nonexistent)
+++ testsuite/g++.dg/cpp1y/constexpr-83921-3.C (working copy)
@@ -0,0 +1,5 @@
+// PR c++/83921
+// { dg-do compile { target c++14 } }
+
+struct Foo { int m; };
+constexpr void test() { Foo f; } // { dg-error "uninitialized" }
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,13 @@
+// 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 "not a constant" }
+
+ return &atest;
+}