diff options
author | Maxim Ostapenko <m.ostapenko@samsung.com> | 2016-03-24 15:12:28 +0300 |
---|---|---|
committer | Maxim Ostapenko <m.ostapenko@samsung.com> | 2016-04-25 12:03:35 +0300 |
commit | abd8d96e0be0492fc4e42c99bed1170720966499 (patch) | |
tree | 341b50b9ebb2bbf937ba5e574f7f9475c884aadf | |
parent | 6c2f22b46fd0e4877e591c2f89cd23724b67d121 (diff) | |
download | linaro-gcc-abd8d96e0be0492fc4e42c99bed1170720966499.tar.gz linaro-gcc-abd8d96e0be0492fc4e42c99bed1170720966499.tar.bz2 linaro-gcc-abd8d96e0be0492fc4e42c99bed1170720966499.zip |
Backport manual fixes for GCC in order to fix various build and runtime errors.
- Return to old hash table.
- Define missing void_zero_node macro.
- Add missing tree_int_cst_le function.
- Add missing gcc/signop.h header.
- Add missing macro.
- Add missing specialization stuff for double_int class.
- Add missing wi::clz and wi::clrsb functions. Add new file wide-int.cc.
- Remove include of double-int.h from gcc/gengtype.c and gcc/gengtype-state.c.
- Small fix for hash table. Change operator '->' to '.' because we have
a reference to hash table, not a pointer.
- Change varpool_node::finalize_decl (var) back to varpool_finalize_decl (var).
- Fix sanopt.c optimizing part to fit old style pointer map.
- Fix for CHECK_TYPE_SIZE(__kernel_old_uid_t) and CHECK_TYPE_SIZE(__kernel_old_gid_t)
fails on Aarch64.
- Replace gcall back to gimple_statement_call.
- Use old cgraph interface.
- Define missing void_node macro.
- Add missing SUBREG_PROMOTED_SIGN macro.
- Fix ICE in ubsan_type_descriptor due to overflow in tree_fits_uhwi_p.
Change-Id: I9741e28505c96c37fb1ff89f4721725c1a5a5eaf
Signed-off-by: Maxim Ostapenko <m.ostapenko@samsung.com>
-rw-r--r-- | gcc/Makefile.in | 1 | ||||
-rw-r--r-- | gcc/asan.c | 6 | ||||
-rw-r--r-- | gcc/c-family/c-gimplify.c | 2 | ||||
-rw-r--r-- | gcc/c-family/c-ubsan.c | 2 | ||||
-rw-r--r-- | gcc/double-int.h | 34 | ||||
-rw-r--r-- | gcc/gengtype-state.c | 1 | ||||
-rw-r--r-- | gcc/gengtype.c | 1 | ||||
-rw-r--r-- | gcc/internal-fn.c | 1 | ||||
-rw-r--r-- | gcc/rtl.h | 5 | ||||
-rw-r--r-- | gcc/sanopt.c | 40 | ||||
-rw-r--r-- | gcc/signop.h | 35 | ||||
-rw-r--r-- | gcc/system.h | 10 | ||||
-rw-r--r-- | gcc/tree.c | 9 | ||||
-rw-r--r-- | gcc/tree.h | 2 | ||||
-rw-r--r-- | gcc/ubsan.c | 9 | ||||
-rw-r--r-- | gcc/wide-int.cc | 106 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc | 2 |
17 files changed, 245 insertions, 21 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in index ff73324c498..d5eaef9922a 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1467,6 +1467,7 @@ OBJS = \ varasm.o \ varpool.o \ vmsdbgout.o \ + wide-int.o \ vtable-verify.o \ web.o \ xcoffout.o \ diff --git a/gcc/asan.c b/gcc/asan.c index de400369bb1..3e24e620d71 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -483,7 +483,7 @@ has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size) asan_mem_ref r; asan_mem_ref_init (&r, ref, access_size); - asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r); + asan_mem_ref *saved_ref = get_mem_ref_hash_table ().find (&r); return saved_ref && saved_ref->access_size >= access_size; } @@ -941,7 +941,7 @@ update_mem_ref_hash_table (tree ref, HOST_WIDE_INT access_size) asan_mem_ref r; asan_mem_ref_init (&r, ref, access_size); - asan_mem_ref **slot = ht->find_slot (&r, INSERT); + asan_mem_ref **slot = ht.find_slot (&r, INSERT); if (*slot == NULL || (*slot)->access_size < access_size) *slot = asan_mem_ref_new (ref, access_size); } @@ -2325,7 +2325,7 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v) TREE_CONSTANT (ctor) = 1; TREE_STATIC (ctor) = 1; DECL_INITIAL (var) = ctor; - varpool_node::finalize_decl (var); + varpool_finalize_decl (var); locptr = fold_convert (uptr, build_fold_addr_expr (var)); } else diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c index 837599b034d..cb7d1468cdb 100644 --- a/gcc/c-family/c-gimplify.c +++ b/gcc/c-family/c-gimplify.c @@ -103,7 +103,7 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data) as the index might be constant or masked, so ensure it is not walked again and walk its subtrees manually. */ tree aref = TREE_OPERAND (*tp, 0); - pset->add (aref); + pointer_set_insert (pset, aref); *walk_subtrees = 0; walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset); walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset); diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 1b71d472085..d702a741117 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -35,6 +35,8 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "gimplify.h" +#define void_node void_zero_node + /* Instrument division by zero and INT_MIN / -1. If not instrumenting, return NULL_TREE. */ diff --git a/gcc/double-int.h b/gcc/double-int.h index 5ca9ccf61f9..a2b11ba8419 100644 --- a/gcc/double-int.h +++ b/gcc/double-int.h @@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see #ifndef DOUBLE_INT_H #define DOUBLE_INT_H +#include "wide-int.h" + /* A large integer is currently represented as a pair of HOST_WIDE_INTs. It therefore represents a number with precision of 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the @@ -435,4 +437,36 @@ void mpz_set_double_int (mpz_t, double_int, bool); double_int mpz_get_double_int (const_tree, mpz_t, bool); #endif +namespace wi +{ + template <> + struct int_traits <double_int> + { + static const enum precision_type precision_type = CONST_PRECISION; + static const bool host_dependent_precision = true; + static const unsigned int precision = HOST_BITS_PER_DOUBLE_INT; + static unsigned int get_precision (const double_int &); + static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int, + const double_int &); + }; +} + +inline unsigned int +wi::int_traits <double_int>::get_precision (const double_int &) +{ + return precision; +} + +inline wi::storage_ref +wi::int_traits <double_int>::decompose (HOST_WIDE_INT *scratch, unsigned int p, + const double_int &x) +{ + gcc_checking_assert (precision == p); + scratch[0] = x.low; + if ((x.high == 0 && scratch[0] >= 0) || (x.high == -1 && scratch[0] < 0)) + return wi::storage_ref (scratch, 1, precision); + scratch[1] = x.high; + return wi::storage_ref (scratch, 2, precision); +} + #endif /* DOUBLE_INT_H */ diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c index 0b925b539bc..2ca0e1de1e7 100644 --- a/gcc/gengtype-state.c +++ b/gcc/gengtype-state.c @@ -30,7 +30,6 @@ #endif #include "system.h" #include "errors.h" /* For fatal. */ -#include "double-int.h" #include "hashtab.h" #include "version.h" /* For version_string & pkgversion_string. */ #include "obstack.h" diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 031004a7b1f..7dc1ce353e4 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -25,7 +25,6 @@ #include "system.h" #include "errors.h" /* for fatal */ #include "getopt.h" -#include "double-int.h" #include "version.h" /* for version_string & pkgversion_string. */ #include "hashtab.h" #include "xregex.h" diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 6008bc0fb21..671510565bf 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "wide-int.h" #include "tree.h" #include "internal-fn.h" #include "stor-layout.h" diff --git a/gcc/rtl.h b/gcc/rtl.h index 6d43b27feb1..cb373ef9142 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1413,6 +1413,11 @@ do { \ extension, except for generating instructions where we need to emit special code (ptr_extend insns) on some architectures. */ +/* Returns sign of promoted mode for SUBREG_PROMOTED_VAR_P(). */ +#define SUBREG_PROMOTED_SIGN(RTX) \ + ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGN", (RTX), SUBREG)->volatil) ? 1\ + : (RTX)->unchanging - 1) + #define SUBREG_PROMOTED_UNSIGNED_P(RTX) \ ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil) \ ? -1 : (int) (RTX)->unchanging) diff --git a/gcc/sanopt.c b/gcc/sanopt.c index 5a35166d546..f00d61f20b9 100644 --- a/gcc/sanopt.c +++ b/gcc/sanopt.c @@ -26,12 +26,10 @@ along with GCC; see the file COPYING3. If not see #include "predict.h" #include "vec.h" #include "hashtab.h" -#include "hash-set.h" +#include "pointer-set.h" #include "tm.h" #include "hard-reg-set.h" #include "function.h" -#include "dominance.h" -#include "cfg.h" #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" @@ -40,7 +38,6 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "gimplify.h" #include "gimple-iterator.h" -#include "hash-map.h" #include "plugin-api.h" #include "tree-pass.h" #include "asan.h" @@ -50,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "ubsan.h" #include "params.h" #include "tree-ssa-operands.h" +#include <new> /* This is used to carry information about basic blocks. It is @@ -91,11 +89,11 @@ struct sanopt_ctx { /* This map maps a pointer (the first argument of UBSAN_NULL) to a vector of UBSAN_NULL call statements that check this pointer. */ - hash_map<tree, auto_vec<gimple> > null_check_map; + pointer_map<auto_vec<gimple> > null_check_map; /* This map maps a pointer (the second argument of ASAN_CHECK) to a vector of ASAN_CHECK call statements that check the access. */ - hash_map<tree, auto_vec<gimple> > asan_check_map; + pointer_map< auto_vec<gimple> > asan_check_map; /* Number of IFN_ASAN_CHECK statements. */ int asan_num_accesses; @@ -208,8 +206,18 @@ maybe_optimize_ubsan_null_ifn (struct sanopt_ctx *ctx, gimple stmt) gcc_assert (TREE_CODE (cur_align) == INTEGER_CST); bool remove = false; - auto_vec<gimple> &v = ctx->null_check_map.get_or_insert (ptr); - if (v.is_empty ()) + bool exists = true; + void **slot = + pointer_map_contains ((const pointer_map_t *)&ctx->null_check_map, ptr); + if (!slot) + { + slot = pointer_map_insert ((pointer_map_t *)&ctx->null_check_map, ptr); + exists = false; + } + auto_vec<gimple> &v + = exists ? *(auto_vec<gimple> *) slot : *new(slot) auto_vec<gimple> (); + + if (!exists) { /* For this PTR we don't have any UBSAN_NULL stmts recorded, so there's nothing to optimize yet. */ @@ -281,8 +289,18 @@ maybe_optimize_asan_check_ifn (struct sanopt_ctx *ctx, gimple stmt) gimple_set_uid (stmt, info->freeing_call_events); - auto_vec<gimple> &v = ctx->asan_check_map.get_or_insert (ptr); - if (v.is_empty ()) + bool exists = true; + void **slot = + pointer_map_contains ((const pointer_map_t *)&ctx->asan_check_map, ptr); + if (!slot) + { + slot = pointer_map_insert ((pointer_map_t *)&ctx->asan_check_map, ptr); + exists = false; + } + auto_vec<gimple> &v + = exists ? *(auto_vec<gimple> *) slot : *new(slot) auto_vec<gimple> (); + + if (!exists) { /* For this PTR we don't have any ASAN_CHECK stmts recorded, so there's nothing to optimize yet. */ @@ -543,7 +561,7 @@ pass_sanopt::execute () if (optimize && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_ADDRESS))) - asan_num_accesses = sanopt_optimize (fun); + asan_num_accesses = sanopt_optimize (cfun); else if (flag_sanitize & SANITIZE_ADDRESS) { gimple_stmt_iterator gsi; diff --git a/gcc/signop.h b/gcc/signop.h new file mode 100644 index 00000000000..bc760eab5ef --- /dev/null +++ b/gcc/signop.h @@ -0,0 +1,35 @@ +/* Operations with SIGNED and UNSIGNED. -*- C++ -*- + Copyright (C) 2012-2015 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +GCC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef SIGNOP_H +#define SIGNOP_H + +/* This type is used for the large number of functions that produce + different results depending on if the operands are signed types or + unsigned types. The signedness of a tree type can be found by + using the TYPE_SIGN macro. */ + +enum signop_e { + SIGNED, + UNSIGNED +}; + +typedef enum signop_e signop; + +#endif diff --git a/gcc/system.h b/gcc/system.h index e23de866097..cb8ed3695ba 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -711,6 +711,16 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; #define gcc_unreachable() (fancy_abort (__FILE__, __LINE__, __FUNCTION__)) #endif +#if GCC_VERSION >= 3001 +#define STATIC_CONSTANT_P(X) (__builtin_constant_p (X) && (X)) +#else +#define STATIC_CONSTANT_P(X) (false && (X)) +#endif + +/* Until we can use C++11's static_assert. */ +#define STATIC_ASSERT(X) \ + typedef int assertion1[(X) ? 1 : -1] ATTRIBUTE_UNUSED + /* Provide a fake boolean type. We make no attempt to use the C99 _Bool, as it may not be available in the bootstrap compiler, and even if it is, it is liable to be buggy. diff --git a/gcc/tree.c b/gcc/tree.c index bec9d7b7aa9..d51b90f8270 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6967,6 +6967,15 @@ tree_int_cst_lt (const_tree t1, const_tree t2) return INT_CST_LT_UNSIGNED (t1, t2); } +/* Nonzero if integer constants T1 and T2 represent values that satisfy <=. + The precise way of comparison depends on their data type. */ + +int +tree_int_cst_le (const_tree t1, const_tree t2) +{ + return tree_int_cst_lt (t1, t2) || tree_int_cst_equal (t1, t2); +} + /* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2. */ int diff --git a/gcc/tree.h b/gcc/tree.h index 2aafb89334c..237447e00c0 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3256,6 +3256,7 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, #define complex_long_double_type_node global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE] #define void_type_node global_trees[TI_VOID_TYPE] +#define void_node void_zero_node /* The C type `void *'. */ #define ptr_type_node global_trees[TI_PTR_TYPE] /* The C type `const void *'. */ @@ -3654,6 +3655,7 @@ extern int attribute_list_equal (const_tree, const_tree); extern int attribute_list_contained (const_tree, const_tree); extern int tree_int_cst_equal (const_tree, const_tree); extern int tree_int_cst_lt (const_tree, const_tree); +extern int tree_int_cst_le (const_tree, const_tree); extern int tree_int_cst_compare (const_tree, const_tree); extern bool tree_fits_shwi_p (const_tree) #ifndef ENABLE_TREE_CHECKING diff --git a/gcc/ubsan.c b/gcc/ubsan.c index 7c2fe66f176..0b34812986b 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -411,7 +411,8 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle) { pretty_name[pos++] = '['; tree dom = TYPE_DOMAIN (t); - if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST) + if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST + && (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom)))) pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC, tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1); else @@ -640,13 +641,13 @@ is_ubsan_builtin_p (tree t) static void ubsan_create_edge (gimple stmt) { - gcall *call_stmt = dyn_cast <gcall *> (stmt); + gimple_statement_call *call_stmt = static_cast <gimple_statement_call *> (stmt); basic_block bb = gimple_bb (stmt); int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); - cgraph_node *node = cgraph_node::get (current_function_decl); + cgraph_node *node = cgraph_get_node (current_function_decl); tree decl = gimple_call_fndecl (call_stmt); if (decl) - node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count, + cgraph_create_edge (node, cgraph_get_create_node (decl), call_stmt, bb->count, freq); } diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc new file mode 100644 index 00000000000..190cb85e008 --- /dev/null +++ b/gcc/wide-int.cc @@ -0,0 +1,106 @@ +/* Operations with very long integers. + Copyright (C) 2012-2015 Free Software Foundation, Inc. + Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +GCC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "hwint.h" +#include "wide-int.h" +#include "machmode.h" +#include "vec.h" +#include "double-int.h" +#include "input.h" +#include "alias.h" +#include "symtab.h" +#include "tree.h" +#include "dumpfile.h" + +#if HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_LONG +# define HOST_HALF_WIDE_INT long +#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_INT +# define HOST_HALF_WIDE_INT int +#else +#error Please add support for HOST_HALF_WIDE_INT +#endif + +/* Return the number of leading (upper) zeros in X. */ +int +wi::clz (const wide_int_ref &x) +{ + /* Calculate how many bits there above the highest represented block. */ + int count = x.precision - x.len * HOST_BITS_PER_WIDE_INT; + + unsigned HOST_WIDE_INT high = x.uhigh (); + if (count < 0) + /* The upper -COUNT bits of HIGH are not part of the value. + Clear them out. */ + high = (high << -count) >> -count; + else if (x.sign_mask () < 0) + /* The upper bit is set, so there are no leading zeros. */ + return 0; + + /* We don't need to look below HIGH. Either HIGH is nonzero, + or the top bit of the block below is nonzero; clz_hwi is + HOST_BITS_PER_WIDE_INT in the latter case. */ + return count + clz_hwi (high); +} + +int +wi::clrsb (const wide_int_ref &x) +{ + /* Calculate how many bits there above the highest represented block. */ + int count = x.precision - x.len * HOST_BITS_PER_WIDE_INT; + + unsigned HOST_WIDE_INT high = x.uhigh (); + unsigned HOST_WIDE_INT mask = -1; + if (count < 0) + { + /* The upper -COUNT bits of HIGH are not part of the value. + Clear them from both MASK and HIGH. */ + mask >>= -count; + high &= mask; + } + + /* If the top bit is 1, count the number of leading 1s. If the top + bit is zero, count the number of leading zeros. */ + if (high > mask / 2) + high ^= mask; + + /* There are no sign bits below the top block, so we don't need to look + beyond HIGH. Note that clz_hwi is HOST_BITS_PER_WIDE_INT when + HIGH is 0. */ + return count + clz_hwi (high) - 1; +} + +/* Return the number of trailing (lower) zeros in X. */ +int +wi::ctz (const wide_int_ref &x) +{ + if (x.len == 1 && x.ulow () == 0) + return x.precision; + + /* Having dealt with the zero case, there must be a block with a + nonzero bit. We don't care about the bits above the first 1. */ + unsigned int i = 0; + while (x.val[i] == 0) + ++i; + return i * HOST_BITS_PER_WIDE_INT + ctz_hwi (x.val[i]); +} diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc index 4793bc18625..09336850716 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -1065,8 +1065,10 @@ CHECK_SIZE_AND_OFFSET(__sysctl_args, newlen); CHECK_TYPE_SIZE(__kernel_uid_t); CHECK_TYPE_SIZE(__kernel_gid_t); +#if !defined(__aarch64__) CHECK_TYPE_SIZE(__kernel_old_uid_t); CHECK_TYPE_SIZE(__kernel_old_gid_t); +#endif CHECK_TYPE_SIZE(__kernel_off_t); CHECK_TYPE_SIZE(__kernel_loff_t); CHECK_TYPE_SIZE(__kernel_fd_set); |