This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] [PR c++/84943] allow folding of array indexing indirect_ref


On Mar 23, 2018, Jason Merrill <jason@redhat.com> wrote:

> On Thu, Mar 22, 2018 at 7:00 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
>> fn[0]() ICEs because we end up with addr_expr of a decl, and that
>> should only happen for artificial or otherwise special internal
>> functions.  For anything else, we should find the decl earlier, but we
>> don't because we build an indirect_ref or an addr_expr and don't
>> cancel them out.

> That's deliberate; we recently changed the C++ front end to defer most
> folding until genericization time.

How about this?  (not significantly tested yet)

[PR c++/84943] keep fndecl hidden from call

fn[0]() ICEd because we 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 that way.

In order to preserve the program structure and properties that depend
on it, we shouldn't cancel out the INDIRECT_REF with the ADDR_EXPR,
nor should we bypass them to find the decl.  So, make build_addr_func
not drop an INDIRECT_REF: when it would do so, wrap its original
INDIRECT_REF value in an ADDR_EXPR, then we won't find the decl hiding
in there unless the decl was visible to begin with.


for  gcc/cp/ChangeLog

	PR c++/84943
	* call.c (build_addr_func): If we'd drop an INDIRECT_REF, wrap
	it in a new ADDR_EXPR instead.

for  gcc/testsuite/ChangeLog

	PR c++/84943
	* g++.dg/pr84943.C: New.
---
 gcc/cp/call.c                  |   10 +++++++++-
 gcc/testsuite/g++.dg/pr84943.C |    8 ++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/pr84943.C

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9351918b23af..5a0d09b1db4e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -283,7 +283,15 @@ build_addr_func (tree function, tsubst_flags_t complain)
       function = build_address (function);
     }
   else
-    function = decay_conversion (function, complain, /*reject_builtin=*/false);
+    {
+      tree orig = function;
+      function = decay_conversion (function, complain, /*reject_builtin=*/false);
+
+      /* Do not cancel out an INDIRECT_REF.  */
+      if (TREE_CODE (orig) == INDIRECT_REF
+	  && TREE_OPERAND (orig, 0) == function)
+	function = build1 (ADDR_EXPR, TREE_TYPE (function), orig);
+    }
 
   return function;
 }
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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]