Avoid -Wdangling-pointer for by-transparent-reference arguments [PR104436].

This change avoids -Wdangling-pointer for by-value arguments transformed
into by-transparent-reference.

Resolves:
PR middle-end/104436 - spurious -Wdangling-pointer assigning local address to a class passed by value

gcc/ChangeLog:

	PR middle-end/104436
	* gimple-ssa-warn-access.cc (pass_waccess::check_dangling_stores):
	Check for warning suppression.  Avoid by-value arguments transformed
	into by-transparent-reference.

gcc/testsuite/ChangeLog:

	PR middle-end/104436
	* c-c++-common/Wdangling-pointer-8.c: New test.
	* g++.dg/warn/Wdangling-pointer-5.C: New test.
This commit is contained in:
Martin Sebor 2022-03-14 18:23:08 -06:00
parent 510613e76c
commit 373a2dc2be
3 changed files with 66 additions and 1 deletions

View File

@ -4511,6 +4511,9 @@ pass_waccess::check_dangling_stores (basic_block bb,
if (!stmt)
break;
if (warning_suppressed_p (stmt, OPT_Wdangling_pointer_))
continue;
if (is_gimple_call (stmt)
&& !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
/* Avoid looking before nonconst, nonpure calls since those might
@ -4536,10 +4539,16 @@ pass_waccess::check_dangling_stores (basic_block bb,
}
else if (TREE_CODE (lhs_ref.ref) == SSA_NAME)
{
/* Avoid looking at or before stores into unknown objects. */
gimple *def_stmt = SSA_NAME_DEF_STMT (lhs_ref.ref);
if (!gimple_nop_p (def_stmt))
/* Avoid looking at or before stores into unknown objects. */
return;
tree var = SSA_NAME_VAR (lhs_ref.ref);
if (TREE_CODE (var) == PARM_DECL && DECL_BY_REFERENCE (var))
/* Avoid by-value arguments transformed into by-reference. */
continue;
}
else if (TREE_CODE (lhs_ref.ref) == MEM_REF)
{
@ -4572,6 +4581,8 @@ pass_waccess::check_dangling_stores (basic_block bb,
"storing the address of local variable %qD in %qE",
rhs_ref.ref, lhs))
{
suppress_warning (stmt, OPT_Wdangling_pointer_);
location_t loc = DECL_SOURCE_LOCATION (rhs_ref.ref);
inform (loc, "%qD declared here", rhs_ref.ref);

View File

@ -0,0 +1,20 @@
/* Verify -Wdangling-pointer is issued only once.
{ dg-do compile }
{ dg-options "-O -Wall" } */
void *p;
void escape_global_warn_once (void)
{
int x[5];
p = &x[3]; // { dg-regexp "\[^\n\r\]+: warning: \[^\n\r\]+ \\\[-Wdangling-pointer.?\\\]" "message" }
}
void escape_param_warn_once (void **p)
{
int x[5];
*p = &x[3]; // { dg-regexp "\[^\n\r\]+: warning: \[^\n\r\]+ \\\[-Wdangling-pointer.?\\\]" "message" }
}

View File

@ -0,0 +1,34 @@
/* PR middle-end/104436 - spurious -Wdangling-pointer assigning local
address to a class passed by value
{ dg-do compile }
{ dg-options "-O1 -Wall" } */
struct S
{
S (void *p): p (p) { }
S (const S &s): p (s.p) { }
void *p;
};
void nowarn_assign_by_value (S s)
{
int i;
S t (&i);
s = t; // { dg-bogus "-Wdangling-pointer" }
}
void nowarn_assign_by_value_arg (S s)
{
S t (&s);
s = t; // { dg-bogus "-Wdangling-pointer" }
}
void warn_assign_local_by_reference (S &s)
{
int i;
S t (&i);
s = t; // { dg-warning "-Wdangling-pointer" }
}