On 09/15/2015 02:32 AM, Mark Wielaard wrote:
On Mon, 2015-09-14 at 21:37 -0600, Martin Sebor wrote:
+void foo(void *bar) __attribute__((nonnull(1)));
+
+void foo(void *bar) { if (!bar) abort(); } /* { dg-warning "null" "argument ‘bar’ 
compared to NULL" } */
This looks like a very useful enhancement. Since the change is limited
to build_binary_op in the two front ends I wonder if the warning also
issued for other expressions? For example, suppose I were to add to
function foo above the following:

       bool is_null = bar;

would GCC issue a warning? The same question goes for other expressions
non-binary expressions, including:

       bar ? f () : g ();
Yes, it will:

nt.c: In function ‘tf’:
nt.c:9:3: warning: nonnull argument ‘bar’ compared to NULL [-Wnonnull]
    bool is_null = bar;
    ^

nt.c:14:7: warning: nonnull argument ‘bar’ compared to NULL [-Wnonnull]
    bar ? f () : g ();
        ^

or in C++:

       bool x = static_cast<bool>(bar);
Likewise for the g++ frontend:
Great!

nt.c: In function ‘bool tf(void*)’:
nt.c:12:18: warning: nonnull argument ‘bar’ compared to NULL [-Wnonnull]
    bool is_null = bar;
                   ^
nt.c:14:19: warning: nonnull argument ‘bar’ compared to NULL [-Wnonnull]
    bar ? f () : g ();
                    ^
IME, the C++ diagnostics aren't entirely consistent in where they
put the location but this one seems worse than I would expect. It
should point at bar.

OTOH, here are a couple of examples of the inconsistency, one with
the same problem as yours, so it's probably not something you did:

  $ cat t.c && g++ -c t.c
  int bar (void *p) {
      return p < 0.0 ? 0 : 1;
      struct A { } a;
      return a ? 0 : 1;
  }
  t.c: In function ‘int bar(void*)’:
t.c:2:16: error: invalid operands of types ‘void*’ and ‘double’ to binary ‘operator<’
       return p < 0.0 ? 0 : 1;
                  ^
  t.c:4:20: error: could not convert ‘a’ from ‘bar(void*)::A’ to ‘bool’
       return a ? 0 : 1;
                      ^

nt.c:16:33: warning: nonnull argument ‘bar’ compared to NULL [-Wnonnull]
    bool x = static_cast<bool>(bar);
                                  ^

Although I now notice they differ on the placement of the carrot.
Maybe the location passed into the warning is not correct/ideal?
I noticed the same problem in other g++ diagnostics. For instance,
in the messages below, the column is that of the closing parenthesis
rather than that of the operand:

  $ cat t.c && g++ -c t.c
  int foo (int, int);

  int bar (void *p) {
      foo (p, 0);
      return static_cast<int>(p);
  }
  t.c: In function ‘int bar(void*)’:
  t.c:4:14: error: invalid conversion from ‘void*’ to ‘int’ [-fpermissive]
       foo (p, 0);
                ^
  t.c:1:5: note:   initializing argument 1 of ‘int foo(int, int)’
   int foo (int, int);
       ^
  t.c:5:30: error: invalid static_cast from type ‘void*’ to type ‘int’
       return static_cast<int>(p);
                                ^

Martin

Reply via email to