Bug 38509 - Bogus "attempt to free a non-heap object" warning
Summary: Bogus "attempt to free a non-heap object" warning
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P3 minor
Target Milestone: 4.7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2008-12-12 22:36 UTC by Rubidium
Modified: 2011-08-23 19:27 UTC (History)
3 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rubidium 2008-12-12 22:36:34 UTC
class TestCase {
private:
  const int *pointer;

public:
  TestCase() {
    static int non_heap = 0;
    this->pointer = &non_heap;
  }

  ~TestCase() {
    if (*this->pointer != 0) __builtin_free(const_cast<int *>(this->pointer));
  }
};

int main(int argc, const char *argv[]) {
 TestCase test;
 return 0;
}

/*

The code above, compiled g++ 4.4.0 with -O1 (or any -On except -O0) gives the following warning:
test.cpp: In function ‘int main(int, const char**)’:
test.cpp:12: warning: attempt to free a non-heap object ‘non_heap’

In this case the warning is bogus because the "free" can never be reached.

Complete command line:
g++ -O1 -o test test.cpp

Output from "g++ -v -O1 -o test test.cpp":
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --with-arch=pentium-m --enable-threads --enable-languages=c,c++
Thread model: posix
gcc version 4.4.0 20081210 (experimental) (GCC)
COLLECT_GCC_OPTIONS='-v' '-O1' '-o' 'test' '-shared-libgcc' '-mtune=generic' '-march=pentium-m'
 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.4.0/cc1plus -quiet -v -D_GNU_SOURCE test.cpp -quiet -dumpbase test.cpp -mtune=generic -march=pentium-m -auxbase test -O1 -version -o /tmp/ccIffeq5.s
ignoring nonexistent directory "/usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../../include/c++/4.4.0
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../../include/c++/4.4.0/i686-pc-linux-gnu
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../../include/c++/4.4.0/backward
 /usr/local/include
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/include
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/include-fixed
 /usr/include
End of search list.
GNU C++ (GCC) version 4.4.0 20081210 (experimental) (i686-pc-linux-gnu)
        compiled by GNU C version 4.4.0 20081210 (experimental), GMP version 4.2.2, MPFR version 2.3.2.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: b043f60097b3fa3e759e89265ea8ebdb
test.cpp: In function ‘int main(int, const char**)’:
test.cpp:12: warning: attempt to free a non-heap object ‘non_heap’
COLLECT_GCC_OPTIONS='-v' '-O1' '-o' 'test' '-shared-libgcc' '-mtune=generic' '-march=pentium-m'
 as -V -Qy -o /tmp/ccshvEr5.o /tmp/ccIffeq5.s
GNU assembler version 2.18.0 (i486-linux-gnu) using BFD version (GNU Binutils for Debian) 2.18.0.20080103
COMPILER_PATH=/usr/local/libexec/gcc/i686-pc-linux-gnu/4.4.0/:/usr/local/libexec/gcc/i686-pc-linux-gnu/4.4.0/:/usr/local/libexec/gcc/i686-pc-linux-gnu/:/usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/local/lib/gcc/i686-pc-linux-gnu/
LIBRARY_PATH=/usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-O1' '-o' 'test' '-shared-libgcc' '-mtune=generic' '-march=pentium-m'
 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.4.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/crtbegin.o -L/usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0 -L/usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/../../.. /tmp/ccshvEr5.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/lib/gcc/i686-pc-linux-gnu/4.4.0/crtend.o /usr/lib/crtn.o


Note: this is a self-compiled binary of SVN revision 142654.
*/
Comment 1 Andrew Pinski 2008-12-12 22:42:00 UTC
  static int non_heap = 0;

<bb 2>:
  if (non_heap != 0)
    goto <bb 3>;
  else
    goto <bb 4>;

<bb 3>:
  __builtin_free (&non_heap);

Hmm, since the address of non_heap is taken, we don't optimize away the conditional.
Comment 2 Rubidium 2009-07-25 23:28:52 UTC
Is there a way to disable this warning?

I've searched the manual and gcc -v --help for 'heap' and 'free'. Neither keyword showed any promising compiler flags.

I've also looked in the code, but I cannot find a variable (like warn_parentheses) that enables/disables the warning.
Comment 3 Andrew Pinski 2009-07-25 23:32:10 UTC
This case needs the compiler needs to know that TestCase::TestCase():: non_heap cannot change value.
Comment 4 Mark Heffernan 2011-08-23 18:06:48 UTC
Author: meheff
Date: Tue Aug 23 18:06:42 2011
New Revision: 178004

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=178004
Log:
2011-08-23  Mark Heffernan  <meheff@google.com>

        PR middle-end/38509
        * common.opt (Wfree-nonheap-object): New option.
        * doc/invoke.texi (Warning options): Document -Wfree-nonheap-object.
        * builtins.c (maybe_emit_free_warning): Add OPT_Wfree_nonheap_object
        to warning.
        (expand_builtin): Make warning conditional.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/builtins.c
    trunk/gcc/common.opt
    trunk/gcc/doc/invoke.texi
Comment 5 Mark Heffernan 2011-08-23 19:27:18 UTC
With patch, warning is controllable with -Wfree-nonheap-object.