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

Reply via email to