public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/67364 (constexpr vs. empty class)
@ 2016-02-25 14:08 Jason Merrill
  2016-03-03 22:37 ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Merrill @ 2016-02-25 14:08 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 165 bytes --]

We don't bother evaluating a store to an empty class member, and we 
shouldn't complain about accesses either.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.

[-- Attachment #2: 67364.patch --]
[-- Type: text/x-patch, Size: 1349 bytes --]

commit fd0e8f3776afa35340bcd3c555280012aa82f645
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Feb 24 17:14:41 2016 -0500

    	PR c++/67364
    	* constexpr.c (cxx_eval_component_reference): Don't complain about
    	unevaluated empty classes.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index d3b04b1..8d9168c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1983,7 +1983,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
       return t;
     }
 
-  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole))
+  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole)
+      && !is_empty_class (TREE_TYPE (part)))
     {
       /* 'whole' is part of the aggregate initializer we're currently
 	 building; if there's no initializer for this member yet, that's an
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty10.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty10.C
new file mode 100644
index 0000000..694ed3d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty10.C
@@ -0,0 +1,17 @@
+// PR c++/67364
+// { dg-do compile { target c++11 } }
+
+template <typename Xn>
+struct element : Xn {
+  constexpr element() : Xn() { }
+};
+
+template <typename Xn>
+struct closure {
+  element<Xn> member;
+  constexpr closure() { }
+};
+
+struct empty { };
+constexpr closure<empty> tup{};
+constexpr empty first = tup.member;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/67364 (constexpr vs. empty class)
  2016-02-25 14:08 C++ PATCH for c++/67364 (constexpr vs. empty class) Jason Merrill
@ 2016-03-03 22:37 ` Jason Merrill
  2016-03-04 22:05   ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Merrill @ 2016-03-03 22:37 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 298 bytes --]

On 02/25/2016 09:08 AM, Jason Merrill wrote:
> We don't bother evaluating a store to an empty class member, and we
> shouldn't complain about accesses either.

This needs to use really_empty_class, since that's what 
expand_aggr_init_1 uses.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.



[-- Attachment #2: 67364.patch --]
[-- Type: text/x-patch, Size: 1601 bytes --]

commit 9a1d6b7c9fa018033ff444829ad3c597e61f5120
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 2 14:33:54 2016 -0500

    	PR c++/67364
    
    	* constexpr.c (cxx_eval_component_reference): Just return an empty
    	CONSTRUCTOR for an empty class.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index bcb129f..5a81469 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1988,11 +1988,12 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
     }
 
   if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole)
-      && !is_empty_class (TREE_TYPE (part)))
+      && !is_really_empty_class (TREE_TYPE (t)))
     {
       /* 'whole' is part of the aggregate initializer we're currently
 	 building; if there's no initializer for this member yet, that's an
-	 error. */
+	 error.  But expand_aggr_init_1 doesn't bother to initialize really
+	 empty classes, so ignore them here, too.  */
       if (!ctx->quiet)
 	error ("accessing uninitialized member %qD", part);
       *non_constant_p = true;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C
new file mode 100644
index 0000000..7437367
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C
@@ -0,0 +1,17 @@
+// PR c++/67364
+// { dg-do compile { target c++11 } }
+
+template <typename Xn>
+struct element : Xn {
+  constexpr element() : Xn() { }
+};
+
+template <typename Xn>
+struct closure {
+  element<Xn> member;
+  constexpr closure() { }
+};
+
+struct empty { struct {} s; };
+constexpr closure<empty> tup{};
+constexpr empty first = tup.member;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/67364 (constexpr vs. empty class)
  2016-03-03 22:37 ` Jason Merrill
@ 2016-03-04 22:05   ` Jason Merrill
  0 siblings, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2016-03-04 22:05 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

On 03/03/2016 05:37 PM, Jason Merrill wrote:
> On 02/25/2016 09:08 AM, Jason Merrill wrote:
>> We don't bother evaluating a store to an empty class member, and we
>> shouldn't complain about accesses either.
>
> This needs to use really_empty_class, since that's what
> expand_aggr_init_1 uses.

And even calling build_value_init is wrong for these classes, as it 
might not be well-formed.  Just build a value directly.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.



[-- Attachment #2: 67364-3.patch --]
[-- Type: text/x-patch, Size: 1845 bytes --]

commit 6207dfd6bce685275831f468e9954bec71d39430
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Mar 4 15:40:16 2016 -0500

    	PR c++/67364
    
    	* constexpr.c (cxx_eval_component_reference): Further tweak.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 4fadc0f..d308175 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1990,13 +1990,16 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
       return t;
     }
 
-  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole)
-      && !is_really_empty_class (TREE_TYPE (t)))
+  /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
+     classes never get represented; throw together a value now.  */
+  if (is_really_empty_class (TREE_TYPE (t)))
+    return build_constructor (TREE_TYPE (t), NULL);
+
+  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole))
     {
       /* 'whole' is part of the aggregate initializer we're currently
 	 building; if there's no initializer for this member yet, that's an
-	 error.  But expand_aggr_init_1 doesn't bother to initialize really
-	 empty classes, so ignore them here, too.  */
+	 error.  */
       if (!ctx->quiet)
 	error ("accessing uninitialized member %qD", part);
       *non_constant_p = true;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-empty2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-empty2.C
new file mode 100644
index 0000000..2acfa98
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-empty2.C
@@ -0,0 +1,27 @@
+// { dg-do compile { target c++14 } }
+
+struct A
+{
+  constexpr A(int) { }
+};
+
+struct B: A {
+  constexpr B(int i): A(i) { }
+  constexpr B(const B& b): A(b) { }
+};
+
+struct C {
+  B b;
+  constexpr C(int i): b(i) { }
+  constexpr C(const C&c): b(c.b) {}
+};
+
+constexpr int f()
+{
+  C b1{42};
+  C b2{b1};
+  b2.b;
+  return 42;
+}
+
+constexpr int i = f();

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-03-04 22:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-25 14:08 C++ PATCH for c++/67364 (constexpr vs. empty class) Jason Merrill
2016-03-03 22:37 ` Jason Merrill
2016-03-04 22:05   ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).