Hi, This patch teaches the C++ frontend to warn on NULL checks against inline functions and it teaches the middle-end to fold NULL checks against inline functions. These two things are currently done for non-inline C++ functions, but inline functions are exceptional in that the C++ frontend marks them as weak, and NULL checks against weak symbols cannot be folded in general because the symbol may be mapped to NULL at link-time.
But in the case of an inline function, the fact that it's a weak symbol is an implementation detail. And because it is not permitted to explicitly give an inline function the "weak" attribute (see handle_weak_attribute), in order to acheive $SUBJECT it suffices to assume that all inline functions are non-null, which is what this patch does. Bootstrap and regtest against x86_64-unknown-linux-gnu in progress. Is this patch OK assuming no regressions? 2014-05-26 Patrick Palka <patr...@parcs.ath.cx> * c-family/c-common.c (decl_with_nonnull_addr_p): Assume inline functions are non-null. * fold-const.c (tree_single_nonzero_warnv_p): Likewise. --- gcc/c-family/c-common.c | 4 +++- gcc/fold-const.c | 5 ++++- gcc/testsuite/g++.dg/inline-1.C | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inline-1.C diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 6ec14fc..d4747a0 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -4508,7 +4508,9 @@ decl_with_nonnull_addr_p (const_tree expr) return (DECL_P (expr) && (TREE_CODE (expr) == PARM_DECL || TREE_CODE (expr) == LABEL_DECL - || !DECL_WEAK (expr))); + || !DECL_WEAK (expr) + || (TREE_CODE (expr) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (expr)))); } /* Prepare expr to be an argument of a TRUTH_NOT_EXPR, diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 188b179..2796079 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -16052,7 +16052,10 @@ tree_single_nonzero_warnv_p (tree t, bool *strict_overflow_p) || (DECL_CONTEXT (base) && TREE_CODE (DECL_CONTEXT (base)) == FUNCTION_DECL && auto_var_in_fn_p (base, DECL_CONTEXT (base))))) - return !VAR_OR_FUNCTION_DECL_P (base) || !DECL_WEAK (base); + return !VAR_OR_FUNCTION_DECL_P (base) + || !DECL_WEAK (base) + || (TREE_CODE (base) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (base)); /* Constants are never weak. */ if (CONSTANT_CLASS_P (base)) diff --git a/gcc/testsuite/g++.dg/inline-1.C b/gcc/testsuite/g++.dg/inline-1.C new file mode 100644 index 0000000..65beff1 --- /dev/null +++ b/gcc/testsuite/g++.dg/inline-1.C @@ -0,0 +1,14 @@ +// { dg-options "-Waddress" } + +inline void +foo (void) +{ +} + +int +bar (void) +{ + return foo == 0; // { dg-warning "never be NULL" } +} + +// { dg-final { scan-assembler-not "foo" } } -- 2.0.0.rc2