Re: [PATCH v2] c: don't emit -Wmissing-variable-declarations for register variables [PR110947]

2023-10-30 Thread Hamza Mahfooz

ping

On Fri, Sep 1 2023 at 03:02:41 PM -04:00:00, Hamza Mahfooz 
 wrote:

Resolves:
PR c/110947 - Should -Wmissing-variable-declarations not trigger on
register variables?

gcc/c/ChangeLog:

PR c/110947
* c-decl.cc (start_decl): don't emit
-Wmissing-variable-declarations for DECL_REGISTER VAR_DECLs.

gcc/testsuite/ChangeLog:

PR c/110947
* gcc.dg/pr110947.c: New test.

Signed-off-by: Hamza Mahfooz 
---
Please push this for me if you think it looks good. Since, I don't 
have

write access to the repository.

v2: put "target" before the relevant architectures in pr110947.c.
---
 gcc/c/c-decl.cc | 3 ++-
 gcc/testsuite/gcc.dg/pr110947.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr110947.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 1f9eb44dbaa..819af6aa050 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5376,7 +5376,8 @@ start_decl (struct c_declarator *declarator, 
struct c_declspecs *declspecs,

 warning (OPT_Wmain, "%q+D is usually a function", decl);

   if (warn_missing_variable_declarations && VAR_P (decl)
-  && !DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) && old_decl == 
NULL_TREE)
+  && !DECL_EXTERNAL (decl) && !DECL_REGISTER (decl) && 
TREE_PUBLIC (decl)

+  && old_decl == NULL_TREE)
 warning_at (DECL_SOURCE_LOCATION (decl), 
OPT_Wmissing_variable_declarations,

"no previous declaration for %qD", decl);

diff --git a/gcc/testsuite/gcc.dg/pr110947.c 
b/gcc/testsuite/gcc.dg/pr110947.c

new file mode 100644
index 000..3c0b8a82ab3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110947.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-Wmissing-variable-declarations" } */
+
+register unsigned long current_stack_pointer asm("rsp");
--
2.41.0






[PATCH v2 2/2] strlen: call handle_builtin_strlen() from fold_strstr_to_strncmp()

2023-09-04 Thread Hamza Mahfooz
Currently, we are not saving the strlen() call we inserted for possible
future common subexpression elimination. Also, it's possible that we can
further fold that strlen() call. So, refactor handle_builtin_strlen()
so that it can be called from fold_strstr_to_strncmp().

gcc/ChangeLog:

* tree-ssa-strlen.cc (strlen_pass::handle_builtin_strlen):
Remove from class and mark as static.
(handle_builtin_strlen): Add parameter
"gimple_stmt_iterator gsi" and replace references of m_gsi
with gsi.
(fold_strstr_to_strncmp): Call handle_builtin_strlen().
(strlen_pass::check_and_optimize_call): Add m_gsi to the
handle_builtin_strlen() call.

gcc/testsuite/ChangeLog:

* gcc.dg/strlenopt-30.c: Add a test.

Signed-off-by: Hamza Mahfooz 
---
v2: bump up the number of strncmp()s from 6 to 7 in strlenopt-30.c
---
 gcc/testsuite/gcc.dg/strlenopt-30.c |  9 -
 gcc/tree-ssa-strlen.cc  | 23 ---
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c 
b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 1ee814048c1..d89fe83ca98 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -44,6 +44,12 @@ _Bool f6(char *s, char *t)
   return __builtin_strstr (s, t) == s;
 }
 
+__attribute__((no_icf))
+_Bool f6plus(char *s, char *t)
+{
+  return __builtin_strstr (s, t) == s && __builtin_strlen(t) > 10;
+}
+
 /* Do not perform transform in this case, since
t1 doesn't have single use.  */
 
@@ -57,4 +63,5 @@ _Bool f7(char *s)
   return (t1 == s);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 6 "strlen1" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_strlen" 2 "strlen1" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 7 "strlen1" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index b0ebbb0db62..8ec6ddbc7c0 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -252,7 +252,6 @@ public:
   bool handle_assign (tree lhs, bool *zero_write);
   bool handle_store (bool *zero_write);
   void handle_pointer_plus ();
-  void handle_builtin_strlen ();
   void handle_builtin_strchr ();
   void handle_builtin_strcpy (built_in_function);
   void handle_integral_assign (bool *cleanup_eh);
@@ -2211,10 +2210,10 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool 
call_lhs,
the strlen call with the known value, otherwise remember that strlen
of the argument is stored in the lhs SSA_NAME.  */
 
-void
-strlen_pass::handle_builtin_strlen ()
+static void
+handle_builtin_strlen (gimple_stmt_iterator gsi)
 {
-  gimple *stmt = gsi_stmt (m_gsi);
+  gimple *stmt = gsi_stmt (gsi);
   tree lhs = gimple_call_lhs (stmt);
 
   if (lhs == NULL_TREE)
@@ -2268,8 +2267,8 @@ strlen_pass::handle_builtin_strlen ()
  if (bound)
rhs = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (rhs), rhs, bound);
 
