<div dir="ltr"><div>... and in fact we also generate wrong code for this example with the sanitizers disabled -- we mark the reference parameter as dereferenceable(sizeof(A)) rather than dereferenceable(nvsize(A)). Oops!</div><div><br></div><div>Fixed in master.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 31 Jan 2020 at 09:54, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div>This looks like a bug to me; it looks like we're checking for the size of an A being available, but should only be checking for the nvsize since we don't know we have an object whose most-derived type is A.<br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 30 Jan 2020, 23:45 Alexey Sidorin via cfe-dev, <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  

    
  
  <div>
    <p>Hello everyone,</p>
    <p>The code example below triggers an undefined behavior sanitizer
      warning when compiled with -O1 and higher:</p>
    <p><tt>     1  struct Aux {</tt><tt><br>
      </tt><tt>     2    virtual ~Aux() = default;</tt><tt><br>
      </tt><tt>     3    int i = 0;</tt><tt><br>
      </tt><tt>     4  };</tt><tt><br>
      </tt><tt>     5</tt><tt><br>
      </tt><tt>     6  struct Base {</tt><tt><br>
      </tt><tt>     7    virtual ~Base() = default;</tt><tt><br>
      </tt><tt>     8  };</tt><tt><br>
      </tt><tt>     9</tt><tt><br>
      </tt><tt>    10  struct A : public virtual Base, public Aux {};</tt><tt><br>
      </tt><tt>    11</tt><tt><br>
      </tt><tt>    12  struct B final : public virtual A {};</tt><tt><br>
      </tt><tt>    13</tt><tt><br>
      </tt><tt>    14  void check(const A &a) {}</tt><tt><br>
      </tt><tt>    15</tt><tt><br>
      </tt><tt>    16  int main() {</tt><tt><br>
      </tt><tt>    17    B b;</tt><tt><br>
      </tt><tt>    18    check(b);</tt><tt> // UBSan warns here<br>
      </tt><tt>    19    return 0;</tt><tt><br>
      </tt><tt>    20  }</tt><br>
    </p>
    <p>When compiled with -fsanitize=undefined:</p>
    <p><tt>example.cpp:18:9: runtime error: reference binding to address
        0x7ffe652149c8 with insufficient space for an object of type
        'const A'</tt></p>
    <p>When compiled with -fsanitize=object-size:</p>
    <tt>example.cpp:12:8: runtime error: constructor call on address
      0x7ffc7988a2e0 with insufficient space for an object of type 'A'</tt><tt><br>
    </tt>
    <p><tt>example.cpp:18:9: runtime error: reference binding to address
        0x7ffc7988a2e0 with insufficient space for an object of type
        'const A'</tt></p>
    <p>Could someone tell if it is a sanitizer false positive or does
      this case actually contains a kind of UB? GCC doesn't give any
      warning for this code.<br>
    </p>
    <p><br>
    </p>
  </div>

_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div></div>
</blockquote></div></div>