public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8205] Propagate type attribute when merging extern declarations at local scope.
@ 2021-04-15 21:51 Martin Sebor
  0 siblings, 0 replies; only message in thread
From: Martin Sebor @ 2021-04-15 21:51 UTC (permalink / raw)
  To: gcc-cvs

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" } } */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-04-15 21:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-15 21:51 [gcc r11-8205] Propagate type attribute when merging extern declarations at local scope Martin Sebor

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).