On Wed, Jan 03, 2018 at 01:49:11PM +0100, Richard Biener wrote: > On January 3, 2018 1:21:40 PM GMT+01:00, Nathan Sidwell <nat...@acm.org> > wrote: > >On 01/02/2018 04:12 PM, Jakub Jelinek wrote: > >> Hi! > >> > >> This patch improves code generated for: > >> struct A { int a; }; > >> struct B { int b; }; > >> struct C : A, B { int c; }; > >> C *bar (B *b) { return &static_cast<C &>(*b); } > >> Unlike return static_cast<C *>(b); where b can be validly NULL, the > >> reference shouldn't bind to NULL, but we still emit > >> b ? b - 4 : 0. The following patch omits the non-NULL check except > >when > >> -fsanitize=null (or undefined) and when sanitizing makes sure such > >bugs are > >> diagnosed. > > > >It's sad the optimizers don't know REFERENCE_TYPE (x) means x != NULL. > >(or perhaps that's just a C++ semantic of REFERENCE_TYPE?). > > Given we treat reference and pointer types as interchangeable we indeed don't > know that.
Yeah, within functions that is quickly lost, sometimes even during folding as in this case. In some cases the optimizers can infer that, e.g. nonnull_arg_p has: /* Values passed by reference are always non-NULL. */ if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE && flag_delete_null_pointer_checks) return true; because we don't change randomly types of function arguments... Though, the above snippet reminds me I should probably also replace: + expr = build_base_path (MINUS_EXPR, expr, base, + /*nonnull=*/!sanitize_null_p, complain); with: + expr = build_base_path (MINUS_EXPR, expr, base, + /*nonnull=*/(!sanitize_null_p + && flag_delete_null_pointer_checks), + complain); Instead of checking for generated asm without sanitization, I think it will be easier/more portable to verify no conditionals in *.optimized dump. Let me repost the updated patch. Jakub