Bug 56373 - -Wzero-as-null-pointer-constant: does not catch issues with smart pointers
Summary: -Wzero-as-null-pointer-constant: does not catch issues with smart pointers
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.0
: P3 minor
Target Milestone: 4.8.0
Assignee: Paolo Carlini
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-02-18 11:35 UTC by Akim Demaille
Modified: 2013-02-20 09:03 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-02-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Akim Demaille 2013-02-18 11:35:26 UTC
Hi all,

Sorry if this report is bogus.  I would expect GCC to complain about the following uses of 0 instead of nullptr, but it does not.

$ cat foo.cc
#include <memory>
struct foo {};

int main ()
{
  std::shared_ptr<foo> a = 0;
  std::shared_ptr<foo> b(0);
  std::shared_ptr<foo> c{0};
  foo *d = 0;
}
$ g++-mp-4.8 -std=c++11 -Wall -Wzero-as-null-pointer-constant /tmp/foo.cc 
/tmp/foo.cc: In function 'int main()':
/tmp/foo.cc:9:12: warning: zero as null pointer constant [-Wzero-as-null-pointer-constant]
   foo *d = 0;
            ^
/tmp/foo.cc:9:8: warning: unused variable 'd' [-Wunused-variable]
   foo *d = 0;
        ^
$ g++-mp-4.8  --version
g++-mp-4.8 (MacPorts gcc48 4.8-20130210_0) 4.8.0 20130210 (experimental)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

It's also a bit sad that only d is diagnosed as useless, although I do
understand that the shared_ptr has a constructor and a destructor that use
it.

Cheers!
Comment 1 Jonathan Wakely 2013-02-18 12:07:49 UTC
The warning isn't issued when 0 converts to std::nullptr_t, only when it converts to a pointer type.

struct shared_ptr
{
    shared_ptr(decltype(nullptr)) { }
    ~shared_ptr() { }
};

int main ()
{
  shared_ptr a = 0;
  shared_ptr b(0);
  shared_ptr c{0};
}


(In reply to comment #0)
> It's also a bit sad that only d is diagnosed as useless, although I do
> understand that the shared_ptr has a constructor and a destructor that use
> it.

It's necessary, because otherwise you get bogus warnings from ScopeGuard-style RAII types.
Comment 2 Akim Demaille 2013-02-18 12:52:46 UTC
Thanks a lot for the detailed answer.

> The warning isn't issued when 0 converts to std::nullptr_t, only when it
> converts to a pointer type.

And shouldn't it?

>> It's also a bit sad that only d is diagnosed as useless, although I do
>> understand that the shared_ptr has a constructor and a destructor that use
>> it.

> It's necessary, because otherwise you get bogus warnings from ScopeGuard-style
> RAII types.

In which case the constructor and destructor would be meaningful,
which is not the case here.  But again, thanks for explaining!
Comment 3 Jonathan Wakely 2013-02-18 13:20:41 UTC
(In reply to comment #2)
> > It's necessary, because otherwise you get bogus warnings from ScopeGuard-style
> > RAII types.
> 
> In which case the constructor and destructor would be meaningful,
> which is not the case here.

~shared_ptr() has non-trivial side-effects, the compiler isn't smart enough to determine they won't fire when its empty, so it's always meaningful.

If you're smart enough to know the object isn't used then don't create it :)
Comment 4 Akim Demaille 2013-02-18 13:23:08 UTC
> If you're smart enough to know the object isn't used then don't create it :)

:) :) :)

> ~shared_ptr() has non-trivial side-effects, the compiler isn't smart enough to
> determine they won't fire when its empty, so it's always meaningful.

I had in mind providing the library authors with an attribute that would
help them influence this diagnostic.
Comment 5 Paolo Carlini 2013-02-18 16:05:40 UTC
So confirming the first issue. I have a simple patch in testing for it.

About the second issue, it was definitely discussed somewhere else too: there is always a tension between consistently treating in a similar way elementary types and classes and avoiding warning for common patterns like RAII.
Comment 6 paolo@gcc.gnu.org 2013-02-20 09:02:41 UTC
Author: paolo
Date: Wed Feb 20 09:02:35 2013
New Revision: 196165

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196165
Log:
/cp
2013-02-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/56373
	* tree.c (maybe_warn_zero_as_null_pointer_constant): Add.
	* cvt.c (ocp_convert): Use the latter.
	(cp_convert_to_pointer): Likewise.
	* decl.c (check_default_argument): Likewise.
	* typeck.c (cp_build_binary_op): Likewise.
	* cp-tree.h (maybe_warn_zero_as_null_pointer_constant): Declare.

/testsuite
2013-02-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/56373
	* g++.dg/cpp0x/Wzero-as-null-pointer-constant-2.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-2.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/cvt.c
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/tree.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/ChangeLog
Comment 7 Paolo Carlini 2013-02-20 09:03:47 UTC
Done.