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