- gimplify_and_update_call_from_tree (_gsi, rhs);
- stmt = gsi_stmt (m_gsi);
+ gimplify_and_update_call_from_tree (, rhs);
+ stmt = gsi_stmt (gsi);
  update_stmt (stmt);
  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
{
@@ -2367,8 +2366,8 @@ strlen_pass::handle_builtin_strlen ()
  }
if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (ret)))
  ret = fold_convert_loc (loc, TREE_TYPE (lhs), ret);
-   gimplify_and_update_call_from_tree (_gsi, ret);
-   stmt = gsi_stmt (m_gsi);
+   gimplify_and_update_call_from_tree (, ret);
+   stmt = gsi_stmt (gsi);
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS) != 0)
  {
@@ -5272,8 +5271,9 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
{
  tree arg1 = gimple_call_arg (call_stmt, 1);
  tree arg1_len = NULL_TREE;
- int idx = get_stridx (arg1, call_stmt);
  gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
+again:
+ int idx = get_stridx (arg1, call_stmt);
 
  if (idx)
{
@@ -5296,7 +5296,8 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
  gimple_call_set_lhs (strlen_call, strlen_lhs);
  gimple_set_vuse (strlen_call, gimple_vuse (call_stmt));
  gsi_insert_before (, strlen_call, GSI_SAME_STMT);
- arg1_len = strlen_lhs;
+ handle_builtin_strlen (gsi_for_stmt (strlen_call));
+ goto again;
}
  else if (!is_gimple_val (arg1_len))
{
@@ -5393,7 +5394,7 @@ strlen_pass::check_and_optimize_call (bool *zero_write)
 {
 case BUILT_IN_STRLEN:
 case BUILT_IN_STRNLEN:
-  handle_builtin_strlen ();
+  handle_builtin_strlen (m_gsi);
   break;
 case BUILT_IN_STRCHR:
   handle_builtin_strchr ();
-- 
2.42.0



[PATCH v2 1/2] strlen: fold strstr() even if the length isn't previously known [PR96601]

2023-09-04 Thread Hamza Mahfooz
Currently, we give up in fold_strstr_to_strncmp() if the length of the
the second argument to strstr() isn't known to us by the time we hit
that function. However, we can instead insert a strlen() in ourselves
and continue trying to fold strstr() into strlen()+strncmp().

PR tree-optimization/96601

gcc/ChangeLog:

* tree-ssa-strlen.cc (fold_strstr_to_strncmp): If arg1_len == NULL,
insert a strlen() for strstr()'s arg1 and use it as arg1_len.

gcc/testsuite/ChangeLog:

* gcc.dg/strlenopt-30.c: Modify test.

Signed-off-by: Hamza Mahfooz 
---
Please push this for me if you think it looks good. Since, I don't have
write access to the repository.
---
 gcc/testsuite/gcc.dg/strlenopt-30.c |  5 +-
 gcc/tree-ssa-strlen.cc  | 81 -
 2 files changed, 45 insertions(+), 41 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c 
b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 2a3098ba96f..1ee814048c1 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -38,9 +38,6 @@ void f5(char *s)
 foo_f5();
 }
 
-/* Do not perform transform, since strlen (t)
-   is unknown.  */
-
 __attribute__((no_icf))
 _Bool f6(char *s, char *t)
 {
@@ -60,4 +57,4 @@ _Bool f7(char *s)
   return (t1 == s);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen1" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 6 "strlen1" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 8b7ef919826..b0ebbb0db62 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -5273,6 +5273,7 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
  tree arg1 = gimple_call_arg (call_stmt, 1);
  tree arg1_len = NULL_TREE;
  int idx = get_stridx (arg1, call_stmt);
+ gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
 
  if (idx)
{
@@ -5286,51 +5287,57 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
}
}
 
- if (arg1_len != NULL_TREE)
+ if (arg1_len == NULL_TREE)
{
- gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
- tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+ tree strlen_decl = builtin_decl_explicit (BUILT_IN_STRLEN);
+ gcall *strlen_call = gimple_build_call (strlen_decl, 1, arg1);
+ tree strlen_lhs = make_ssa_name (size_type_node, strlen_call);
+
+ gimple_call_set_lhs (strlen_call, strlen_lhs);
+ gimple_set_vuse (strlen_call, gimple_vuse (call_stmt));
+ gsi_insert_before (, strlen_call, GSI_SAME_STMT);
+ arg1_len = strlen_lhs;
+   }
+ else if (!is_gimple_val (arg1_len))
+   {
+ tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
+ gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
+   arg1_len);
+ gsi_insert_before (, arg1_stmt, GSI_SAME_STMT);
+ arg1_len = arg1_len_tmp;
+   }
 
- if (!is_gimple_val (arg1_len))
+ tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+ gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
+  arg0, arg1, arg1_len);
+ tree strncmp_lhs = make_ssa_name (integer_type_node);
+ gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
+ gimple_call_set_lhs (strncmp_call, strncmp_lhs);
+ gsi_remove (, true);
+ gsi_insert_before (, strncmp_call, GSI_SAME_STMT);
+ tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
+
+ if (is_gimple_assign (stmt))
+   {
+ if (gimple_assign_rhs_code (stmt) == COND_EXPR)
{
- tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
- gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
-   arg1_len);
- gsi_insert_before (, arg1_stmt, GSI_SAME_STMT);
- arg1_len = arg1_len_tmp;
-   }
-
- gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
- arg0, arg1, arg1_len);
- tree strncmp_lhs = make_ssa_name (integer_type_node);
- gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
- gimple_call_set_lhs (strncmp_call, strncmp_lhs);
- gsi_remove (, true);
- gsi_insert_before (, strncmp_call, GSI_SAME_STMT);
- tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
-
- if (is_gimple_assign (stmt))
-   {
- if (gimple_assign_rhs_code (stmt) == COND_EXPR)
-   {
- 

[PATCH 2/2] strlen: call handle_builtin_strlen() from fold_strstr_to_strncmp()

2023-09-04 Thread Hamza Mahfooz
Currently, we are not saving the strlen() call we inserted for possible
future common subexpression elimination. Also, it's possible that we can
further fold that strlen() call. So, refactor handle_builtin_strlen()
so that it can be called from fold_strstr_to_strncmp().

gcc/ChangeLog:

* tree-ssa-strlen.cc (strlen_pass::handle_builtin_strlen):
Remove from class and mark as static.
(handle_builtin_strlen): Add parameter
"gimple_stmt_iterator gsi" and replace references of m_gsi
with gsi.
(fold_strstr_to_strncmp): Call handle_builtin_strlen().
(strlen_pass::check_and_optimize_call): Add m_gsi to the
handle_builtin_strlen() call.

gcc/testsuite/ChangeLog:

* gcc.dg/strlenopt-30.c: Add a test.

Signed-off-by: Hamza Mahfooz 
---
Please push this for me if you think it looks good. Since, I don't have
write access to the repository.
---
 gcc/testsuite/gcc.dg/strlenopt-30.c |  7 +++
 gcc/tree-ssa-strlen.cc  | 23 ---
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c 
b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 1ee814048c1..de51a66383b 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -44,6 +44,12 @@ _Bool f6(char *s, char *t)
   return __builtin_strstr (s, t) == s;
 }
 
+__attribute__((no_icf))
+_Bool f6plus(char *s, char *t)
+{
+  return __builtin_strstr (s, t) == s && __builtin_strlen(t) > 10;
+}
+
 /* Do not perform transform in this case, since
t1 doesn't have single use.  */
 
@@ -57,4 +63,5 @@ _Bool f7(char *s)
   return (t1 == s);
 }
 
