Bug 101358 - Warn when saving a pointer to an object with temporary lifetime
Summary: Warn when saving a pointer to an object with temporary lifetime
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 12.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: 2021-07-07 05:04 UTC by Joseph C. Sible
Modified: 2021-10-27 05:25 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-07-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph C. Sible 2021-07-07 05:04:05 UTC
Consider this C code:

typedef struct {
    int x[1];
} foo;

foo f(void);

int g(void) {
    int *p = f().x;
    return *p;
}

The g() function is always UB, since the return value of f() has temporary lifetime, so doing "return *p;" is dereferencing a pointer to an object whose lifetime has ended. (This is the case both before and after C11's change to temporary lifetime.) Since it's obvious at compile time that p can never be used safely, we should have a warning for it, similar to how we have -Wreturn-local-addr to catch mistakes like this function:

int *h(void) {
    int x;
    return &x;
}
Comment 1 Martin Sebor 2021-07-07 21:59:40 UTC
Confirmed as an enhancement request for the front end.  The Gimplifier introduces a local variable for the return value so the problem is no longer detectable:

$ cat pr101358.c && /build/gcc-master/gcc/xgcc -B /build/gcc-master/gcc -S -Wall -fdump-tree-original=/dev/stdout -fdump-tree-gimple=/dev/stdout pr101358.c
typedef struct {
    int x[1];
} foo;

foo f(void);

int g(void) {
    int *p = f().x;
    return *p;
}

;; Function g (null)
;; enabled by -tree-original


{
  int * p = (int *) &f ().x;

    int * p = (int *) &f ().x;
  return *p;
}

int g ()
{
  struct 
{
  int x[1];
} D.1952;
  int D.1953;
  int * p;

  D.1952 = f ();
  p = &D.1952.x;
  D.1953 = *p;
  return D.1953;
}