On Mon, May 26, 2014 at 9:01 PM, Patrick Palka <patr...@parcs.ath.cx> wrote: > 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?
What about always_inline function wrappers as used in FORTIFY_SOURCE? IIRC the actual referenced function may be declared weak and thus the address can compare to NULL? Sth like extern void __foo (void) __attribute__((weak,asm("foo"))); extern inline __attribute__((always_inline,gnu_inline)) void foo (void) { __foo (); } int main() { if (foo == 0) return 0; abort (); } The issue is that the inline and alias may be hidden to the user and thus he'll get unwanted and confusing warnings. Richard. > 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 >