Bug 95485 - missing warning writing into function text
Summary: missing warning writing into function text
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 10.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: new-warning, new_warning
  Show dependency treegraph
 
Reported: 2020-06-02 20:14 UTC by Martin Sebor
Modified: 2022-01-26 17:55 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-06-02 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2020-06-02 20:14:42 UTC
GCC doesn't diagnose attempts to write into functions, even though those will in all likelihood crash with a SIGBUS at runtime.

For example, in the following snippet the destination of the memset call is a function rather than the memory it was called to obtain.  The memset call should be diagnosed.

$ cat z.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout z.c
typedef void* F (int);

void* f (F *p)
{
  void *q = p (32);              // allocate memory
  __builtin_memset (p, 0, 32);   // zero out -- whoops! -- writing to a function
  return q;                      // return "clear" memory
}

;; Function f (f, funcdef_no=0, decl_uid=1933, cgraph_uid=1, symbol_order=0)

f (void * (*<T322>) (int) p)
{
  void * q;

  <bb 2> [local count: 1073741824]:
  q_4 = p_2(D) (32);
  __builtin_memset (p_2(D), 0, 32);
  return q_4;

}


Two compilers on Godbolt diagnose the code: Visual C++:

z.c(8): warning C4152: nonstandard extension, function/data pointer conversion in expression

and the Small Device C Compiler (SDCC):

x.c:8: warning 244: pointer types incompatible 
from type 'void generic* function ( int fixed) code* fixed'
  to type 'void generic* fixed'
Comment 1 Martin Sebor 2020-06-02 20:21:46 UTC
See also pr90404.  I'm working on a solution for that, and I expect it to handle this as well.
Comment 2 Eric Gallager 2020-06-03 05:05:17 UTC
-Wpedantic catches it:

$ /usr/local/bin/gcc -c -O2 -S -Wall -Wextra -pedantic -fdump-tree-optimized=/dev/stdout 95485.c
95485.c: In function 'f':
95485.c:6:20: warning: ISO C forbids passing argument 1 of '__builtin_memset' between function pointer and 'void *' [-Wpedantic]
    6 |  __builtin_memset (p, 0, 32);   // zero out -- whoops! -- writing to a function
      |                    ^
95485.c:6:20: note: expected 'void *' but argument is of type 'void * (*)(int)'

;; Function f (f, funcdef_no=0, decl_uid=1910, cgraph_uid=1, symbol_order=0)

f (void * (*<T318>) (int) p)
{
  void * q;

  <bb 2> [local count: 1073741824]:
  q_4 = p_2(D) (32);
  __builtin_memset (p_2(D), 0, 32);
  return q_4;

}


$
Comment 3 Martin Sebor 2020-06-03 16:23:46 UTC
Ah, yes, -Wpedantic does detect the invalid conversion.  But few projects use -Wpedantic (GCC itself doesn't) and enabling the warning in -Wall or -Wextra would likely lead to lots of noise for code that converts between object and function pointers (POSIX requires it to work).

A warning implemented in a front end can also only detect questionable conversions but not the actual writes, which is what the warning I'm working on does (i.e., detect stores into read-only storage).
Comment 4 Eric Gallager 2022-01-04 06:51:55 UTC
(In reply to Martin Sebor from comment #3)
> Ah, yes, -Wpedantic does detect the invalid conversion.  But few projects
> use -Wpedantic (GCC itself doesn't) and enabling the warning in -Wall or
> -Wextra would likely lead to lots of noise for code that converts between
> object and function pointers (POSIX requires it to work).
> 
> A warning implemented in a front end can also only detect questionable
> conversions but not the actual writes, which is what the warning I'm working
> on does (i.e., detect stores into read-only storage).

so... you're suggesting a new flag, then?
Comment 5 Martin Sebor 2022-01-26 17:55:01 UTC
I'm not working on this anymore.