Re: [PATCH v2] c: don't emit -Wmissing-variable-declarations for register variables [PR110947]
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()
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]
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()
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]
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]
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]
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]
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]
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].
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].
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'"