+/* { dg-final { scan-tree-dump-times "__builtin_strlen" 2 "strlen1" } } */
 /* { dg-final { scan-tree-dump-times "__builtin_strncmp" 6 "strlen1" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index b0ebbb0db62..8ec6ddbc7c0 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -252,7 +252,6 @@ public:
   bool handle_assign (tree lhs, bool *zero_write);
   bool handle_store (bool *zero_write);
   void handle_pointer_plus ();
-  void handle_builtin_strlen ();
   void handle_builtin_strchr ();
   void handle_builtin_strcpy (built_in_function);
   void handle_integral_assign (bool *cleanup_eh);
@@ -2211,10 +2210,10 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool 
call_lhs,
the strlen call with the known value, otherwise remember that strlen
of the argument is stored in the lhs SSA_NAME.  */
 
-void
-strlen_pass::handle_builtin_strlen ()
+static void
+handle_builtin_strlen (gimple_stmt_iterator gsi)
 {
-  gimple *stmt = gsi_stmt (m_gsi);
+  gimple *stmt = gsi_stmt (gsi);
   tree lhs = gimple_call_lhs (stmt);
 
   if (lhs == NULL_TREE)
@@ -2268,8 +2267,8 @@ strlen_pass::handle_builtin_strlen ()
  if (bound)
rhs = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (rhs), rhs, bound);
 
- gimplify_and_update_call_from_tree (_gsi, rhs);
- stmt = gsi_stmt (m_gsi);
+ gimplify_and_update_call_from_tree (, rhs);
+ stmt = gsi_stmt (gsi);
  update_stmt (stmt);
  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
{
@@ -2367,8 +2366,8 @@ strlen_pass::handle_builtin_strlen ()
  }
