From f8fc8b8e787c4279c1f24c91459b6dbe481d7805 Mon Sep 17 00:00:00 2001 From: jakub Date: Tue, 18 Nov 2014 22:15:42 +0000 Subject: [PATCH] PR sanitizer/63813 * c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Change type argument to ptype, set type to TREE_TYPE (ptype). Don't call get_pointer_alignment for non-pointers. Use ptype, or if it is reference type, corresponding pointer type, as type of kind argument. (ubsan_maybe_instrument_reference, ubsan_maybe_instrument_member_call): Adjust callers. * g++.dg/ubsan/pr63813.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217741 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/c-family/ChangeLog | 11 +++++++++++ gcc/c-family/c-ubsan.c | 28 ++++++++++++++++++---------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/ubsan/pr63813.C | 12 ++++++++++++ 4 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ubsan/pr63813.C diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index fa0518a63eb..cc6771a1bf5 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,14 @@ +2014-11-18 Jakub Jelinek + + PR sanitizer/63813 + * c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Change type + argument to ptype, set type to TREE_TYPE (ptype). Don't call + get_pointer_alignment for non-pointers. Use ptype, or if it is + reference type, corresponding pointer type, as type of kind + argument. + (ubsan_maybe_instrument_reference, + ubsan_maybe_instrument_member_call): Adjust callers. + 2014-11-15 Marek Polacek PR middle-end/63884 diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index ab16799b0c9..90b03f23e73 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -383,18 +383,19 @@ ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one) } static tree -ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type, +ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype, enum ubsan_null_ckind ckind) { - tree orig_op = op; - bool instrument = false; - unsigned int mina = 0; - if (current_function_decl == NULL_TREE || lookup_attribute ("no_sanitize_undefined", DECL_ATTRIBUTES (current_function_decl))) return NULL_TREE; + tree type = TREE_TYPE (ptype); + tree orig_op = op; + bool instrument = false; + unsigned int mina = 0; + if (flag_sanitize & SANITIZE_ALIGNMENT) { mina = min_align_of_type (type); @@ -431,13 +432,20 @@ ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type, } else if (flag_sanitize & SANITIZE_NULL) instrument = true; - if (mina && mina > get_pointer_alignment (op) / BITS_PER_UNIT) - instrument = true; + if (mina && mina > 1) + { + if (!POINTER_TYPE_P (TREE_TYPE (op)) + || mina > get_pointer_alignment (op) / BITS_PER_UNIT) + instrument = true; + } } if (!instrument) return NULL_TREE; op = save_expr (orig_op); - tree kind = build_int_cst (TREE_TYPE (op), ckind); + gcc_assert (POINTER_TYPE_P (ptype)); + if (TREE_CODE (ptype) == REFERENCE_TYPE) + ptype = build_pointer_type (TREE_TYPE (ptype)); + tree kind = build_int_cst (ptype, ckind); tree align = build_int_cst (pointer_sized_int_node, mina); tree call = build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node, @@ -453,7 +461,7 @@ ubsan_maybe_instrument_reference (tree stmt) { tree op = TREE_OPERAND (stmt, 0); op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op, - TREE_TYPE (TREE_TYPE (stmt)), + TREE_TYPE (stmt), UBSAN_REF_BINDING); if (op) TREE_OPERAND (stmt, 0) = op; @@ -471,7 +479,7 @@ ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor) || !POINTER_TYPE_P (TREE_TYPE (op))) return; op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op, - TREE_TYPE (TREE_TYPE (op)), + TREE_TYPE (op), is_ctor ? UBSAN_CTOR_CALL : UBSAN_MEMBER_CALL); if (op) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad651fa7830..49f497396f7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2014-11-18 Jakub Jelinek + PR sanitizer/63813 + * g++.dg/ubsan/pr63813.C: New test. + PR tree-optimization/61042 * gcc.c-torture/compile/pr61042.c: New test. diff --git a/gcc/testsuite/g++.dg/ubsan/pr63813.C b/gcc/testsuite/g++.dg/ubsan/pr63813.C new file mode 100644 index 00000000000..6ca5b2d18c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr63813.C @@ -0,0 +1,12 @@ +// PR sanitizer/63813 +// { dg-do compile } +// { dg-options "-fsanitize=undefined -O1" } + +struct A {}; +struct B { long foo () const; A &bar () const; }; + +A & +B::bar () const +{ + return *reinterpret_cast (foo ()); +} -- 2.11.4.GIT