public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-3304] Make use of new attribute access infrastructure in -Wuninitialized (PR 50584).
@ 2020-09-19 23:57 Martin Sebor
  0 siblings, 0 replies; only message in thread
From: Martin Sebor @ 2020-09-19 23:57 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:72be80e47d059f33ff11f5015b9494c42b4e0a12

commit r11-3304-g72be80e47d059f33ff11f5015b9494c42b4e0a12
Author: Martin Sebor <msebor@redhat.com>
Date:   Sat Sep 19 17:30:32 2020 -0600

    Make use of new attribute access infrastructure in -Wuninitialized (PR 50584).
    
    gcc/ChangeLog:
    
            * tree-ssa-uninit.c (maybe_warn_pass_by_reference): Handle attribute
            access internal representation of arrays.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/uninit-37.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/uninit-37.c | 154 +++++++++++++++++++++++++++++++++++++++
 gcc/tree-ssa-uninit.c            |  62 +++++++++-------
 2 files changed, 190 insertions(+), 26 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/uninit-37.c b/gcc/testsuite/gcc.dg/uninit-37.c
new file mode 100644
index 00000000000..b8c49ad17ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-37.c
@@ -0,0 +1,154 @@
+/* PR middle-end/10138 - warn for uninitialized arrays passed as const arguments
+   Verify that -Wuninitialized and -Wmaybe-uninitialized trigger (or don't)
+   when passing uninitialized variables by reference to functions declared
+   with or without attribute access and with (or without) const qualified
+   arguments of array, VLA, or pointer types.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NONE    /* none */
+#define RO(...) __attribute__ ((access (read_only, __VA_ARGS__)))
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+#define WO(...) __attribute__ ((access (write_only, __VA_ARGS__)))
+#define X(...)  __attribute__ ((access (none, __VA_ARGS__)))
+
+#define CONCAT(x, y) x ## y
+#define CAT(x, y)    CONCAT (x, y)
+#define UNIQ(pfx)    CAT (pfx, __LINE__)
+
+extern void sink (void*);
+
+
+#define T1(attr, name, type)			\
+  void UNIQ (CAT (test_, name))(void) {		\
+    extern attr void UNIQ (name)(type);		\
+    int x;					\
+    UNIQ (name)(&x);				\
+    sink (&x);					\
+  }
+
+#define T2(attr, name, types)			\
+  void UNIQ (CAT (test_, name))(void) {		\
+    extern attr void UNIQ (name)(types);	\
+    int x;					\
+    UNIQ (name)(1, &x);				\
+    sink (&x);					\
+  }
+
+
+typedef int IA_[];
+typedef const int CIA_[];
+
+T1 (NONE,   fia_,   IA_);
+T1 (NONE,   fcia_,  CIA_);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froia_, IA_);     // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwia_, IA_);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoia_, IA_);
+T1 (X (1),  fxia_,  IA_);
+
+
+typedef int IA1[1];
+typedef const int CIA1[1];
+
+T1 (NONE,   fia1,   IA1);
+T1 (NONE,   fcia1,  CIA1);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froia1, IA1);     // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwia1, IA1);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoia1, IA1);
+T1 (X (1),  fxia1,  IA1);
+
+
+#define IARS1  int[restrict static 1]
+#define CIARS1 const int[restrict static 1]
+
+T1 (NONE,   fiars1,   IARS1);
+T1 (NONE,   fciars1,  CIARS1);// { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froiars1, IARS1); // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwiars1, IARS1); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoiars1, IARS1);
+T1 (X (1),  fxiars1,  IARS1);
+
+
+#define IAS1  int[static 1]
+#define CIAS1 const int[static 1]
+
+T1 (NONE,   fias1,   IAS1);
+T1 (NONE,   fcias1,  CIAS1);   // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froias1, IAS1);    // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwias1, IAS1);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoias1, IAS1);
+T1 (X (1),  fxias1,  IAS1);
+
+
+#define IAX  int[*]
+#define CIAX const int[*]
+
+T1 (NONE,   fiax,   IAX);
+T1 (NONE,   fciax,  CIAX);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froiax, IAX);     // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwiax, IAX);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoiax, IAX);
+T1 (X (1),  fxiax,  IAX);
+
+
+#define IAN  int n, int[n]
+#define CIAN int n, const int[n]
+
+T2 (NONE,      fian,   IAN);
+T2 (NONE,      fcian,  CIAN); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T2 (RO (2, 1), froian, IAN);  // { dg-warning "\\\[-Wuninitialized" }
+T2 (RW (2, 1), frwian, IAN);  // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T2 (WO (2, 1), fwoian, IAN);
+T2 (X (2, 1),  fxian,  IAN);
+
+
+typedef int* IP;
+typedef const int* CIP;
+
+T1 (NONE,   fip,   IP);
+T1 (NONE,   fcip,  CIP);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froip, IP);      // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwip, IP);      // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoip, IP);
+T1 (X (1),  fxip,  IP);
+
+
+/* Verify that the notes printed after the warning mention attribute
+   access only when the attribute is explicitly used in the declaration
+   and not otherwise.  */
+
+void test_note_cst_restrict (void)
+{
+  extern void
+    fccar (const char[restrict]);   // { dg-message "by argument 1 of type 'const char\\\[restrict]' to 'fccar'" "note" }
+
+  char a[1];                  // { dg-message "'a' declared here" "note" }
+  fccar (a);                  // { dg-warning "'a' may be used uninitialized" }
+}
+
+void test_note_vla (int n)
+{
+  extern void
+    fccvla (const char[n]);   // { dg-message "by argument 1 of type 'const char\\\[n]' to 'fccvla'" "note" }
+
+  char a[2];                  // { dg-message "'a' declared here" "note" }
+  fccvla (a);                 // { dg-warning "'a' may be used uninitialized" }
+}
+
+void test_note_ro (void)
+{
+  extern RO (1) void
+    frocar (char[restrict]);  // { dg-message "in a call to 'frocar' declared with attribute 'access \\\(read_only, 1\\\)'" "note" }
+
+  char a[3];                  // { dg-message "'a' declared here" "note" }
+  frocar (a);                 // { dg-warning "'a' is used uninitialized" }
+}
+
+void test_note_rw (void)
+{
+  extern RW (1) void
+    frwcar (char[restrict]);  // { dg-message "in a call to 'frwcar' declared with attribute 'access \\\(read_write, 1\\\)'" "note" }
+
+  char a[4];                  // { dg-message "'a' declared here" "note" }
+  frwcar (a);                 // { dg-warning "'a' may be used uninitialized" }
+}
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 2cef5f3643f..0447bb2f3fb 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+#define INCLUDE_STRING
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -472,7 +473,8 @@ maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims)
      read_only.  */
   const bool save_always_executed = wlims.always_executed;
 