if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (ret)))
  ret = fold_convert_loc (loc, TREE_TYPE (lhs), ret);
-   gimplify_and_update_call_from_tree (_gsi, ret);
-   stmt = gsi_stmt (m_gsi);
+   gimplify_and_update_call_from_tree (, ret);
+   stmt = gsi_stmt (gsi);
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS) != 0)
  {
@@ -5272,8 +5271,9 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
{
  tree arg1 = gimple_call_arg (call_stmt, 1);
  tree arg1_len = NULL_TREE;
- int idx = get_stridx (arg1, call_stmt);
  gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
+again:
+ int idx = get_stridx (arg1, call_stmt);
 
  if (idx)
{
@@ -5296,7 +5296,8 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
  gimple_call_set_lhs (strlen_call, strlen_lhs);
  gimple_set_vuse (strlen_call, gimple_vuse (call_stmt));
  gsi_insert_before (, strlen_call, GSI_SAME_STMT);
- arg1_len = strlen_lhs;
+ handle_builtin_strlen (gsi_for_stmt (strlen_call));
+ goto again;
}
  else if (!is_gimple_val (arg1_len))
{
@@ -5393,7 +5394,7 @@ strlen_pass::check_and_optimize_call (bool *zero_write)
 {
 case BUILT_IN_STRLEN:
 case BUILT_IN_STRNLEN:
-  handle_builtin_strlen ();
+  handle_builtin_strlen (m_gsi);
   break;
 case BUILT_IN_STRCHR:
   handle_builtin_strchr ();
-- 
2.42.0



[PATCH 1/2] strlen: fold strstr() even if the length isn't previously known [PR96601]

2023-09-04 Thread Hamza Mahfooz
Currently, we give up in fold_strstr_to_strncmp() if the length of the
the second argument to strstr() isn't known to us by the time we hit
that function. However, we can instead insert a strlen() in ourselves
and continue trying to fold strstr() into strlen()+strncmp().

PR tree-optimization/96601

gcc/ChangeLog:

* tree-ssa-strlen.cc (fold_strstr_to_strncmp): If arg1_len == NULL,
insert a strlen() for strstr()'s arg1 and use it as arg1_len.

gcc/testsuite/ChangeLog:

* gcc.dg/strlenopt-30.c: Modify test.

Signed-off-by: Hamza Mahfooz 
---
Please push this for me if you think it looks good. Since, I don't have
write access to the repository.
---
 gcc/testsuite/gcc.dg/strlenopt-30.c |  5 +-
 gcc/tree-ssa-strlen.cc  | 81 -
 2 files changed, 45 insertions(+), 41 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c 
b/gcc/testsuite/gcc.dg/strlenopt-30.c
index 2a3098ba96f..1ee814048c1 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-30.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -38,9 +38,6 @@ void f5(char *s)
 foo_f5();
 }
 
-/* Do not perform transform, since strlen (t)
-   is unknown.  */
-
 __attribute__((no_icf))
 _Bool f6(char *s, char *t)
 {
@@ -60,4 +57,4 @@ _Bool f7(char *s)
   return (t1 == s);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen1" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 6 "strlen1" } } */
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 8b7ef919826..b0ebbb0db62 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -5273,6 +5273,7 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
  tree arg1 = gimple_call_arg (call_stmt, 1);
  tree arg1_len = NULL_TREE;
  int idx = get_stridx (arg1, call_stmt);
+ gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
 
  if (idx)
{
@@ -5286,51 +5287,57 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple 
*stmt)
}
}
 
- if (arg1_len != NULL_TREE)
+ if (arg1_len == NULL_TREE)
{
- gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
- tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+ tree strlen_decl = builtin_decl_explicit (BUILT_IN_STRLEN);
+ gcall *strlen_call = gimple_build_call (strlen_decl, 1, arg1);
+ tree strlen_lhs = make_ssa_name (size_type_node, strlen_call);
+
+ gimple_call_set_lhs (strlen_call, strlen_lhs);
+ gimple_set_vuse (strlen_call, gimple_vuse (call_stmt));
+ gsi_insert_before (, strlen_call, GSI_SAME_STMT);
+ arg1_len = strlen_lhs;
+   }
+ else if (!is_gimple_val (arg1_len))
+   {
+ tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
+ gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
+   arg1_len);
+ gsi_insert_before (, arg1_stmt, GSI_SAME_STMT);
+ arg1_len = arg1_len_tmp;
+   }
 
- if (!is_gimple_val (arg1_len))
+ tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
+ gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
+  arg0, arg1, arg1_len);
+ tree strncmp_lhs = make_ssa_name (integer_type_node);
+ gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
+ gimple_call_set_lhs (strncmp_call, strncmp_lhs);
+ gsi_remove (, true);
+ gsi_insert_before (, strncmp_call, GSI_SAME_STMT);
+ tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
+
+ if (is_gimple_assign (stmt))
+   {
+ if (gimple_assign_rhs_code (stmt) == COND_EXPR)
{
- tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
- gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
-   arg1_len);
- gsi_insert_before (, arg1_stmt, GSI_SAME_STMT);
- arg1_len = arg1_len_tmp;
-   }
-
- gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
- arg0, arg1, arg1_len);
- tree strncmp_lhs = make_ssa_name (integer_type_node);
- gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
- gimple_call_set_lhs (strncmp_call, strncmp_lhs);
- gsi_remove (, true);
- gsi_insert_before (, strncmp_call, GSI_SAME_STMT);
- tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
-
- if (is_gimple_assign (stmt))
-   {
- if (gimple_assign_rhs_code (stmt) == COND_EXPR)
-   {
- 

[PATCH v2] c: don't emit -Wmissing-variable-declarations for register variables [PR110947]

2023-09-01 Thread Hamza Mahfooz
Resolves:
PR c/110947 - Should -Wmissing-variable-declarations not trigger on
register variables?

gcc/c/ChangeLog:

PR c/110947
* c-decl.cc (start_decl): don't emit
-Wmissing-variable-declarations for DECL_REGISTER VAR_DECLs.

gcc/testsuite/ChangeLog:

PR c/110947
* gcc.dg/pr110947.c: New test.

Signed-off-by: Hamza Mahfooz 
---
Please push this for me if you think it looks good. Since, I don't have
write access to the repository.

v2: put "target" before the relevant architectures in pr110947.c.
---
 gcc/c/c-decl.cc | 3 ++-
 gcc/testsuite/gcc.dg/pr110947.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr110947.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 1f9eb44dbaa..819af6aa050 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5376,7 +5376,8 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
 warning (OPT_Wmain, "%q+D is usually a function", decl);
 
   if (warn_missing_variable_declarations && VAR_P (decl)
-  && !DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) && old_decl == NULL_TREE)
+  && !DECL_EXTERNAL (decl) && !DECL_REGISTER (decl) && TREE_PUBLIC (decl)
+  && old_decl == NULL_TREE)
 warning_at (DECL_SOURCE_LOCATION (decl), 
OPT_Wmissing_variable_declarations,
"no previous declaration for %qD", decl);
 
