https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dodji at gcc dot gnu.org,
                   |                            |dvyukov at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org,
                   |                            |kcc at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
          Component|c++                         |sanitizer

--- Comment #2 from Martin Liška <marxin at gcc dot gnu.org> ---
Slightly reduced test-case:

$ cat pr89869.cc
struct Object
{
    Object* next = 0;
    virtual ~Object() {}
};

void unlinkChild(Object* child, Object *nul)
{
  ( child->next ? nul: child) = child->next;
}

int main( int argc, char** argv)
{
  Object a;
  unlinkChild(&a, 0);
  return 0;
}

UBSAN generates following original dump:

;; Function void unlinkChild(Object*, Object*) (null)

<<cleanup_point <<< Unknown tree: expr_stmt
  if ((.UBSAN_VPTR (SAVE_EXPR <child>, (long unsigned int) SAVE_EXPR
<child>->_vptr.Object, 11320505648503524435, &_ZTI6Object, 3B);, SAVE_EXPR
<child>;)->next != 0B)
    {
      (void) (nul = (.UBSAN_VPTR (SAVE_EXPR <child>, (long unsigned int)
SAVE_EXPR <child>->_vptr.Object, 11320505648503524435, &_ZTI6Object, 3B);,
SAVE_EXPR <child>;)->next);
    }
  else
    {
      (void) (child = (.UBSAN_VPTR (SAVE_EXPR <child>, (long unsigned int)
SAVE_EXPR <child>->_vptr.Object, 11320505648503524435, &_ZTI6Object, 3B);,
SAVE_EXPR <child>;)->next);
    } >>>>>;

which looks fine to me. However gimplification generates:

unlinkChild (struct Object * child, struct Object * nul)
{
  struct Object * child.0;
  struct Object * child.1;

  child.0 = child;
  _1 = child.0->_vptr.Object;
  _2 = (long unsigned int) _1;
  .UBSAN_VPTR (child.0, _2, 11320505648503524435, &_ZTI6Object, 3B);
  _3 = child.0->next;
  if (_3 != 0B) goto <D.2727>; else goto <D.2728>;
  <D.2727>:
  child.1 = child;
  _4 = child.1->_vptr.Object;
  _5 = (long unsigned int) _4;
  .UBSAN_VPTR (child.1, _5, 11320505648503524435, &_ZTI6Object, 3B);
  nul = child.1->next;
  goto <D.2730>;
  <D.2728>:
  _6 = child.1->_vptr.Object;
  _7 = (long unsigned int) _6;
  .UBSAN_VPTR (child.1, _7, 11320505648503524435, &_ZTI6Object, 3B);
  child = child.1->next;
  <D.2730>:
}

which is wrong because child.1 is used in <D.2728> uninitialized. Richi is it a
gimplification bug?
Or is the generic wrongly generated?

Reply via email to