We were hitting the assert in nonnull_arg_p that only wants to see POINTER_TYPE, but it got OFFSET_TYPE instead. Which is--in tree.def--described as "a pointer relative to an object". Thus I think we should allow OFFSET_TYPE here. In the attached testcase I demonstrated that this warning works even for OFFSET_TYPEs.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2015-12-02 Marek Polacek <pola...@redhat.com> PR c++/68653 * tree.c (nonnull_arg_p): Allow OFFSET_TYPE. * g++.dg/warn/nonnull3.C: New test. diff --git gcc/testsuite/g++.dg/warn/nonnull3.C gcc/testsuite/g++.dg/warn/nonnull3.C index e69de29..d82fa31 100644 --- gcc/testsuite/g++.dg/warn/nonnull3.C +++ gcc/testsuite/g++.dg/warn/nonnull3.C @@ -0,0 +1,19 @@ +// PR c++/68653 +// { dg-do compile { target c++11 } } +// { dg-options "-Wall" } + +struct B; +struct A { + template <typename T> __attribute__((nonnull)) bool foo (int T::*); + void bar (B *); +}; + +template <typename T> bool A::foo (int T::*p) +{ + return p; +} +void A::bar (B *) +{ + foo ((int B::*) nullptr); +} +// { dg-warning "nonnull argument" "" {target "*-*-*"} 0 } diff --git gcc/tree.c gcc/tree.c index 587bd74..bd5cf73 100644 --- gcc/tree.c +++ gcc/tree.c @@ -13848,7 +13848,9 @@ nonnull_arg_p (const_tree arg) tree t, attrs, fntype; unsigned HOST_WIDE_INT arg_num; - gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg))); + gcc_assert (TREE_CODE (arg) == PARM_DECL + && (POINTER_TYPE_P (TREE_TYPE (arg)) + || TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)); /* The static chain decl is always non null. */ if (arg == cfun->static_chain_decl) Marek