diff options
author | Denis Khalikov <d.khalikov@partner.samsung.com> | 2017-10-28 17:39:01 +0300 |
---|---|---|
committer | Denis Khalikov <d.khalikov@partner.samsung.com> | 2017-10-28 18:41:11 +0300 |
commit | 02b62443516966cb329722fa2ad217a384a95cd9 (patch) | |
tree | 120fae60a95c7141cd71c3308320f39ad64aff5d | |
parent | da1dbde9cfceed248de0b28a0ef7a0f2a54ba5bd (diff) | |
download | linaro-gcc-sandbox/denis13/isan_fix.tar.gz linaro-gcc-sandbox/denis13/isan_fix.tar.bz2 linaro-gcc-sandbox/denis13/isan_fix.zip |
[ISan] Workaround for SAVE_EXPRsandbox/denis13/isan_fix
Change-Id: Iac55ab97fae23b9046bb40b4556cb85b24c278bf
-rw-r--r-- | gcc/cp/tree.c | 11 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 5 | ||||
-rw-r--r-- | gcc/tree.c | 39 |
3 files changed, 53 insertions, 2 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 5e8bb742bf4..e6daeac26a8 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "attribs.h" +extern tree isan_expr (tree expr); static tree bot_manip (tree *, int *, void *); static tree bot_replace (tree *, int *, void *); static hashval_t list_hash_pieces (tree, tree, tree); @@ -4057,6 +4058,16 @@ cp_save_expr (tree expr) return save_expr (expr); } +/* Workaround for isan and save_expr. */ + +tree +cp_isan_expr (tree expr) +{ + if (processing_template_decl) + return expr; + return isan_expr (expr); +} + /* Initialize tree.c. */ void diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 458baa70539..5e5cd6407e7 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "c-family/c-ubsan.h" #include "params.h" +extern tree cp_isan_expr (tree expr); static tree cp_build_addr_expr_strict (tree, tsubst_flags_t); static tree cp_build_function_call (tree, tree, tsubst_flags_t); static tree pfn_from_ptrmemfunc (tree); @@ -5173,9 +5174,9 @@ cp_build_binary_op (location_t location, How to get actual value from SAVE_EXPR ? FIXME: use SAVE_EXPR. */ + op0 = cp_isan_expr (op0); + op1 = cp_isan_expr (op1); /* - op0 = cp_save_expr (op0); - op1 = cp_save_expr (op1); op0 = fold_non_dependent_expr (op0); op1 = fold_non_dependent_expr (op1); */ diff --git a/gcc/tree.c b/gcc/tree.c index 7ce14c93663..64327099909 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -3375,6 +3375,45 @@ save_expr (tree expr) return t; } +/* Workaround for isan and save_expr. */ + +tree +isan_expr (tree expr) +{ + tree t = fold (expr); + tree inner; + + /* If the tree evaluates to a constant, then we don't want to hide that + fact (i.e. this allows further folding, and direct checks for constants). + However, a read-only object that has side effects cannot be bypassed. + Since it is no problem to reevaluate literals, we just return the + literal node. */ + inner = skip_simple_arithmetic (t); + if (TREE_CODE (inner) == ERROR_MARK) + return inner; + + if (tree_invariant_p_1 (inner)) + return t; + + /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since + it means that the size or offset of some field of an object depends on + the value within another field. + + Note that it must not be the case that T contains both a PLACEHOLDER_EXPR + and some variable since it would then need to be both evaluated once and + evaluated more than once. Front-ends must assure this case cannot + happen by surrounding any such subexpressions in their own SAVE_EXPR + and forcing evaluation at the proper time. */ + if (contains_placeholder_p (inner)) + return t; + + /* This expression might be placed ahead of a jump to ensure that the + value was computed on both sides of the jump. So make sure it isn't + eliminated as dead. */ + TREE_SIDE_EFFECTS (t) = 1; + return t; +} + /* Look inside EXPR into any simple arithmetic operations. Return the outermost non-arithmetic or non-invariant node. */ |