Commit 24d21a0b by Alexandre Oliva Committed by Alexandre Oliva

[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.

From-SVN: r259067
parent 30feb954
2018-04-04 Alexandre Oliva <aoliva@redhat.com>
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.
2018-04-03 Jason Merrill <jason@redhat.com>
PR c++/85092 - C++17 ICE with unused list constructor.
......
......@@ -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 true;
/* 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
......
......@@ -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);
......
2018-04-04 Alexandre Oliva <aoliva@redhat.com>
PR c++/84943
* g++.dg/pr84943.C: New.
* g++.dg/pr84943-2.C: New.
2018-04-03 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/85167
......
// { 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();
}
}
// { dg-do compile }
// Avoid -pedantic-error default
// { dg-options "" }
void a() {
a[0](); // { dg-warning "arithmetic" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment