Bug 24786 - Missing warning on questionable use of parameter to initialize static
Summary: Missing warning on questionable use of parameter to initialize static
Status: RESOLVED DUPLICATE of bug 69433
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 6.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, missed-optimization
Depends on:
Blocks: Wreturn-local-addr
  Show dependency treegraph
 
Reported: 2005-11-11 06:28 UTC by dank
Modified: 2020-05-20 21:59 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-05-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dank 2005-11-11 06:28:13 UTC
gcc only warns on blah1 on the following code:

const char *blah1() {
   char x = 7;
   return &x;
}

const char *blah2() {
   char x = 7;
   static const char *names[1] = { &x }; 
   return names[0];
}

returnlocal.cc: In function 'const char* blah1()':
returnlocal.cc:2: warning: address of local variable 'x' returned

Shouldn't it warn on blah2 as well?
Or is that asking too much?
Comment 1 Andrew Pinski 2005-11-11 15:11:14 UTC
Warning on blah2 means moving this warning to the middle-end and down to the end of the optimization passes, maybe way to hard and then you get inconstaint warnings at different optimization levels.
Comment 2 Andrew Pinski 2005-11-11 17:59:15 UTC
Actually we should be able to warn about this as " = { &x }; " is only ran once, the first time the blah2 is called.
Comment 3 Manuel López-Ibáñez 2015-09-18 00:40:37 UTC
GCC generates code like this:

const char *names[1];
const char *blah2() {
   char x = 7;
    if (first_time)
       names[0] = { &x }; 
   return names[0];
}

and we end up returning:

  # .MEM_1 = PHI <.MEM_4(2), .MEM_9(4), .MEM_6(3)>
  [test.c:5:17] # VUSE <.MEM_1>
  # PT = nonlocal escaped { D.2254 } (escaped)
  _10 = [test.c:5:17] _ZZ5blah2vE5namesD.2255[0];
  # .MEM_11 = VDEF <.MEM_1>
  xD.2254 ={v} {CLOBBER};
  [test.c:5:17] # VUSE <.MEM_11>
  return _10;
;;    succ:       EXIT [100.0%]

While in the non-static case we propagate &x:

;;   basic block 2, loop depth 0, count 0, freq 10000, maybe hot
;;    prev block 0, next block 1, flags: (NEW, REACHABLE)
;;    pred:       ENTRY [100.0%]  (FALLTHRU,EXECUTABLE)
;;   starting at line 5
  # .MEM_2 = VDEF <.MEM_1(D)>
  xD.2254 ={v} {CLOBBER};
  [test.c:5:17] # VUSE <.MEM_2>
  return &xD.2254;
;;    succ:       EXIT [100.0%]


This seems like a missed optimization.

Somehow related to PR60517.
Comment 4 Martin Sebor 2020-05-19 19:56:07 UTC
Reconfirming that a warning for this and other similar cases (e.g., pr82520 and pr69433) would be valuable.
Comment 5 dank 2020-05-19 20:14:44 UTC
Methinks it's been fixed:

$ gcc --version
gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0

$ gcc -c blah.c
blah.c: In function ‘blah1’:
blah.c:3:11: warning: function returns address of local variable [-Wreturn-local-addr]
    3 |    return &x;
      |           ^~
blah.c: In function ‘blah2’:
blah.c:8:36: error: initializer element is not constant
    8 |    static const char *names[1] = { &x };
      |                                    ^
blah.c:8:36: note: (near initialization for ‘names[0]’)

Also fixed with:

gcc-6 (Ubuntu 6.5.0-2ubuntu1) 6.5.0 20181026

Marking fixed.

But see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69433
Comment 6 Martin Sebor 2020-05-19 21:13:23 UTC
Not fixed yet.  There is no warning for blah2() returning the address of the local variable.  pr69433 includes a test case for the same thing:

  const char* f2 () {
    const char a[] = "abc";
    static const char *s = a;
    return s;
  }

so this report can be resolved as a duplicate of that one.

*** This bug has been marked as a duplicate of bug 69433 ***