comparison gcc/sanopt.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 /* Optimize and expand sanitizer functions. 1 /* Optimize and expand sanitizer functions.
2 Copyright (C) 2014-2017 Free Software Foundation, Inc. 2 Copyright (C) 2014-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
457 /* Optimize away redundant UBSAN_PTR calls. */ 457 /* Optimize away redundant UBSAN_PTR calls. */
458 458
459 static bool 459 static bool
460 maybe_optimize_ubsan_ptr_ifn (sanopt_ctx *ctx, gimple *stmt) 460 maybe_optimize_ubsan_ptr_ifn (sanopt_ctx *ctx, gimple *stmt)
461 { 461 {
462 HOST_WIDE_INT bitsize, bitpos; 462 poly_int64 bitsize, pbitpos;
463 machine_mode mode; 463 machine_mode mode;
464 int volatilep = 0, reversep, unsignedp = 0; 464 int volatilep = 0, reversep, unsignedp = 0;
465 tree offset; 465 tree offset;
466 466
467 gcc_assert (gimple_call_num_args (stmt) == 2); 467 gcc_assert (gimple_call_num_args (stmt) == 2);
481 tree base = ptr; 481 tree base = ptr;
482 if (TREE_CODE (base) == ADDR_EXPR) 482 if (TREE_CODE (base) == ADDR_EXPR)
483 { 483 {
484 base = TREE_OPERAND (base, 0); 484 base = TREE_OPERAND (base, 0);
485 485
486 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode, 486 HOST_WIDE_INT bitpos;
487 base = get_inner_reference (base, &bitsize, &pbitpos, &offset, &mode,
487 &unsignedp, &reversep, &volatilep); 488 &unsignedp, &reversep, &volatilep);
488 if (offset == NULL_TREE && DECL_P (base)) 489 if ((offset == NULL_TREE || TREE_CODE (offset) == INTEGER_CST)
489 { 490 && DECL_P (base)
490 gcc_assert (!DECL_REGISTER (base)); 491 && !DECL_REGISTER (base)
491 offset_int expr_offset = bitpos / BITS_PER_UNIT; 492 && pbitpos.is_constant (&bitpos))
493 {
494 offset_int expr_offset;
495 if (offset)
496 expr_offset = wi::to_offset (offset) + bitpos / BITS_PER_UNIT;
497 else
498 expr_offset = bitpos / BITS_PER_UNIT;
499 expr_offset = wi::sext (expr_offset, POINTER_SIZE);
492 offset_int total_offset = expr_offset + cur_offset; 500 offset_int total_offset = expr_offset + cur_offset;
493 if (total_offset != wi::sext (total_offset, POINTER_SIZE)) 501 if (total_offset != wi::sext (total_offset, POINTER_SIZE))
494 { 502 {
495 record_ubsan_ptr_check_stmt (ctx, stmt, ptr, cur_offset); 503 record_ubsan_ptr_check_stmt (ctx, stmt, ptr, cur_offset);
496 return false; 504 return false;
506 && DECL_SIZE_UNIT (base) 514 && DECL_SIZE_UNIT (base)
507 && TREE_CODE (DECL_SIZE_UNIT (base)) == INTEGER_CST 515 && TREE_CODE (DECL_SIZE_UNIT (base)) == INTEGER_CST
508 && (!is_global_var (base) || decl_binds_to_current_def_p (base))) 516 && (!is_global_var (base) || decl_binds_to_current_def_p (base)))
509 { 517 {
510 offset_int base_size = wi::to_offset (DECL_SIZE_UNIT (base)); 518 offset_int base_size = wi::to_offset (DECL_SIZE_UNIT (base));
511 if (bitpos >= 0 519 if (!wi::neg_p (expr_offset)
512 && wi::les_p (total_offset, base_size)) 520 && wi::les_p (total_offset, base_size))
513 { 521 {
514 if (!wi::neg_p (total_offset) 522 if (!wi::neg_p (total_offset)
515 && wi::les_p (total_offset, base_size)) 523 && wi::les_p (total_offset, base_size))
516 return true; 524 return true;
527 UBSAN_PTR (&MEM_REF[ptr + 100], -50) 535 UBSAN_PTR (&MEM_REF[ptr + 100], -50)
528 b) check for dominating check of ptr + x + y. 536 b) check for dominating check of ptr + x + y.
529 */ 537 */
530 538
531 bool sign_cur_offset = !wi::neg_p (cur_offset); 539 bool sign_cur_offset = !wi::neg_p (cur_offset);
532 bool sign_expr_offset = bitpos >= 0; 540 bool sign_expr_offset = !wi::neg_p (expr_offset);
533 541
534 tree base_addr 542 tree base_addr
535 = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (base)), base); 543 = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (base)), base);
536 544
537 bool add = false; 545 bool add = false;
1138 1146
1139 for (tree arg = DECL_ARGUMENTS (current_function_decl); 1147 for (tree arg = DECL_ARGUMENTS (current_function_decl);
1140 arg; arg = DECL_CHAIN (arg)) 1148 arg; arg = DECL_CHAIN (arg))
1141 { 1149 {
1142 tree type = TREE_TYPE (arg); 1150 tree type = TREE_TYPE (arg);
1143 if (TREE_ADDRESSABLE (arg) && !TREE_ADDRESSABLE (type) 1151 if (TREE_ADDRESSABLE (arg)
1152 && !TREE_ADDRESSABLE (type)
1153 && !TREE_THIS_VOLATILE (arg)
1144 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) 1154 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
1145 { 1155 {
1146 TREE_ADDRESSABLE (arg) = 0; 1156 TREE_ADDRESSABLE (arg) = 0;
1147 /* The parameter is no longer addressable. */ 1157 /* The parameter is no longer addressable. */
1148 has_any_addressable_param = true; 1158 has_any_addressable_param = true;
1153 TREE_ADDRESSABLE (var) = 1; 1163 TREE_ADDRESSABLE (var) = 1;
1154 DECL_IGNORED_P (var) = 1; 1164 DECL_IGNORED_P (var) = 1;
1155 1165
1156 gimple_add_tmp_var (var); 1166 gimple_add_tmp_var (var);
1157 1167
1168 /* We skip parameters that have a DECL_VALUE_EXPR. */
1169 if (DECL_HAS_VALUE_EXPR_P (arg))
1170 continue;
1171
1158 if (dump_file) 1172 if (dump_file)
1159 fprintf (dump_file, 1173 fprintf (dump_file,
1160 "Rewriting parameter whose address is taken: %s\n", 1174 "Rewriting parameter whose address is taken: %s\n",
1161 IDENTIFIER_POINTER (DECL_NAME (arg))); 1175 IDENTIFIER_POINTER (DECL_NAME (arg)));
1162
1163 gcc_assert (!DECL_HAS_VALUE_EXPR_P (arg));
1164 1176
1165 SET_DECL_PT_UID (var, DECL_PT_UID (arg)); 1177 SET_DECL_PT_UID (var, DECL_PT_UID (arg));
1166 1178
1167 /* Assign value of parameter to newly created variable. */ 1179 /* Assign value of parameter to newly created variable. */
1168 if ((TREE_CODE (type) == COMPLEX_TYPE 1180 if ((TREE_CODE (type) == COMPLEX_TYPE