* [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398)
@ 2018-09-25 7:30 Jakub Jelinek
2018-09-25 14:32 ` Marek Polacek
2018-09-25 14:57 ` Jason Merrill
0 siblings, 2 replies; 7+ messages in thread
From: Jakub Jelinek @ 2018-09-25 7:30 UTC (permalink / raw)
To: Jason Merrill, Marek Polacek; +Cc: gcc-patches
Hi!
ARRAY_REF is a handled component, so when a virtual call is on an array
element (or some component thereof), the loop to look through handled
components will look through the ARRAY_REFs too and then TREE_TYPE (obj)
might be an ARRAY_TYPE. The code wants to look at the class type instead
though.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2018-09-25 Jakub Jelinek <jakub@redhat.com>
PR c++/87398
* constexpr.c (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Use
strip_array_types before checking TYPE_BINFO.
* g++.dg/other/pr87398.C: New test.
* g++.dg/cpp2a/constexpr-virtual10.C: New test.
--- gcc/cp/constexpr.c.jj 2018-09-24 10:36:53.687031261 +0200
+++ gcc/cp/constexpr.c 2018-09-24 11:01:34.035268597 +0200
@@ -4814,7 +4814,7 @@ cxx_eval_constant_expression (const cons
obj = TREE_OPERAND (obj, 0);
while (handled_component_p (obj))
obj = TREE_OPERAND (obj, 0);
- tree objtype = TREE_TYPE (obj);
+ tree objtype = strip_array_types (TREE_TYPE (obj));
/* Find the function decl in the virtual functions list. TOKEN is
the DECL_VINDEX that says which function we're looking for. */
tree virtuals = BINFO_VIRTUALS (TYPE_BINFO (objtype));
--- gcc/testsuite/g++.dg/other/pr87398.C.jj 2018-09-24 10:53:41.605170048 +0200
+++ gcc/testsuite/g++.dg/other/pr87398.C 2018-09-24 10:53:14.642621001 +0200
@@ -0,0 +1,12 @@
+// PR c++/87398
+// { dg-do compile }
+
+struct A { virtual int foo (); };
+
+int
+bar (int x)
+{
+ A e[5][2];
+ int f = e[4][x].foo ();
+ return f;
+}
--- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C.jj 2018-09-24 10:56:15.604594387 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C 2018-09-24 10:56:54.882937453 +0200
@@ -0,0 +1,18 @@
+// P1064R0
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+struct X
+{
+ constexpr virtual int f() const { return 1; };
+};
+
+struct Y : public X
+{
+ constexpr virtual int f() const { return 2; };
+};
+
+constexpr X a[2][1][3];
+constexpr Y b[3][12];
+static_assert (a[1][0][1].f() == 1);
+static_assert (b[2][11].f() == 2);
Jakub
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398)
2018-09-25 7:30 [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398) Jakub Jelinek
@ 2018-09-25 14:32 ` Marek Polacek
2018-09-25 14:57 ` Jason Merrill
1 sibling, 0 replies; 7+ messages in thread
From: Marek Polacek @ 2018-09-25 14:32 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches
On Tue, Sep 25, 2018 at 09:17:54AM +0200, Jakub Jelinek wrote:
> Hi!
>
> ARRAY_REF is a handled component, so when a virtual call is on an array
> element (or some component thereof), the loop to look through handled
> components will look through the ARRAY_REFs too and then TREE_TYPE (obj)
> might be an ARRAY_TYPE. The code wants to look at the class type instead
> though.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-09-25 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/87398
> * constexpr.c (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Use
> strip_array_types before checking TYPE_BINFO.
>
> * g++.dg/other/pr87398.C: New test.
> * g++.dg/cpp2a/constexpr-virtual10.C: New test.
Can't approve but this looks fine to me, thanks!
Marek
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398)
2018-09-25 7:30 [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398) Jakub Jelinek
2018-09-25 14:32 ` Marek Polacek
@ 2018-09-25 14:57 ` Jason Merrill
2018-09-25 14:58 ` Jakub Jelinek
1 sibling, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2018-09-25 14:57 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Marek Polacek, gcc-patches List
On Tue, Sep 25, 2018 at 3:17 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> ARRAY_REF is a handled component, so when a virtual call is on an array
> element (or some component thereof), the loop to look through handled
> components will look through the ARRAY_REFs too and then TREE_TYPE (obj)
> might be an ARRAY_TYPE. The code wants to look at the class type instead
> though.
Yeah, I think looping through handled components is wrong here; given
something like
struct A
{
virtual void f();
};
struct B
{
A a;
} b;
int main()
{
b.a.f();
}
Looking through all handled components would give us "b", which has no
virtual functions.
I think we need to be more specific about what we're expecting here.
Jason
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398)
2018-09-25 14:57 ` Jason Merrill
@ 2018-09-25 14:58 ` Jakub Jelinek
2018-09-25 15:15 ` Jason Merrill
0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2018-09-25 14:58 UTC (permalink / raw)
To: Jason Merrill; +Cc: Marek Polacek, gcc-patches List
On Tue, Sep 25, 2018 at 10:42:08AM -0400, Jason Merrill wrote:
> On Tue, Sep 25, 2018 at 3:17 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> > ARRAY_REF is a handled component, so when a virtual call is on an array
> > element (or some component thereof), the loop to look through handled
> > components will look through the ARRAY_REFs too and then TREE_TYPE (obj)
> > might be an ARRAY_TYPE. The code wants to look at the class type instead
> > though.
>
> Yeah, I think looping through handled components is wrong here; given
> something like
>
> struct A
> {
> virtual void f();
> };
>
> struct B
> {
> A a;
> } b;
>
> int main()
> {
> b.a.f();
> }
>
> Looking through all handled components would give us "b", which has no
> virtual functions.
You're right. So like this (only look through COMPONENT_REFs where the
FIELD_DECL is DECL_FIELD_IS_BASE)?
Only checked
make check-c++-all RUNTESTFLAGS="dg.exp='constexpr-virt* pr87398*'"
so far, but it also fixes the PR87425 testcase and doesn't regress anything.
2018-09-25 Jakub Jelinek <jakub@redhat.com>
PR c++/87398
* constexpr.c (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Only
look through COMPONENT_REFs with DECL_FIELD_IS_BASE FIELD_DECLs.
* g++.dg/other/pr87398.C: New test.
* g++.dg/cpp2a/constexpr-virtual10.C: New test.
--- gcc/cp/constexpr.c.jj 2018-09-25 15:14:36.335386401 +0200
+++ gcc/cp/constexpr.c 2018-09-25 16:50:38.085334475 +0200
@@ -4812,7 +4812,8 @@ cxx_eval_constant_expression (const cons
return t;
}
obj = TREE_OPERAND (obj, 0);
- while (handled_component_p (obj))
+ while (TREE_CODE (obj) == COMPONENT_REF
+ && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)))
obj = TREE_OPERAND (obj, 0);
tree objtype = TREE_TYPE (obj);
/* Find the function decl in the virtual functions list. TOKEN is
--- gcc/testsuite/g++.dg/other/pr87398.C.jj 2018-09-25 16:49:40.458304980 +0200
+++ gcc/testsuite/g++.dg/other/pr87398.C 2018-09-25 16:49:40.458304980 +0200
@@ -0,0 +1,12 @@
+// PR c++/87398
+// { dg-do compile }
+
+struct A { virtual int foo (); };
+
+int
+bar (int x)
+{
+ A e[5][2];
+ int f = e[4][x].foo ();
+ return f;
+}
--- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C.jj 2018-09-25 16:49:40.458304980 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C 2018-09-25 16:49:40.458304980 +0200
@@ -0,0 +1,18 @@
+// P1064R0
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+struct X
+{
+ constexpr virtual int f() const { return 1; };
+};
+
+struct Y : public X
+{
+ constexpr virtual int f() const { return 2; };
+};
+
+constexpr X a[2][1][3];
+constexpr Y b[3][12];
+static_assert (a[1][0][1].f() == 1);
+static_assert (b[2][11].f() == 2);
Jakub
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398)
2018-09-25 14:58 ` Jakub Jelinek
@ 2018-09-25 15:15 ` Jason Merrill
2018-09-25 15:26 ` Jakub Jelinek
0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2018-09-25 15:15 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Marek Polacek, gcc-patches List
On Tue, Sep 25, 2018 at 10:57 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Sep 25, 2018 at 10:42:08AM -0400, Jason Merrill wrote:
>> On Tue, Sep 25, 2018 at 3:17 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> > ARRAY_REF is a handled component, so when a virtual call is on an array
>> > element (or some component thereof), the loop to look through handled
>> > components will look through the ARRAY_REFs too and then TREE_TYPE (obj)
>> > might be an ARRAY_TYPE. The code wants to look at the class type instead
>> > though.
>>
>> Yeah, I think looping through handled components is wrong here; given
>> something like
>>
>> struct A
>> {
>> virtual void f();
>> };
>>
>> struct B
>> {
>> A a;
>> } b;
>>
>> int main()
>> {
>> b.a.f();
>> }
>>
>> Looking through all handled components would give us "b", which has no
>> virtual functions.
>
> You're right. So like this (only look through COMPONENT_REFs where the
> FIELD_DECL is DECL_FIELD_IS_BASE)?
> Only checked
> make check-c++-all RUNTESTFLAGS="dg.exp='constexpr-virt* pr87398*'"
> so far, but it also fixes the PR87425 testcase and doesn't regress anything.
Looks good.
Jason
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398)
2018-09-25 15:15 ` Jason Merrill
@ 2018-09-25 15:26 ` Jakub Jelinek
2018-09-25 15:47 ` Jason Merrill
0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2018-09-25 15:26 UTC (permalink / raw)
To: Jason Merrill; +Cc: Marek Polacek, gcc-patches List
On Tue, Sep 25, 2018 at 11:07:19AM -0400, Jason Merrill wrote:
> > You're right. So like this (only look through COMPONENT_REFs where the
> > FIELD_DECL is DECL_FIELD_IS_BASE)?
> > Only checked
> > make check-c++-all RUNTESTFLAGS="dg.exp='constexpr-virt* pr87398*'"
> > so far, but it also fixes the PR87425 testcase and doesn't regress anything.
>
> Looks good.
Thanks, will bootstrap/regtest it now. I also took your testcase and turned it into
something that ICEd without this patch too, is that testcase also ok
(constexpr-virtual11.C)?
2018-09-25 Jakub Jelinek <jakub@redhat.com>
PR c++/87398
* constexpr.c (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Only
look through COMPONENT_REFs with DECL_FIELD_IS_BASE FIELD_DECLs.
* g++.dg/other/pr87398.C: New test.
* g++.dg/cpp2a/constexpr-virtual10.C: New test.
* g++.dg/cpp2a/constexpr-virtual11.C: New test.
--- gcc/cp/constexpr.c.jj 2018-09-25 15:14:36.335386401 +0200
+++ gcc/cp/constexpr.c 2018-09-25 16:50:38.085334475 +0200
@@ -4812,7 +4812,8 @@ cxx_eval_constant_expression (const cons
return t;
}
obj = TREE_OPERAND (obj, 0);
- while (handled_component_p (obj))
+ while (TREE_CODE (obj) == COMPONENT_REF
+ && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)))
obj = TREE_OPERAND (obj, 0);
tree objtype = TREE_TYPE (obj);
/* Find the function decl in the virtual functions list. TOKEN is
--- gcc/testsuite/g++.dg/other/pr87398.C.jj 2018-09-25 16:49:40.458304980 +0200
+++ gcc/testsuite/g++.dg/other/pr87398.C 2018-09-25 16:49:40.458304980 +0200
@@ -0,0 +1,12 @@
+// PR c++/87398
+// { dg-do compile }
+
+struct A { virtual int foo (); };
+
+int
+bar (int x)
+{
+ A e[5][2];
+ int f = e[4][x].foo ();
+ return f;
+}
--- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C.jj 2018-09-25 16:49:40.458304980 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C 2018-09-25 16:49:40.458304980 +0200
@@ -0,0 +1,18 @@
+// P1064R0
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+struct X
+{
+ constexpr virtual int f() const { return 1; };
+};
+
+struct Y : public X
+{
+ constexpr virtual int f() const { return 2; };
+};
+
+constexpr X a[2][1][3];
+constexpr Y b[3][12];
+static_assert (a[1][0][1].f() == 1);
+static_assert (b[2][11].f() == 2);
--- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C.jj 2018-09-01 11:09:41.506153390 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C 2018-09-25 17:11:30.563244029 +0200
@@ -0,0 +1,26 @@
+// P1064R0
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+struct A
+{
+ constexpr virtual int f () const { return 1; }
+};
+
+struct B : public A
+{
+ constexpr virtual int f () const { return 2; }
+};
+
+struct C
+{
+ A a;
+ B b;
+};
+
+constexpr C c;
+constexpr const A &d = c.a;
+constexpr const A &e = c.b;
+constexpr const B &f = c.b;
+static_assert (c.a.f () == 1 && c.b.f () == 2);
+static_assert (d.f () == 1 && e.f () == 2 && f.f () == 2);
Jakub
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398)
2018-09-25 15:26 ` Jakub Jelinek
@ 2018-09-25 15:47 ` Jason Merrill
0 siblings, 0 replies; 7+ messages in thread
From: Jason Merrill @ 2018-09-25 15:47 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Marek Polacek, gcc-patches List
Yes, thanks.
On Tue, Sep 25, 2018 at 11:14 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Sep 25, 2018 at 11:07:19AM -0400, Jason Merrill wrote:
>> > You're right. So like this (only look through COMPONENT_REFs where the
>> > FIELD_DECL is DECL_FIELD_IS_BASE)?
>> > Only checked
>> > make check-c++-all RUNTESTFLAGS="dg.exp='constexpr-virt* pr87398*'"
>> > so far, but it also fixes the PR87425 testcase and doesn't regress anything.
>>
>> Looks good.
>
> Thanks, will bootstrap/regtest it now. I also took your testcase and turned it into
> something that ICEd without this patch too, is that testcase also ok
> (constexpr-virtual11.C)?
>
> 2018-09-25 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/87398
> * constexpr.c (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Only
> look through COMPONENT_REFs with DECL_FIELD_IS_BASE FIELD_DECLs.
>
> * g++.dg/other/pr87398.C: New test.
> * g++.dg/cpp2a/constexpr-virtual10.C: New test.
> * g++.dg/cpp2a/constexpr-virtual11.C: New test.
>
> --- gcc/cp/constexpr.c.jj 2018-09-25 15:14:36.335386401 +0200
> +++ gcc/cp/constexpr.c 2018-09-25 16:50:38.085334475 +0200
> @@ -4812,7 +4812,8 @@ cxx_eval_constant_expression (const cons
> return t;
> }
> obj = TREE_OPERAND (obj, 0);
> - while (handled_component_p (obj))
> + while (TREE_CODE (obj) == COMPONENT_REF
> + && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)))
> obj = TREE_OPERAND (obj, 0);
> tree objtype = TREE_TYPE (obj);
> /* Find the function decl in the virtual functions list. TOKEN is
> --- gcc/testsuite/g++.dg/other/pr87398.C.jj 2018-09-25 16:49:40.458304980 +0200
> +++ gcc/testsuite/g++.dg/other/pr87398.C 2018-09-25 16:49:40.458304980 +0200
> @@ -0,0 +1,12 @@
> +// PR c++/87398
> +// { dg-do compile }
> +
> +struct A { virtual int foo (); };
> +
> +int
> +bar (int x)
> +{
> + A e[5][2];
> + int f = e[4][x].foo ();
> + return f;
> +}
> --- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C.jj 2018-09-25 16:49:40.458304980 +0200
> +++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C 2018-09-25 16:49:40.458304980 +0200
> @@ -0,0 +1,18 @@
> +// P1064R0
> +// { dg-do compile }
> +// { dg-options "-std=c++2a" }
> +
> +struct X
> +{
> + constexpr virtual int f() const { return 1; };
> +};
> +
> +struct Y : public X
> +{
> + constexpr virtual int f() const { return 2; };
> +};
> +
> +constexpr X a[2][1][3];
> +constexpr Y b[3][12];
> +static_assert (a[1][0][1].f() == 1);
> +static_assert (b[2][11].f() == 2);
> --- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C.jj 2018-09-01 11:09:41.506153390 +0200
> +++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C 2018-09-25 17:11:30.563244029 +0200
> @@ -0,0 +1,26 @@
> +// P1064R0
> +// { dg-do compile }
> +// { dg-options "-std=c++2a" }
> +
> +struct A
> +{
> + constexpr virtual int f () const { return 1; }
> +};
> +
> +struct B : public A
> +{
> + constexpr virtual int f () const { return 2; }
> +};
> +
> +struct C
> +{
> + A a;
> + B b;
> +};
> +
> +constexpr C c;
> +constexpr const A &d = c.a;
> +constexpr const A &e = c.b;
> +constexpr const B &f = c.b;
> +static_assert (c.a.f () == 1 && c.b.f () == 2);
> +static_assert (d.f () == 1 && e.f () == 2 && f.f () == 2);
>
>
> Jakub
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-09-25 15:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-25 7:30 [C++ PATCH] Fix constexpr OBJ_TYPE_REF handling on array elts (PR c++/87398) Jakub Jelinek
2018-09-25 14:32 ` Marek Polacek
2018-09-25 14:57 ` Jason Merrill
2018-09-25 14:58 ` Jakub Jelinek
2018-09-25 15:15 ` Jason Merrill
2018-09-25 15:26 ` Jakub Jelinek
2018-09-25 15:47 ` 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).