diff --git a/gcc/testsuite/gcc.dg/pr110947.c b/gcc/testsuite/gcc.dg/pr110947.c
new file mode 100644
index 000..3c0b8a82ab3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110947.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-Wmissing-variable-declarations" } */
+
+register unsigned long current_stack_pointer asm("rsp");
-- 
2.41.0



[PATCH] c: don't emit -Wmissing-variable-declarations for register variables [PR110947]

2023-09-01 Thread Hamza Mahfooz
Resolves:
PR c/110947 - Should -Wmissing-variable-declarations not trigger on
register variables?

gcc/c/ChangeLog:

PR c/110947
* c-decl.cc (start_decl): don't emit
-Wmissing-variable-declarations for DECL_REGISTER VAR_DECLs.

gcc/testsuite/ChangeLog:

PR c/110947
* gcc.dg/pr110947.c: New test.

Signed-off-by: Hamza Mahfooz 
---
Please push this for me if you think it looks good. Since, I don't have
write access to the repository.
---
 gcc/c/c-decl.cc | 3 ++-
 gcc/testsuite/gcc.dg/pr110947.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr110947.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 1f9eb44dbaa..819af6aa050 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5376,7 +5376,8 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
 warning (OPT_Wmain, "%q+D is usually a function", decl);
 
   if (warn_missing_variable_declarations && VAR_P (decl)
-  && !DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) && old_decl == NULL_TREE)
+  && !DECL_EXTERNAL (decl) && !DECL_REGISTER (decl) && TREE_PUBLIC (decl)
+  && old_decl == NULL_TREE)
 warning_at (DECL_SOURCE_LOCATION (decl), 
OPT_Wmissing_variable_declarations,
"no previous declaration for %qD", decl);
 
diff --git a/gcc/testsuite/gcc.dg/pr110947.c b/gcc/testsuite/gcc.dg/pr110947.c
new file mode 100644
index 000..19e38ed4d18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110947.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { i?86-*-* target x86_64-*-* } } */
+/* { dg-options "-Wmissing-variable-declarations" } */
+
+register unsigned long current_stack_pointer asm("rsp");
-- 
2.41.0



Re: [PATCH RESEND] c: add -Wmissing-variable-declarations [PR65213]

2023-07-31 Thread Hamza Mahfooz

Hey Joseph,

On Fri, Jul 28 2023 at 08:32:31 PM +00:00:00, Joseph Myers 
 wrote:

OK.


--
Joseph S. Myers
jos...@codesourcery.com


Since I don't have write access, do you mind pushing this for me?




