[Bug sanitizer/89869] -fsanitize=undefined miscompilation
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
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
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
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
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
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
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
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
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
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
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?