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;
+}

Reply via email to