public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Martin Sebor <msebor@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r11-8205] Propagate type attribute when merging extern declarations at local scope.
Date: Thu, 15 Apr 2021 21:51:50 +0000 (GMT)	[thread overview]
Message-ID: <20210415215150.DA6863846454@sourceware.org> (raw)

https://gcc.gnu.org/g:da879e01ecd35737c18be1da3324f4560aba1961

commit r11-8205-gda879e01ecd35737c18be1da3324f4560aba1961
Author: Martin Sebor <msebor@redhat.com>
Date:   Thu Apr 15 15:49:30 2021 -0600

    Propagate type attribute when merging extern declarations at local scope.
    
    Resolves:
    PR c/99420 - bogus -Warray-parameter on a function redeclaration in function scope
    PR c/99972 - missing -Wunused-result on a call to a locally redeclared warn_unused_result function
    
    gcc/c/ChangeLog:
    
            PR c/99420
            PR c/99972
            * c-decl.c (pushdecl): Always propagate type attribute.
    
    gcc/testsuite/ChangeLog:
    
            PR c/99420
            PR c/99972
            * gcc.dg/Warray-parameter-9.c: New test.
            * gcc.dg/Wnonnull-6.c: New test.
            * gcc.dg/Wreturn-type3.c: New test.
            * gcc.dg/Wunused-result.c: New test.
            * gcc.dg/attr-noreturn.c: New test.
            * gcc.dg/attr-returns-nonnull.c: New test.

Diff:
---
 gcc/c/c-decl.c                              |  9 ++-
 gcc/testsuite/gcc.dg/Warray-parameter-9.c   | 54 +++++++++++++++++
 gcc/testsuite/gcc.dg/Wnonnull-6.c           | 93 +++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wreturn-type3.c        | 54 +++++++++++++++++
 gcc/testsuite/gcc.dg/Wunused-result.c       | 50 ++++++++++++++++
 gcc/testsuite/gcc.dg/attr-noreturn.c        | 64 ++++++++++++++++++++
 gcc/testsuite/gcc.dg/attr-returns-nonnull.c | 58 ++++++++++++++++++
 7 files changed, 377 insertions(+), 5 deletions(-)

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 3c254511bd8..3ea4708c507 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -3263,11 +3263,10 @@ pushdecl (tree x)
 	  else
 	    thistype = type;
 	  b->u.type = TREE_TYPE (b->decl);
