Mercurial > hg > CbC > CbC_gcc
comparison gcc/ubsan.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* UndefinedBehaviorSanitizer, undefined behavior detector. | 1 /* UndefinedBehaviorSanitizer, undefined behavior detector. |
2 Copyright (C) 2013-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2013-2018 Free Software Foundation, Inc. |
3 Contributed by Marek Polacek <polacek@redhat.com> | 3 Contributed by Marek Polacek <polacek@redhat.com> |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
434 tree dom = TYPE_DOMAIN (t); | 434 tree dom = TYPE_DOMAIN (t); |
435 if (dom != NULL_TREE | 435 if (dom != NULL_TREE |
436 && TYPE_MAX_VALUE (dom) != NULL_TREE | 436 && TYPE_MAX_VALUE (dom) != NULL_TREE |
437 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST) | 437 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST) |
438 { | 438 { |
439 unsigned HOST_WIDE_INT m; | |
439 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom)) | 440 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom)) |
440 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0) | 441 && (m = tree_to_uhwi (TYPE_MAX_VALUE (dom))) + 1 != 0) |
441 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC, | 442 pp_unsigned_wide_integer (&pretty_name, m + 1); |
442 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1); | |
443 else | 443 else |
444 pp_wide_int (&pretty_name, | 444 pp_wide_int (&pretty_name, |
445 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1), | 445 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1), |
446 TYPE_SIGN (TREE_TYPE (dom))); | 446 TYPE_SIGN (TREE_TYPE (dom))); |
447 } | 447 } |
661 | 661 |
662 bool | 662 bool |
663 is_ubsan_builtin_p (tree t) | 663 is_ubsan_builtin_p (tree t) |
664 { | 664 { |
665 return TREE_CODE (t) == FUNCTION_DECL | 665 return TREE_CODE (t) == FUNCTION_DECL |
666 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL | 666 && fndecl_built_in_p (t, BUILT_IN_NORMAL) |
667 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), | 667 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), |
668 "__builtin___ubsan_", 18) == 0; | 668 "__builtin___ubsan_", 18) == 0; |
669 } | 669 } |
670 | 670 |
671 /* Create a callgraph edge for statement STMT. */ | 671 /* Create a callgraph edge for statement STMT. */ |
673 static void | 673 static void |
674 ubsan_create_edge (gimple *stmt) | 674 ubsan_create_edge (gimple *stmt) |
675 { | 675 { |
676 gcall *call_stmt = dyn_cast <gcall *> (stmt); | 676 gcall *call_stmt = dyn_cast <gcall *> (stmt); |
677 basic_block bb = gimple_bb (stmt); | 677 basic_block bb = gimple_bb (stmt); |
678 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); | |
679 cgraph_node *node = cgraph_node::get (current_function_decl); | 678 cgraph_node *node = cgraph_node::get (current_function_decl); |
680 tree decl = gimple_call_fndecl (call_stmt); | 679 tree decl = gimple_call_fndecl (call_stmt); |
681 if (decl) | 680 if (decl) |
682 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count, | 681 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count); |
683 freq); | |
684 } | 682 } |
685 | 683 |
686 /* Expand the UBSAN_BOUNDS special builtin function. */ | 684 /* Expand the UBSAN_BOUNDS special builtin function. */ |
687 | 685 |
688 bool | 686 bool |
802 | 800 |
803 /* Make an edge coming from the 'cond block' into the 'then block'; | 801 /* Make an edge coming from the 'cond block' into the 'then block'; |
804 this edge is unlikely taken, so set up the probability accordingly. */ | 802 this edge is unlikely taken, so set up the probability accordingly. */ |
805 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); | 803 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); |
806 e->probability = profile_probability::very_unlikely (); | 804 e->probability = profile_probability::very_unlikely (); |
805 then_bb->count = e->count (); | |
807 | 806 |
808 /* Connect 'then block' with the 'else block'. This is needed | 807 /* Connect 'then block' with the 'else block'. This is needed |
809 as the ubsan routines we call in the 'then block' are not noreturn. | 808 as the ubsan routines we call in the 'then block' are not noreturn. |
810 The 'then block' only has one outcoming edge. */ | 809 The 'then block' only has one outcoming edge. */ |
811 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU); | 810 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU); |
1083 /* Make an edge coming from the 'cond block' into the 'then block'; | 1082 /* Make an edge coming from the 'cond block' into the 'then block'; |
1084 this edge is unlikely taken, so set up the probability | 1083 this edge is unlikely taken, so set up the probability |
1085 accordingly. */ | 1084 accordingly. */ |
1086 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); | 1085 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); |
1087 e->probability = profile_probability::very_unlikely (); | 1086 e->probability = profile_probability::very_unlikely (); |
1087 then_bb->count = e->count (); | |
1088 } | 1088 } |
1089 else | 1089 else |
1090 { | 1090 { |
1091 e->probability = profile_probability::even (); | 1091 e->probability = profile_probability::even (); |
1092 | 1092 |
1096 e->probability = profile_probability::very_likely (); | 1096 e->probability = profile_probability::very_likely (); |
1097 e->flags = EDGE_FALSE_VALUE; | 1097 e->flags = EDGE_FALSE_VALUE; |
1098 | 1098 |
1099 e = make_edge (cond_neg_bb, then_bb, EDGE_TRUE_VALUE); | 1099 e = make_edge (cond_neg_bb, then_bb, EDGE_TRUE_VALUE); |
1100 e->probability = profile_probability::very_unlikely (); | 1100 e->probability = profile_probability::very_unlikely (); |
1101 then_bb->count = e->count (); | |
1101 | 1102 |
1102 cond_pos_bb = create_empty_bb (cond_bb); | 1103 cond_pos_bb = create_empty_bb (cond_bb); |
1103 add_bb_to_loop (cond_pos_bb, cond_bb->loop_father); | 1104 add_bb_to_loop (cond_pos_bb, cond_bb->loop_father); |
1104 | 1105 |
1105 e = make_edge (cond_bb, cond_pos_bb, EDGE_TRUE_VALUE); | 1106 e = make_edge (cond_bb, cond_pos_bb, EDGE_TRUE_VALUE); |
1106 e->probability = profile_probability::even (); | 1107 e->probability = profile_probability::even (); |
1108 cond_pos_bb->count = e->count (); | |
1107 | 1109 |
1108 e = make_edge (cond_pos_bb, then_bb, EDGE_TRUE_VALUE); | 1110 e = make_edge (cond_pos_bb, then_bb, EDGE_TRUE_VALUE); |
1109 e->probability = profile_probability::very_unlikely (); | 1111 e->probability = profile_probability::very_unlikely (); |
1110 | 1112 |
1111 e = make_edge (cond_pos_bb, fallthru_bb, EDGE_FALSE_VALUE); | 1113 e = make_edge (cond_pos_bb, fallthru_bb, EDGE_FALSE_VALUE); |
1421 t = TREE_OPERAND (t, 0); | 1423 t = TREE_OPERAND (t, 0); |
1422 | 1424 |
1423 if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF) | 1425 if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF) |
1424 return; | 1426 return; |
1425 | 1427 |
1426 HOST_WIDE_INT bitsize, bitpos, bytepos; | 1428 poly_int64 bitsize, bitpos, bytepos; |
1427 tree offset; | 1429 tree offset; |
1428 machine_mode mode; | 1430 machine_mode mode; |
1429 int volatilep = 0, reversep, unsignedp = 0; | 1431 int volatilep = 0, reversep, unsignedp = 0; |
1430 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode, | 1432 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode, |
1431 &unsignedp, &reversep, &volatilep); | 1433 &unsignedp, &reversep, &volatilep); |
1439 return; | 1441 return; |
1440 base = inner; | 1442 base = inner; |
1441 /* If BASE is a fixed size automatic variable or | 1443 /* If BASE is a fixed size automatic variable or |
1442 global variable defined in the current TU and bitpos | 1444 global variable defined in the current TU and bitpos |
1443 fits, don't instrument anything. */ | 1445 fits, don't instrument anything. */ |
1446 poly_int64 base_size; | |
1444 if (offset == NULL_TREE | 1447 if (offset == NULL_TREE |
1445 && bitpos > 0 | 1448 && maybe_ne (bitpos, 0) |
1446 && (VAR_P (base) | 1449 && (VAR_P (base) |
1447 || TREE_CODE (base) == PARM_DECL | 1450 || TREE_CODE (base) == PARM_DECL |
1448 || TREE_CODE (base) == RESULT_DECL) | 1451 || TREE_CODE (base) == RESULT_DECL) |
1449 && DECL_SIZE (base) | 1452 && poly_int_tree_p (DECL_SIZE (base), &base_size) |
1450 && TREE_CODE (DECL_SIZE (base)) == INTEGER_CST | 1453 && known_ge (base_size, bitpos) |
1451 && compare_tree_int (DECL_SIZE (base), bitpos) >= 0 | |
1452 && (!is_global_var (base) || decl_binds_to_current_def_p (base))) | 1454 && (!is_global_var (base) || decl_binds_to_current_def_p (base))) |
1453 return; | 1455 return; |
1454 } | 1456 } |
1455 else if (TREE_CODE (inner) == MEM_REF) | 1457 else if (TREE_CODE (inner) == MEM_REF) |
1456 { | 1458 { |
1467 else | 1469 else |
1468 return; | 1470 return; |
1469 | 1471 |
1470 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base)) | 1472 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base)) |
1471 return; | 1473 return; |
1472 bytepos = bitpos / BITS_PER_UNIT; | 1474 bytepos = bits_to_bytes_round_down (bitpos); |
1473 if (offset == NULL_TREE && bytepos == 0 && moff == NULL_TREE) | 1475 if (offset == NULL_TREE && known_eq (bytepos, 0) && moff == NULL_TREE) |
1474 return; | 1476 return; |
1475 | 1477 |
1476 tree base_addr = base; | 1478 tree base_addr = base; |
1477 if (decl_p) | 1479 if (decl_p) |
1478 base_addr = build1 (ADDR_EXPR, | 1480 base_addr = build1 (ADDR_EXPR, |
1479 build_pointer_type (TREE_TYPE (base)), base); | 1481 build_pointer_type (TREE_TYPE (base)), base); |
1480 t = offset; | 1482 t = offset; |
1481 if (bytepos) | 1483 if (maybe_ne (bytepos, 0)) |
1482 { | 1484 { |
1483 if (t) | 1485 if (t) |
1484 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t, | 1486 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t, |
1485 build_int_cst (TREE_TYPE (t), bytepos)); | 1487 build_int_cst (TREE_TYPE (t), bytepos)); |
1486 else | 1488 else |
1575 | 1577 |
1576 /* If this is not a signed operation, don't instrument anything here. | 1578 /* If this is not a signed operation, don't instrument anything here. |
1577 Also punt on bit-fields. */ | 1579 Also punt on bit-fields. */ |
1578 if (!INTEGRAL_TYPE_P (lhsinner) | 1580 if (!INTEGRAL_TYPE_P (lhsinner) |
1579 || TYPE_OVERFLOW_WRAPS (lhsinner) | 1581 || TYPE_OVERFLOW_WRAPS (lhsinner) |
1580 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner)) | 1582 || maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner)), |
1583 TYPE_PRECISION (lhsinner))) | |
1581 return; | 1584 return; |
1582 | 1585 |
1583 switch (code) | 1586 switch (code) |
1584 { | 1587 { |
1585 case MINUS_EXPR: | 1588 case MINUS_EXPR: |
1659 } | 1662 } |
1660 else | 1663 else |
1661 return; | 1664 return; |
1662 | 1665 |
1663 int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type)); | 1666 int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type)); |
1664 HOST_WIDE_INT bitsize, bitpos; | 1667 poly_int64 bitsize, bitpos; |
1665 tree offset; | 1668 tree offset; |
1666 machine_mode mode; | 1669 machine_mode mode; |
1667 int volatilep = 0, reversep, unsignedp = 0; | 1670 int volatilep = 0, reversep, unsignedp = 0; |
1668 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode, | 1671 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode, |
1669 &unsignedp, &reversep, &volatilep); | 1672 &unsignedp, &reversep, &volatilep); |
1670 tree utype = build_nonstandard_integer_type (modebitsize, 1); | 1673 tree utype = build_nonstandard_integer_type (modebitsize, 1); |
1671 | 1674 |
1672 if ((VAR_P (base) && DECL_HARD_REGISTER (base)) | 1675 if ((VAR_P (base) && DECL_HARD_REGISTER (base)) |
1673 || (bitpos % modebitsize) != 0 | 1676 || !multiple_p (bitpos, modebitsize) |
1674 || bitsize != modebitsize | 1677 || maybe_ne (bitsize, modebitsize) |
1675 || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize | 1678 || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize |
1676 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) | 1679 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) |
1677 return; | 1680 return; |
1678 | 1681 |
1679 bool ends_bb = stmt_ends_bb_p (stmt); | 1682 bool ends_bb = stmt_ends_bb_p (stmt); |
2081 | 2084 |
2082 size_in_bytes = int_size_in_bytes (type); | 2085 size_in_bytes = int_size_in_bytes (type); |
2083 if (size_in_bytes <= 0) | 2086 if (size_in_bytes <= 0) |
2084 return; | 2087 return; |
2085 | 2088 |
2086 HOST_WIDE_INT bitsize, bitpos; | 2089 poly_int64 bitsize, bitpos; |
2087 tree offset; | 2090 tree offset; |
2088 machine_mode mode; | 2091 machine_mode mode; |
2089 int volatilep = 0, reversep, unsignedp = 0; | 2092 int volatilep = 0, reversep, unsignedp = 0; |
2090 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode, | 2093 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode, |
2091 &unsignedp, &reversep, &volatilep); | 2094 &unsignedp, &reversep, &volatilep); |
2092 | 2095 |
2093 if (bitpos % BITS_PER_UNIT != 0 | 2096 if (!multiple_p (bitpos, BITS_PER_UNIT) |
2094 || bitsize != size_in_bytes * BITS_PER_UNIT) | 2097 || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT)) |
2095 return; | 2098 return; |
2096 | 2099 |
2097 bool decl_p = DECL_P (inner); | 2100 bool decl_p = DECL_P (inner); |
2098 tree base; | 2101 tree base; |
2099 if (decl_p) | 2102 if (decl_p) |