-  /* Map of attribute access specifications for function arguments.  */
+  /* Initialize a map of attribute access specifications for arguments
+     to the function function call.  */
   rdwr_map rdwr_idx;
   init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
 
@@ -488,12 +490,17 @@ maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims)
 	continue;
 
       tree access_size = NULL_TREE;
-      attr_access *access = rdwr_idx.get (argno - 1);
+      const attr_access* access = rdwr_idx.get (argno - 1);
       if (access)
 	{
 	  if (access->mode == access_none
 	      || access->mode == access_write_only)
 	    continue;
+
+	  if (access->mode == access_deferred
+	      && !TYPE_READONLY (TREE_TYPE (argtype)))
+	    continue;
+
 	  if (save_always_executed && access->mode == access_read_only)
 	    /* Attribute read_only arguments imply read access.  */
 	    wlims.always_executed = true;
@@ -524,45 +531,48 @@ maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims)
       if (!argbase)
 	continue;
 
-      if (access)
+      if (access && access->mode != access_deferred)
 	{
-	  const char* const mode = (access->mode == access_read_only
-				    ? "read_only" : "read_write");
-	  char attrstr[80];
-	  int n = sprintf (attrstr, "access (%s, %u", mode, argno);
-	  if (access->sizarg < UINT_MAX)
-	    sprintf (attrstr + n, ", %u)", access->sizarg);
-	  else
-	    strcpy (attrstr + n, ")");
+	  const char* const access_str =
+	    TREE_STRING_POINTER (access->to_external_string ());
 
 	  if (fndecl)
 	    {
 	      location_t loc = DECL_SOURCE_LOCATION (fndecl);
-	      inform (loc, "in a call to %qD declared "
-		      "with attribute %<access (%s, %u)%> here",
-		      fndecl, mode, argno);
+	      inform (loc, "in a call to %qD declared with "
+		      "attribute %<%s%> here", fndecl, access_str);
 	    }
 	  else
 	    {
 	      /* Handle calls through function pointers.  */
 	      location_t loc = gimple_location (stmt);
 	      inform (loc, "in a call to %qT declared with "
-		      "attribute %<access (%s, %u)%>",
-		      fntype, mode, argno);
+		      "attribute %<%s%>", fntype, access_str);
 	    }
 	}
-      else if (fndecl)
-	{
-	  location_t loc = DECL_SOURCE_LOCATION (fndecl);
-	  inform (loc, "by argument %u of type %qT to %qD declared here",
-		  argno, argtype, fndecl);
-	}
       else
 	{
-	  /* Handle calls through function pointers.  */
-	  location_t loc = gimple_location (stmt);
-	  inform (loc, "by argument %u of type %qT to %qT",
-		  argno, argtype, fntype);
+	  /* For a declaration with no relevant attribute access create
+	     a dummy object and use the formatting function to avoid
+	     having to complicate things here.  */
+	  attr_access ptr_access = { };
+	  if (!access)
+	    access = &ptr_access;
+	  const std::string argtypestr = access->array_as_string (argtype);
+	  if (fndecl)
+	    {
+	      location_t loc (DECL_SOURCE_LOCATION (fndecl));
+	      inform (loc, "by argument %u of type %<%s%> to %qD "
+		      "declared here",
+		      argno, argtypestr.c_str (), fndecl);
+	    }
+	  else
+	    {
+	      /* Handle calls through function pointers.  */
+	      location_t loc (gimple_location (stmt));
+	      inform (loc, "by argument %u of type %<%s%> to %qT",
+		      argno, argtypestr.c_str (), fntype);
+	    }
 	}
 
       if (DECL_P (argbase))


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

only message in thread, other threads:[~2020-09-19 23:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-19 23:57 [gcc r11-3304] Make use of new attribute access infrastructure in -Wuninitialized (PR 50584) 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).