On 2023-07-21 07:21, Martin Uecker via Gcc-patches wrote:


This patch adds a warning for allocations with insufficient size
based on the "alloc_size" attribute and the type of the pointer
the result is assigned to. While it is theoretically legal to
assign to the wrong pointer type and cast it to the right type
later, this almost always indicates an error. Since this catches
common mistakes and is simple to diagnose, it is suggested to
add this warning.
Bootstrapped and regression tested on x86.


Martin



Add option Walloc-type that warns about allocations that have
insufficient storage for the target type of the pointer the
storage is assigned to.

gcc:
        * doc/invoke.texi: Document -Wstrict-flex-arrays option.

gcc/c-family:

        * c.opt (Walloc-type): New option.

gcc/c:
        * c-typeck.cc (convert_for_assignment): Add Walloc-type warning.

gcc/testsuite:

        * gcc.dg/Walloc-type-1.c: New test.


diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 4abdc8d0e77..8b9d148582b 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -319,6 +319,10 @@ Walloca
  C ObjC C++ ObjC++ Var(warn_alloca) Warning
  Warn on any use of alloca.
+Walloc-type
+C ObjC Var(warn_alloc_type) Warning
+Warn when allocating insufficient storage for the target type of the
assigned pointer.
+
  Walloc-size-larger-than=
  C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Joined Host_Wide_Int
ByteSize Warning Init(HOST_WIDE_INT_MAX)
  -Walloc-size-larger-than=<bytes>        Warn for calls to allocation
functions that
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 7cf411155c6..2e392f9c952 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -7343,6 +7343,32 @@ convert_for_assignment (location_t location,
location_t expr_loc, tree type,
                    "request for implicit conversion "
                    "from %qT to %qT not permitted in C++", rhstype,
type);
+ /* Warn of new allocations are not big enough for the target
type.  */
+      tree fndecl;
+      if (warn_alloc_type
+         && TREE_CODE (rhs) == CALL_EXPR
+         && (fndecl = get_callee_fndecl (rhs)) != NULL_TREE
+         && DECL_IS_MALLOC (fndecl))
+       {
+         tree fntype = TREE_TYPE (fndecl);
+         tree fntypeattrs = TYPE_ATTRIBUTES (fntype);
+         tree alloc_size = lookup_attribute ("alloc_size",
fntypeattrs);
+         if (alloc_size)
+           {
+             tree args = TREE_VALUE (alloc_size);
+             int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
+             /* For calloc only use the second argument.  */
+             if (TREE_CHAIN (args))
+               idx = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN
(args))) - 1;
+             tree arg = CALL_EXPR_ARG (rhs, idx);
+             if (TREE_CODE (arg) == INTEGER_CST
+                 && tree_int_cst_lt (arg, TYPE_SIZE_UNIT (ttl)))
+                warning_at (location, OPT_Walloc_type, "allocation of
"
+                            "insufficient size %qE for type %qT with
"
+                            "size %qE", arg, ttl, TYPE_SIZE_UNIT
(ttl));
+           }
+       }
+

Wouldn't this be much more useful in later phases with ranger feedback like with the warn_access warnings? That way the comparison won't be limited to constant sizes.

Thanks,
Sid

Reply via email to