diff mbox series

use is_empty_type to check for empty types (PR 97840)

Message ID f67fb3c3-d939-95e8-a965-3cda8138ff12@gmail.com
State New
Headers show
Series use is_empty_type to check for empty types (PR 97840) | expand

Commit Message

Martin Sebor Nov. 16, 2020, 11:22 p.m. UTC
The -Wmaybe-uninitialized enhancement to warn when the address
of an uninitialized object is passed to a function taking a const
pointer (or, in C++, a const reference) tries to avoid triggering
when the address is that of an empty object.  It does that by
checking EMPTY_TYPE_P() and default_is_empty_record() for structs.
As it turns out, neither of these is reliable for this purpose
(both are subject to ABI constraints).

The attached patch replaces these tests by one for is_empty_type(),
the workhorse function behind default_is_empty_record().  Besides
bootstrapping and regtesting on x86_64-linux I've tested the patch
works to suppress the warning with an aarch64-gnu-linux cross
(where the bogus warning was reported).

Martin

Comments

Jeff Law Nov. 16, 2020, 11:37 p.m. UTC | #1
On 11/16/20 4:22 PM, Martin Sebor via Gcc-patches wrote:
> The -Wmaybe-uninitialized enhancement to warn when the address
> of an uninitialized object is passed to a function taking a const
> pointer (or, in C++, a const reference) tries to avoid triggering
> when the address is that of an empty object.  It does that by
> checking EMPTY_TYPE_P() and default_is_empty_record() for structs.
> As it turns out, neither of these is reliable for this purpose
> (both are subject to ABI constraints).
>
> The attached patch replaces these tests by one for is_empty_type(),
> the workhorse function behind default_is_empty_record().  Besides
> bootstrapping and regtesting on x86_64-linux I've tested the patch
> works to suppress the warning with an aarch64-gnu-linux cross
> (where the bogus warning was reported).
>
> Martin
>
> gcc-97840.diff
>
> PR middle-end/97840 - Bogus -Wmaybe-uninitialized passing an empty object to a function
>
> gcc/ChangeLog:
> 	* tree-ssa-uninit.c (maybe_warn_operand): Call is_empty_type.
> 	* tree.c (default_is_empty_type): Rename...
> 	(is_empty_type): ...to this.
> 	* tree.h (is_empty_type): Declare.

OK

jeff
diff mbox series

Patch

PR middle-end/97840 - Bogus -Wmaybe-uninitialized passing an empty object to a function

gcc/ChangeLog:
	* tree-ssa-uninit.c (maybe_warn_operand): Call is_empty_type.
	* tree.c (default_is_empty_type): Rename...
	(is_empty_type): ...to this.
	* tree.h (is_empty_type): Declare.

diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index c94831bfb75..516a7bd2c99 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -404,10 +404,7 @@  maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
   tree rhstype = TREE_TYPE (rhs);
   if (POINTER_TYPE_P (rhstype))
     rhstype = TREE_TYPE (rhstype);
-  if (TYPE_EMPTY_P (rhstype)
-      || (RECORD_OR_UNION_TYPE_P (rhstype)
-	  && (!first_field (rhstype)
-	      || default_is_empty_record (rhstype))))
+  if (is_empty_type (rhstype))
     return NULL_TREE;
 
   bool warned = false;
diff --git a/gcc/tree.c b/gcc/tree.c
index 1ad4ad5a5f7..0fe9097bbbc 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -15136,22 +15136,22 @@  get_nonnull_args (const_tree fntype)
 /* Returns true if TYPE is a type where it and all of its subobjects
    (recursively) are of structure, union, or array type.  */
 
-static bool
-default_is_empty_type (tree type)
+bool
+is_empty_type (const_tree type)
 {
   if (RECORD_OR_UNION_TYPE_P (type))
     {
       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
 	if (TREE_CODE (field) == FIELD_DECL
 	    && !DECL_PADDING_P (field)
-	    && !default_is_empty_type (TREE_TYPE (field)))
+	    && !is_empty_type (TREE_TYPE (field)))
 	  return false;
       return true;
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     return (integer_minus_onep (array_type_nelts (type))
 	    || TYPE_DOMAIN (type) == NULL_TREE
-	    || default_is_empty_type (TREE_TYPE (type)));
+	    || is_empty_type (TREE_TYPE (type)));
   return false;
 }
 
@@ -15170,7 +15170,7 @@  default_is_empty_record (const_tree type)
   if (TREE_ADDRESSABLE (type))
     return false;
 
-  return default_is_empty_type (TYPE_MAIN_VARIANT (type));
+  return is_empty_type (TYPE_MAIN_VARIANT (type));
 }
 
 /* Determine whether TYPE is a structure with a flexible array member,
diff --git a/gcc/tree.h b/gcc/tree.h
index 9a713cdb0c7..5c0e3cc2e5a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -6233,6 +6233,7 @@  extern void gt_pch_nx (tree &);
 extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
 
 extern bool nonnull_arg_p (const_tree);
+extern bool is_empty_type (const_tree);
 extern bool default_is_empty_record (const_tree);
 extern bool flexible_array_type_p (const_tree);
 extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree);