This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] [PR c++/84943] allow folding of array indexing indirect_ref
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches List <gcc-patches at gcc dot gnu dot org>, Nathan Sidwell <nathan at acm dot org>
- Date: Tue, 03 Apr 2018 04:44:08 -0300
- Subject: Re: [PATCH] [PR c++/84943] allow folding of array indexing indirect_ref
- References: <ork1u3k95q.fsf@lxoliva.fsfla.org> <CADzB+2k6sJiQcZ+u5iAAdh=SAPy5ie4rZnjg6vFmakPYORmz4Q@mail.gmail.com> <orwoy2py0o.fsf@lxoliva.fsfla.org> <CADzB+2nnSeH1Oe37kG9iWVMrgBGwgxNDKE0SWP9oFqJYvDXR_Q@mail.gmail.com> <CADzB+2kPvPute770350hRx8qACVyvE7ni+-aFLPuxBWEZShuaw@mail.gmail.com> <CADzB+2koRicaeyWMKYu9wpNbFwGHK9qTz2hrTfRbi75r9OeYkQ@mail.gmail.com> <ora7usiuyp.fsf@lxoliva.fsfla.org> <CADzB+2=HUuzBLdg=txnvGBpCEdcQ5-g=cSOJTpU6Kkp+keEnNA@mail.gmail.com> <ortvsyxxq6.fsf@lxoliva.fsfla.org> <orpo3mwcv3.fsf@lxoliva.fsfla.org> <ora7uq6m2d.fsf@lxoliva.fsfla.org> <CADzB+2=75YwaJHL0YF=F4iPwLjh=t3mG24JMG0pdQF5o3TrFfg@mail.gmail.com> <ord0zkzrs1.fsf@lxoliva.fsfla.org> <CADzB+2kL+sKadsXKJvA5CJnTSXK4wpFknWJ1tUFVkq1Y9G+dXg@mail.gmail.com>
On Apr 2, 2018, Jason Merrill <jason@redhat.com> wrote:
> On Sat, Mar 31, 2018 at 2:24 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
>> On Mar 30, 2018, Jason Merrill <jason@redhat.com> wrote:
>>
>>> I don't think we need this; if arg is overloaded, we take the
>>> type_unknown_p early exit, so the code lower down is always dealing
>>> with a single function.
>>
>> Aah, that's why it seemed to me that we had already resolved overloads
>> when we got there.
>>
>> As a bonus, I added the tf_conv test before another mark_used call I'd
>> missed in the previous patch.
> What if we check tf_conv in mark_used itself rather than at all the call sites?
There are other uses of mark_used, but presumably we want them all to
be more conservative under tf_conv, so... Here's what I'm testing. Ok
if it passes?
[PR c++/84943] mark function as used when taking its address
fn[0]() ICEd because we would fold the INDIRECT_REF used for the
array indexing while building the address for the call, after not
finding the decl hiding there at first. But the decl would be exposed
by the folding, and then lower layers would complain we had the decl,
after all, but it wasn't one of the artificial or special functions
that could be called without being marked as used.
This patch arranges for a FUNCTION_DECL to be marked as used when
taking its address, just like we already did when taking the address
of a static function to call it as a member function (i.e. using the
obj.fn() notation). However, we shouldn't mark functions as used when
just performing overload resolution, lest we might instantiate
templates we shouldn't, as in g++.dg/overload/template1.C, so we
adjust mark_used to return early when testing conversions.
for gcc/cp/ChangeLog
PR c++/84943
* typeck.c (cp_build_addr_expr_1): Mark FUNCTION_DECL as
used.
* decl2.c (mark_used): Return without effects if tf_conv.
for gcc/testsuite/ChangeLog
PR c++/84943
* g++.dg/pr84943.C: New.
* g++.dg/pr84943-2.C: New.
---
gcc/cp/decl2.c | 6 ++++
gcc/cp/typeck.c | 3 ++
gcc/testsuite/g++.dg/pr84943-2.C | 64 ++++++++++++++++++++++++++++++++++++++
gcc/testsuite/g++.dg/pr84943.C | 8 +++++
4 files changed, 81 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/pr84943-2.C
create mode 100644 gcc/testsuite/g++.dg/pr84943.C
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index fa753749e1a6..740e85b35617 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5201,6 +5201,12 @@ maybe_instantiate_decl (tree decl)
bool
mark_used (tree decl, tsubst_flags_t complain)
{
+ /* If we're just testing conversions or resolving overloads, we
+ don't want any permanent effects like forcing functions to be
+ output or instantiating templates. */
+ if ((complain & tf_conv))
+ return false;
+
/* If DECL is a BASELINK for a single function, then treat it just
like the DECL for the function. Otherwise, if the BASELINK is
for an overloaded function, we don't know which function was
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index d454c6c5a295..bd67b82fcc65 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5971,6 +5971,9 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
so we can just form an ADDR_EXPR with the correct type. */
if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
{
+ if (TREE_CODE (arg) == FUNCTION_DECL
+ && !mark_used (arg, complain) && !(complain & tf_error))
+ return error_mark_node;
val = build_address (arg);
if (TREE_CODE (arg) == OFFSET_REF)
PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
diff --git a/gcc/testsuite/g++.dg/pr84943-2.C b/gcc/testsuite/g++.dg/pr84943-2.C
new file mode 100644
index 000000000000..d1ef012b9155
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr84943-2.C
@@ -0,0 +1,64 @@
+// { dg-do run }
+
+// Avoid -pedantic-error default
+// { dg-options "" }
+
+// Make sure the functions referenced by various forms of
+// address-taking are marked as used and compiled in.
+
+static void ac() {}
+void a() {
+ ac[0](); // { dg-warning "arithmetic" }
+}
+
+static void bc() {}
+void b() {
+ (&*&*&*&bc)();
+}
+
+template <typename U> U cc() {}
+void (*c())() {
+ return cc;
+}
+
+template <typename T>
+struct x {
+ void a(int);
+ template <typename U> static U a(x*) {}
+ static void a(long) {}
+ static void a(void *) {}
+ static void a() {
+ void (*p0)(void*) = x().a;
+ p0(0);
+ void (*p1)(long) = a;
+ p1(0);
+ void (*p2)() = a;
+ p2();
+ void (*p3)(x*) = a;
+ p3(0);
+ }
+};
+
+struct z {
+ void a(int);
+ template <typename U> static U a(z*) {}
+ static void a(long) {}
+ static void a(void *) {}
+ static void a() {
+ void (*p0)(void*) = z().a;
+ p0(0);
+ void (*p1)(long) = a;
+ p1(0);
+ void (*p2)() = a;
+ p2();
+ void (*p3)(z*) = a;
+ p3(0);
+ }
+};
+
+int main(int argc, char *argv[]) {
+ if (argc > 1) {
+ x<void>().a();
+ z().a();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/pr84943.C b/gcc/testsuite/g++.dg/pr84943.C
new file mode 100644
index 000000000000..36f75a164119
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr84943.C
@@ -0,0 +1,8 @@
+// { dg-do compile }
+
+// Avoid -pedantic-error default
+// { dg-options "" }
+
+void a() {
+ a[0](); // { dg-warning "arithmetic" }
+}
--
Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/ FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer