aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-12-05 16:03:21 +0100
committerRichard Biener <rguenther@suse.de>2022-12-05 16:50:49 +0100
commit0d14720f93a8139a7f234b2762c361e8e5da99cc (patch)
tree63623322b3af2ad46092c9fe0c5397cae23d751e
parentd492d50f644811327c5976e2c918ab6d906ed40c (diff)
downloadgcc-0d14720f93a8139a7f234b2762c361e8e5da99cc.zip
gcc-0d14720f93a8139a7f234b2762c361e8e5da99cc.tar.gz
gcc-0d14720f93a8139a7f234b2762c361e8e5da99cc.tar.bz2
middle-end/40635 - SSA update losing PHI arg loations
The following fixes an issue where SSA update loses PHI argument locations when updating PHI nodes it didn't create as part of the SSA update. For the case where the reaching def is the same as the current argument opt to do nothing and for the case where the PHI argument already has a location keep that (that's an indication the PHI node wasn't created as part of the update SSA process). PR middle-end/40635 * tree-into-ssa.cc (rewrite_update_phi_arguments): Only update the argument when the reaching definition is different from the current argument. Keep an existing argument location. * gcc.dg/uninit-pr40635.c: New testcase.
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pr40635.c33
-rw-r--r--gcc/tree-into-ssa.cc11
2 files changed, 40 insertions, 4 deletions
diff --git a/gcc/testsuite/gcc.dg/uninit-pr40635.c b/gcc/testsuite/gcc.dg/uninit-pr40635.c
new file mode 100644
index 0000000..fab7c3d4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-pr40635.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized" } */
+
+struct hostent {
+ char **h_addr_list;
+};
+struct hostent *gethostbyname(const char*);
+int socket(void);
+int close(int);
+int connect(int, const char*);
+
+int get_tcp_socket(const char *machine)
+{
+ struct hostent *hp;
+ int s42, x;
+ char **addr;
+
+ hp = gethostbyname(machine);
+ x = 0;
+ for (addr = hp->h_addr_list; *addr; addr++)
+ {
+ s42 = socket();
+ if (s42 < 0)
+ return -1;
+ x = connect(s42, *addr);
+ if (x == 0)
+ break;
+ close(s42);
+ }
+ if (x < 0)
+ return -1;
+ return s42; /* { dg-warning "uninitialized" } */
+}
diff --git a/gcc/tree-into-ssa.cc b/gcc/tree-into-ssa.cc
index f21ed2b..9a2417d 100644
--- a/gcc/tree-into-ssa.cc
+++ b/gcc/tree-into-ssa.cc
@@ -2110,7 +2110,6 @@ rewrite_update_phi_arguments (basic_block bb)
symbol we may find NULL arguments. That's why we
take the symbol from the LHS of the PHI node. */
reaching_def = get_reaching_def (lhs_sym);
-
}
else
{
@@ -2122,8 +2121,9 @@ rewrite_update_phi_arguments (basic_block bb)
reaching_def = get_reaching_def (arg);
}
- /* Update the argument if there is a reaching def. */
- if (reaching_def)
+ /* Update the argument if there is a reaching def different
+ from arg. */
+ if (reaching_def && reaching_def != arg)
{
location_t locus;
int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p);
@@ -2133,6 +2133,10 @@ rewrite_update_phi_arguments (basic_block bb)
/* Virtual operands do not need a location. */
if (virtual_operand_p (reaching_def))
locus = UNKNOWN_LOCATION;
+ /* If SSA update didn't insert this PHI the argument
+ might have a location already, keep that. */
+ else if (gimple_phi_arg_has_location (phi, arg_i))
+ locus = gimple_phi_arg_location (phi, arg_i);
else
{
gimple *stmt = SSA_NAME_DEF_STMT (reaching_def);
@@ -2150,7 +2154,6 @@ rewrite_update_phi_arguments (basic_block bb)
gimple_phi_arg_set_location (phi, arg_i, locus);
}
-
if (e->flags & EDGE_ABNORMAL)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1;
}