-	  if (TREE_CODE (b->decl) == FUNCTION_DECL
-	      && fndecl_built_in_p (b->decl))
-	    thistype
-	      = build_type_attribute_variant (thistype,
-					      TYPE_ATTRIBUTES (b->u.type));
+	  /* Propagate the type attributes to the decl.  */
+	  thistype
+	    = build_type_attribute_variant (thistype,
+					    TYPE_ATTRIBUTES (b->u.type));
 	  TREE_TYPE (b->decl) = thistype;
 	  bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true,
 		locus);
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-9.c b/gcc/testsuite/gcc.dg/Warray-parameter-9.c
new file mode 100644
index 00000000000..b5d3d963c88
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-9.c
@@ -0,0 +1,54 @@
+/* PR c/99420 - bogus -Warray-parameter on a function redeclaration
+   in function scope
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+extern int a1[1], a2[2], a3[3], a4[4];
+
+void fa1 (int [1]);     // { dg-message "previously declared as 'int\\\[1]'" }
+void fa1 (int [1]);
+
+
+void nested_decl (void)
+{
+  void fa2 (int [2]);
+
+  fa2 (a1);             // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
+  fa2 (a2);
+  fa2 (a3);
+
+  void fa3 (int [3]);
+
+  fa3 (a2);             // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
+  fa3 (a3);
+}
+
+
+void nested_redecl (void)
+{
+  void fa1 (int [2]);   // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" }
+
+  fa1 (a1 + 1);         // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
+  fa1 (a1);
+
+  void fa2 (int [2]);   // { dg-bogus "\\\[-Warray-parameter" }
+
+  fa2 (a1);             // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
+  fa2 (a2);
+  fa2 (a3);
+
+  void fa3 (int [3]);   // { dg-bogus "\\\[-Warray-parameter" }
+
+  fa3 (a2);             // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
+  fa3 (a3);
+
+  void fa4 (int [4]);
+}
+
+void fa4 (int [5]);     // { dg-warning "\\\[-Warray-parameter" }
+
+void call_fa4 (void)
+{
+  fa4 (a4);
+  fa4 (a3);             // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wnonnull-6.c b/gcc/testsuite/gcc.dg/Wnonnull-6.c
new file mode 100644
index 00000000000..48f09da996f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wnonnull-6.c
@@ -0,0 +1,93 @@
+/* Verify that attribute nonnull on global and local function declarations
+   or those to pointers to functions is merged.
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+void fnonnull_local_local (void)
+{
+  extern __attribute__ ((nonnull)) void fnonnull1 (void*);
+
+  fnonnull1 (0);    // { dg-warning "\\\[-Wnonnull" }
+}
+
+void gnonnull_local_local (void)
+{
+  extern void fnonnull1 (void*);
+
+  fnonnull1 (0);    // { dg-warning "\\\[-Wnonnull" }
+}
+
+
+void fnonnull_local_global (void)
+{
+  extern __attribute__ ((nonnull)) void fnonnull2 (void*);
+
+  fnonnull2 (0);    // { dg-warning "\\\[-Wnonnull" }
+}
+
+extern void fnonnull2 (void*);
+
+void gnonnull_local_global (void)
+{
+  fnonnull2 (0);    // { dg-warning "\\\[-Wnonnull" }
+}
+
+
+extern __attribute__ ((nonnull)) void fnonnull3 (void*);
+
+void fnonnull_global_local (void)
+{
+  fnonnull3 (0);    // { dg-warning "\\\[-Wnonnull" }
+}
+
+void gnonnull_global_local (void)
+{
+  extern void fnonnull3 (void*);
+
+  fnonnull3 (0);    // { dg-warning "\\\[-Wnonnull" }
+}
+
+
+void pfnonnull_local_local (void)
+{
+  extern __attribute__ ((nonnull)) void (*pfnonnull1) (void*);
+
+  pfnonnull1 (0);   // { dg-warning "\\\[-Wnonnull" }
+}
+
+void gpnonnull_local_local (void)
+{
+  extern void (*pfnonnull1) (void*);
+
+  pfnonnull1 (0);   // { dg-warning "\\\[-Wnonnull" "pr?????" { xfail *-*-* } }
+}
+
+
+void pfnonnull_local_global (void)
+{
+  extern __attribute__ ((nonnull)) void (*pfnonnull2) (void*);
+
+  pfnonnull2 (0);   // { dg-warning "\\\[-Wnonnull" }
+}
+
+extern void (*pfnonnull2) (void*);
+
+void gpnonnull_local_global (void)
+{
+  pfnonnull2 (0);   // { dg-warning "\\\[-Wnonnull" "pr?????" { xfail *-*-* } }
+}
+
+
+extern __attribute__ ((nonnull)) void (*pfnonnull3) (void*);
+
+void pfnonnull_global_local (void)
+{
+  pfnonnull3 (0);   // { dg-warning "\\\[-Wnonnull" }
+}
+
+void gpnonnull_global_local (void)
+{
+  extern void (*pfnonnull3) (void*);
+
+  pfnonnull3 (0);   // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-type3.c b/gcc/testsuite/gcc.dg/Wreturn-type3.c
new file mode 100644
index 00000000000..93596b399f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-type3.c
@@ -0,0 +1,54 @@
+/* Verify that attribute noreturn on global and local function declarations
+   is merged.
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+int fnr_local_local (void)
+{
+  __attribute__ ((noreturn)) void fnr1 (void);
+
+  fnr1 ();
+  // no return, no warning (good)
+}
+
+int gnr_local_local (void)
+{
+  void fnr1 (void);
+
+  fnr1 ();
+  // no return, no warning (good)
+}
+
+
+int fnr_local_global (void)
+{
+  __attribute__ ((noreturn)) void fnr2 (void);
+
+  fnr2 ();
+  // no return, no warning (good)
+}
+
+void fnr2 (void);
+
+int gnr_local_global (void)
+{
+  fnr2 ();
+  // no return, no warning (good)
+}
+
+
+__attribute__ ((noreturn)) void fnr3 (void);
+
+int fnr_global_local (void)
+{
+  fnr3 ();
+  // no return, no warning (good)
+}
+
+int gnr_global_local (void)
+{
+  void fnr3 (void);
+
+  fnr3 ();
+  // no return, no warning (good)
+}
diff --git a/gcc/testsuite/gcc.dg/Wunused-result.c b/gcc/testsuite/gcc.dg/Wunused-result.c
new file mode 100644
index 00000000000..c0bb9ae35e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunused-result.c
@@ -0,0 +1,50 @@
+/* PR c/99972 - missing -Wunused-result on a call to a locally redeclared
+   warn_unused_result function
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+void gwur_local_local (void)
+{
+  __attribute__ ((warn_unused_result)) int fwur1 (void);
+
+  fwur1 ();         // { dg-warning "\\\[-Wunused-result" }
+}
+
+void hwur_local_local (void)
+{
+  /* Verify the attribute from the declaration above is copied/merged
+     into the declaration below.  */
+  int fwur1 (void);
+
+  fwur1 ();          // { dg-warning "\\\[-Wunused-result" }
+}
+
+
+void gwur_local_global (void)
+{
+  __attribute__ ((warn_unused_result)) int fwur2 (void);
+
+  fwur2 ();         // { dg-warning "\\\[-Wunused-result" }
+}
+
+int fwur2 (void);
+
+void hwur_local_global (void)
+{
+  fwur2 ();         // { dg-warning "\\\[-Wunused-result" }
+}
+
+
+__attribute__ ((warn_unused_result)) int fwur3 (void);
+
+void gwur_global_local (void)
+{
+  fwur3 ();         // { dg-warning "\\\[-Wunused-result" }
+}
+
+void hwur_global_local (void)
+{
+  int fwur3 (void);
+
+  fwur3 ();         // { dg-warning "\\\[-Wunused-result" }
+}
diff --git a/gcc/testsuite/gcc.dg/attr-noreturn.c b/gcc/testsuite/gcc.dg/attr-noreturn.c
new file mode 100644
index 00000000000..8d58f6ece9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-noreturn.c
@@ -0,0 +1,64 @@
+/* Verify that attribute noreturn on global and local function declarations
+   is merged.
+   { dg-do compile }
+   { dg-options "-Wall -fdump-tree-optimized" } */
+
+void foo (void);
+
+int fnr_local_local (void)
+{
+  __attribute__ ((noreturn)) void fnr1 (void);
+
+  fnr1 ();
+
+  foo ();
+}
+
+int gnr_local_local (void)
+{
+  void fnr1 (void);
+
+  fnr1 ();
+
+  foo ();
+}
+
+
+int fnr_local_global (void)
+{
+  __attribute__ ((noreturn)) void fnr2 (void);
+
+  fnr2 ();
+
+  foo ();
+}
+
+void fnr2 (void);
+
+int gnr_local_global (void)
+{
+  fnr2 ();
+
+  foo ();
+}
+
+
+__attribute__ ((noreturn)) void fnr3 (void);
+
+int fnr_global_local (void)
+{
+  fnr3 ();
+
+  foo ();
+}
+
+int gnr_global_local (void)
+{
+  void fnr3 (void);
+
+  fnr3 ();
+
+  foo ();
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/attr-returns-nonnull.c b/gcc/testsuite/gcc.dg/attr-returns-nonnull.c
new file mode 100644
index 00000000000..22ee30ac5df
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-returns-nonnull.c
@@ -0,0 +1,58 @@
+/* Verify that attribute returns_nonnull on global and local function
+   declarations is merged.
+   { dg-do compile }
+   { dg-options "-Wall -fdump-tree-optimized" } */
+
+void foo (void);
+
+
+void frnn_local_local (void)
+{
+  __attribute__ ((returns_nonnull)) void* frnn1 (void);
+
+  if (!frnn1 ())
+    foo ();
+}
+
+void gnr_local_local (void)
+{
+  void* frnn1 (void);
+
+  if (!frnn1 ())
+    foo ();
+}
+
+void frnn_local_global (void)
+{
+  __attribute__ ((returns_nonnull)) void* frnn2 (void);
+
+  if (!frnn2 ())
+    foo ();
+}
+
+void* frnn2 (void);
+
+void gnr_local_global (void)
+{
+  if (!frnn2 ())
+    foo ();
+}
+
+__attribute__ ((returns_nonnull)) void* frnn3 (void);
+
+void frnn_global_local (void)
+{
+  if (!frnn3 ())
+    foo ();
+}
+
+void gnr_global_local (void)
+{
+  void* frnn3 (void);
+
+  if (!frnn3 ())
+    foo ();
+}
+
+
+/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */


                 reply	other threads:[~2021-04-15 21:51 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210415215150.DA6863846454@sourceware.org \
    --to=msebor@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).