[PATCH RESEND] c: add -Wmissing-variable-declarations [PR65213]

2023-07-18 Thread Hamza Mahfooz
Resolves:
PR c/65213 - Extend -Wmissing-declarations to variables [i.e. add
-Wmissing-variable-declarations]

gcc/c-family/ChangeLog:

PR c/65213
* c.opt (-Wmissing-variable-declarations): New option.

gcc/c/ChangeLog:

PR c/65213
* c-decl.cc (start_decl): Handle
-Wmissing-variable-declarations.

gcc/ChangeLog:

PR c/65213
* doc/invoke.texi (-Wmissing-variable-declarations): Document
new option.

gcc/testsuite/ChangeLog:

PR c/65213
* gcc.dg/Wmissing-variable-declarations.c: New test.

Signed-off-by: Hamza Mahfooz 
---
 gcc/c-family/c.opt|  4 +++
 gcc/c/c-decl.cc   | 10 +-
 gcc/doc/invoke.texi   | 11 +--
 .../gcc.dg/Wmissing-variable-declarations.c   | 33 +++
 4 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 4abdc8d0e77..0ed87fcc7be 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1048,6 +1048,10 @@ Wmissing-prototypes
 C ObjC Var(warn_missing_prototypes) Warning
 Warn about global functions without prototypes.
 
+Wmissing-variable-declarations
+C ObjC Var(warn_missing_variable_declarations) Warning
+Warn about global variables without previous declarations.
+
 Wmudflap
 C ObjC C++ ObjC++ WarnRemoved
 
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index ecd10ebb69c..1f9eb44dbaa 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5340,6 +5340,7 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
location_t *lastloc /* = NULL */)
 {
   tree decl;
+  tree old_decl;
   tree tem;
   tree expr = NULL_TREE;
   enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
@@ -5360,7 +5361,9 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
   if (!decl || decl == error_mark_node)
 return NULL_TREE;
 
-  if (tree lastdecl = lastloc ? lookup_last_decl (decl) : NULL_TREE)
+  old_decl = lookup_last_decl (decl);
+
+  if (tree lastdecl = lastloc ? old_decl : NULL_TREE)
 if (lastdecl != error_mark_node)
   *lastloc = DECL_SOURCE_LOCATION (lastdecl);
 
@@ -5372,6 +5375,11 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
   && TREE_PUBLIC (decl))
 warning (OPT_Wmain, "%q+D is usually a function", decl);
 
