[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-08-30 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

Jakub Jelinek  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED
   Target Milestone|--- |7.5

--- Comment #11 from Jakub Jelinek  ---
Fixed.

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-08-30 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

--- Comment #10 from Jakub Jelinek  ---
Author: jakub
Date: Fri Aug 30 12:34:19 2019
New Revision: 275145

URL: https://gcc.gnu.org/viewcvs?rev=275145=gcc=rev
Log:
Backported from mainline
2019-03-29  Jakub Jelinek  

PR sanitizer/89869
* typeck.c: Include gimplify.h.
(cp_build_modify_expr) : Unshare rhs before using it
for second time.  Formatting fixes.

* g++.dg/ubsan/vptr-14.C: New test.

Added:
branches/gcc-7-branch/gcc/testsuite/g++.dg/ubsan/vptr-14.C
Modified:
branches/gcc-7-branch/gcc/cp/ChangeLog
branches/gcc-7-branch/gcc/cp/typeck.c
branches/gcc-7-branch/gcc/testsuite/ChangeLog

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-05-01 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

Jakub Jelinek  changed:

   What|Removed |Added

  Known to work||8.3.1

--- Comment #9 from Jakub Jelinek  ---
Fixed for 8.4+ too.

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-04-30 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

--- Comment #8 from Jakub Jelinek  ---
Author: jakub
Date: Tue Apr 30 20:56:40 2019
New Revision: 270744

URL: https://gcc.gnu.org/viewcvs?rev=270744=gcc=rev
Log:
Backported from mainline
2019-03-29  Jakub Jelinek  

PR sanitizer/89869
* typeck.c: Include gimplify.h.
(cp_build_modify_expr) : Unshare rhs before using it
for second time.  Formatting fixes.

* g++.dg/ubsan/vptr-14.C: New test.

Added:
branches/gcc-8-branch/gcc/testsuite/g++.dg/ubsan/vptr-14.C
Modified:
branches/gcc-8-branch/gcc/cp/ChangeLog
branches/gcc-8-branch/gcc/cp/typeck.c
branches/gcc-8-branch/gcc/testsuite/ChangeLog

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-03-29 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

Jakub Jelinek  changed:

   What|Removed |Added

  Known to work||9.0
  Known to fail|9.0 |

--- Comment #7 from Jakub Jelinek  ---
Fixed for 9.1+ so far.

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-03-29 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

--- Comment #6 from Jakub Jelinek  ---
Author: jakub
Date: Fri Mar 29 20:10:19 2019
New Revision: 270024

URL: https://gcc.gnu.org/viewcvs?rev=270024=gcc=rev
Log:
PR sanitizer/89869
* typeck.c: Include gimplify.h.
(cp_build_modify_expr) : Unshare rhs before using it
for second time.  Formatting fixes.

* g++.dg/ubsan/vptr-14.C: New test.

Added:
trunk/gcc/testsuite/g++.dg/ubsan/vptr-14.C
Modified:
trunk/gcc/cp/ChangeLog
trunk/gcc/cp/typeck.c
trunk/gcc/testsuite/ChangeLog

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-03-29 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

--- Comment #5 from Jakub Jelinek  ---
Created attachment 46056
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46056=edit
gcc9-pr89869.patch

Untested fix.

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-03-29 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

--- Comment #4 from Jakub Jelinek  ---
The problem is that for the COND_EXPR as lvalue, cp_build_modify_expr does:
  /* Handle (a ? b : c) used as an "lvalue".  */
case COND_EXPR:
  {
/* Produce (a ? (b = rhs) : (c = rhs))
   except that the RHS goes through a save-expr
   so the code to compute it is only emitted once.  */

It uses stabilize_expr on the rhs, but this is before ubsan instrumentation, so
there is nothing to stabilize.
And then we emit:
cond = build_conditional_expr
  (input_location, TREE_OPERAND (lhs, 0),
   cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
 modifycode, rhs, complain),
   cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
 modifycode, rhs, complain),
   complain);
so rhs is a tree shared in two COND_EXPR branches.
And then we later instrument this and wrap in a SAVE_EXPR for VPTR
instrumentation.

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-03-29 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

--- Comment #3 from Jakub Jelinek  ---
If there is a SAVE_EXPR used in both arms of the conditional and not used
before that, then it is a bug in the generic code.

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-03-29 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

Martin Liška  changed:

   What|Removed |Added

   Keywords||wrong-code
   Priority|P3  |P1
 Status|ASSIGNED|NEW
  Known to fail||7.4.0, 8.3.0, 9.0

[Bug sanitizer/89869] -fsanitize=undefined miscompilation

2019-03-29 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89869

Martin Liška  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  ---
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(, 0);
  return 0;
}

UBSAN generates following original dump:

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

<, (long unsigned int) SAVE_EXPR
->_vptr.Object, 11320505648503524435, &_ZTI6Object, 3B);, SAVE_EXPR
;)->next != 0B)
{
  (void) (nul = (.UBSAN_VPTR (SAVE_EXPR , (long unsigned int)
SAVE_EXPR ->_vptr.Object, 11320505648503524435, &_ZTI6Object, 3B);,
SAVE_EXPR ;)->next);
}
  else
{
  (void) (child = (.UBSAN_VPTR (SAVE_EXPR , (long unsigned int)
SAVE_EXPR ->_vptr.Object, 11320505648503524435, &_ZTI6Object, 3B);,
SAVE_EXPR ;)->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 ; else goto ;
  :
  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 ;
  :
  _6 = child.1->_vptr.Object;
  _7 = (long unsigned int) _6;
  .UBSAN_VPTR (child.1, _7, 11320505648503524435, &_ZTI6Object, 3B);
  child = child.1->next;
  :
}

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