+  if (warn_missing_variable_declarations && VAR_P (decl)
+  && !DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) && old_decl == NULL_TREE)
+warning_at (DECL_SOURCE_LOCATION (decl), 
OPT_Wmissing_variable_declarations,
+   "no previous declaration for %qD", decl);
+
   if (initialized)
 /* Is it valid for this decl to have an initializer at all?
If not, set INITIALIZED to zero, which will indirectly
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 88e3c625030..c2a0562b9e6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -498,8 +498,8 @@ Objective-C and Objective-C++ Dialects}.
 
 @item C and Objective-C-only Warning Options
 @gccoptlist{-Wbad-function-cast  -Wmissing-declarations
--Wmissing-parameter-type  -Wmissing-prototypes  -Wnested-externs
--Wold-style-declaration  -Wold-style-definition
+-Wmissing-parameter-type -Wmissing-prototypes -Wmissing-variable-declarations
+-Wnested-externs -Wold-style-declaration  -Wold-style-definition
 -Wstrict-prototypes  -Wtraditional  -Wtraditional-conversion
 -Wdeclaration-after-statement  -Wpointer-sign}
 
@@ -9610,6 +9610,13 @@ provide prototypes and a non-matching declaration 
declares an
 overload rather than conflict with an earlier declaration.
 Use @option{-Wmissing-declarations} to detect missing declarations in C++.
 
+@opindex Wmissing-variable-declarations
+@opindex Wno-missing-variable-declarations
+@item -Wmissing-variable-declarations @r{(C and Objective-C only)}
+Warn if a global variable is defined without a previous declaration.
+Use this option to detect global variables that do not have a matching
+extern declaration in a header file.
+
 @opindex Wmissing-declarations
 @opindex Wno-missing-declarations
 @item -Wmissing-declarations
diff --git a/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c 
b/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c
new file mode 100644
index 000..b292dbe8c22
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-variable-declarations" } */
+
+int b0; /* { dg-warning "no previous declaration for 'b0'" } */
+
+int b1 = 1; /* { dg-warning "no previous declaration for 'b1'" } */
+
+int b2; /* { dg-warning "no previous declaration for 'b2'" } */
+int b2 = 2; 
+
+struct {
+int g0;
+} b3; /* { dg-warning "no previous declaration for 

Re: [PATCH] Add -Wmissing-variable-declarations [PR65213].

2023-07-05 Thread Hamza Mahfooz

Ping?

On Tue, Jun 13 2023 at 09:05:29 AM -04:00:00, Hamza Mahfooz 
 wrote:

Resolves:
PR c/65213 - Extend -Wmissing-declarations to variables [i.e. add
-Wmissing-variable-declarations]

gcc/c-family/ChangeLog:

PR c/65213
* c.opt (-Wmissing-variable-declarations): New option.

gcc/c/ChangeLog:

PR c/65213
* c-decl.cc (start_decl): Handle -Wmissing-variable-declarations

gcc/ChangeLog:

PR c/65213
* doc/invoke.texi (-Wmissing-variable-declarations): Document
new option.

gcc/testsuite/ChangeLog:

PR c/65213
* gcc.dg/Wmissing-variable-declarations.c: New test.

Signed-off-by: Hamza Mahfooz 
---
 gcc/c-family/c.opt|  4 +++
 gcc/c/c-decl.cc   | 10 +-
 gcc/doc/invoke.texi   | 11 +--
 .../gcc.dg/Wmissing-variable-declarations.c   | 33 
+++

 4 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c


diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index cead1995561..42ad447f39b 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1043,6 +1043,10 @@ Wmissing-prototypes
 C ObjC Var(warn_missing_prototypes) Warning
 Warn about global functions without prototypes.

+Wmissing-variable-declarations
+C ObjC Var(warn_missing_variable_declarations) Warning
+Warn about global variables without previous declarations.
+
 Wmudflap
 C ObjC C++ ObjC++ WarnRemoved

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 1af51c4acfc..8e276b2a846 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5340,6 +5340,7 @@ start_decl (struct c_declarator *declarator, 
struct c_declspecs *declspecs,

location_t *lastloc /* = NULL */)
 {
   tree decl;
+  tree old_decl;
   tree tem;
   tree expr = NULL_TREE;
   enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
@@ -5360,7 +5361,9 @@ start_decl (struct c_declarator *declarator, 
struct c_declspecs *declspecs,

   if (!decl || decl == error_mark_node)
 return NULL_TREE;

-  if (tree lastdecl = lastloc ? lookup_last_decl (decl) : NULL_TREE)
+  old_decl = lookup_last_decl (decl);
+
+  if (tree lastdecl = lastloc ? old_decl : NULL_TREE)
 if (lastdecl != error_mark_node)
   *lastloc = DECL_SOURCE_LOCATION (lastdecl);

@@ -5372,6 +5375,11 @@ start_decl (struct c_declarator *declarator, 
struct c_declspecs *declspecs,

   && TREE_PUBLIC (decl))
 warning (OPT_Wmain, "%q+D is usually a function", decl);

+  if (warn_missing_variable_declarations && VAR_P (decl)
+  && !DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) && old_decl == 
NULL_TREE)
+warning_at (DECL_SOURCE_LOCATION (decl), 
OPT_Wmissing_variable_declarations,

+   "no previous declaration for %qD", decl);
+
   if (initialized)
 /* Is it valid for this decl to have an initializer at all?
If not, set INITIALIZED to zero, which will indirectly
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8fa3f9fae01..e9b51842234 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -496,8 +496,8 @@ Objective-C and Objective-C++ Dialects}.

 @item C and Objective-C-only Warning Options
 @gccoptlist{-Wbad-function-cast  -Wmissing-declarations
--Wmissing-parameter-type  -Wmissing-prototypes  -Wnested-externs
--Wold-style-declaration  -Wold-style-definition
+-Wmissing-parameter-type -Wmissing-prototypes 
-Wmissing-variable-declarations

+-Wnested-externs -Wold-style-declaration  -Wold-style-definition
 -Wstrict-prototypes  -Wtraditional  -Wtraditional-conversion
 -Wdeclaration-after-statement  -Wpointer-sign}

@@ -9565,6 +9565,13 @@ provide prototypes and a non-matching 
declaration declares an

 overload rather than conflict with an earlier declaration.
 Use @option{-Wmissing-declarations} to detect missing declarations 
in C++.


+@opindex Wmissing-variable-declarations
+@opindex Wno-missing-variable-declarations
+@item -Wmissing-variable-declarations @r{(C and Objective-C only)}
+Warn if a global variable is defined without a previous declaration.
+Use this option to detect global variables that do not have a 
matching

+extern declaration in a header file.
+
 @opindex Wmissing-declarations
 @opindex Wno-missing-declarations
 @item -Wmissing-declarations
diff --git a/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c 
b/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c

new file mode 100644
index 000..b292dbe8c22
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-variable-declarations" } */
+
+int b0; /* { dg-warning "no previous declaration for 'b0'" } */
+
+int b1 = 1; /* { dg-warning "no previous declaration for 'b1'" } */
+
+int b2; /* { dg-warning "no previous declaration for 'b2'" } */
+int b2 = 2;
+
+str

[PATCH] Add -Wmissing-variable-declarations [PR65213].

2023-06-13 Thread Hamza Mahfooz
Resolves:
PR c/65213 - Extend -Wmissing-declarations to variables [i.e. add
-Wmissing-variable-declarations]

gcc/c-family/ChangeLog:

PR c/65213
* c.opt (-Wmissing-variable-declarations): New option.

gcc/c/ChangeLog:

PR c/65213
* c-decl.cc (start_decl): Handle -Wmissing-variable-declarations

gcc/ChangeLog:

PR c/65213
* doc/invoke.texi (-Wmissing-variable-declarations): Document
new option.

gcc/testsuite/ChangeLog:

PR c/65213
* gcc.dg/Wmissing-variable-declarations.c: New test.

Signed-off-by: Hamza Mahfooz 
---
 gcc/c-family/c.opt|  4 +++
 gcc/c/c-decl.cc   | 10 +-
 gcc/doc/invoke.texi   | 11 +--
 .../gcc.dg/Wmissing-variable-declarations.c   | 33 +++
 4 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index cead1995561..42ad447f39b 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1043,6 +1043,10 @@ Wmissing-prototypes
 C ObjC Var(warn_missing_prototypes) Warning
 Warn about global functions without prototypes.
 
+Wmissing-variable-declarations
+C ObjC Var(warn_missing_variable_declarations) Warning
+Warn about global variables without previous declarations.
+
 Wmudflap
 C ObjC C++ ObjC++ WarnRemoved
 
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 1af51c4acfc..8e276b2a846 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5340,6 +5340,7 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
location_t *lastloc /* = NULL */)
 {
   tree decl;
+  tree old_decl;
   tree tem;
   tree expr = NULL_TREE;
   enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
@@ -5360,7 +5361,9 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
   if (!decl || decl == error_mark_node)
 return NULL_TREE;
 
-  if (tree lastdecl = lastloc ? lookup_last_decl (decl) : NULL_TREE)
+  old_decl = lookup_last_decl (decl);
+
+  if (tree lastdecl = lastloc ? old_decl : NULL_TREE)
 if (lastdecl != error_mark_node)
   *lastloc = DECL_SOURCE_LOCATION (lastdecl);
 
@@ -5372,6 +5375,11 @@ start_decl (struct c_declarator *declarator, struct 
c_declspecs *declspecs,
   && TREE_PUBLIC (decl))
 warning (OPT_Wmain, "%q+D is usually a function", decl);
 
+  if (warn_missing_variable_declarations && VAR_P (decl)
+  && !DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) && old_decl == NULL_TREE)
+warning_at (DECL_SOURCE_LOCATION (decl), 
OPT_Wmissing_variable_declarations,
+   "no previous declaration for %qD", decl);
+
   if (initialized)
 /* Is it valid for this decl to have an initializer at all?
If not, set INITIALIZED to zero, which will indirectly
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8fa3f9fae01..e9b51842234 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -496,8 +496,8 @@ Objective-C and Objective-C++ Dialects}.
 
 @item C and Objective-C-only Warning Options
 @gccoptlist{-Wbad-function-cast  -Wmissing-declarations
--Wmissing-parameter-type  -Wmissing-prototypes  -Wnested-externs
--Wold-style-declaration  -Wold-style-definition
+-Wmissing-parameter-type -Wmissing-prototypes -Wmissing-variable-declarations
+-Wnested-externs -Wold-style-declaration  -Wold-style-definition
 -Wstrict-prototypes  -Wtraditional  -Wtraditional-conversion
 -Wdeclaration-after-statement  -Wpointer-sign}
 
@@ -9565,6 +9565,13 @@ provide prototypes and a non-matching declaration 
declares an
 overload rather than conflict with an earlier declaration.
 Use @option{-Wmissing-declarations} to detect missing declarations in C++.
 
+@opindex Wmissing-variable-declarations
+@opindex Wno-missing-variable-declarations
+@item -Wmissing-variable-declarations @r{(C and Objective-C only)}
+Warn if a global variable is defined without a previous declaration.
+Use this option to detect global variables that do not have a matching
+extern declaration in a header file.
+
 @opindex Wmissing-declarations
 @opindex Wno-missing-declarations
 @item -Wmissing-declarations
diff --git a/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c 
b/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c
new file mode 100644
index 000..b292dbe8c22
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-variable-declarations.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-variable-declarations" } */
+
+int b0; /* { dg-warning "no previous declaration for 'b0'" } */
+
+int b1 = 1; /* { dg-warning "no previous declaration for 'b1'" } */
+
+int b2; /* { dg-warning "no previous declaration for 'b2'" } */
+int b2 = 2; 
+
+struct {
+int g0;
+} b3; /* { dg-warning "no previous declaration for 'b3'"