From 6f3af3562804db0ef656dcc02b1e192c8f7fc8cc Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 31 Mar 2017 20:39:25 +0200 Subject: [PATCH] re PR sanitizer/79572 (reference binding to null pointer not reported with -fsanitize=undefined) PR c++/79572 * c-ubsan.h (ubsan_maybe_instrument_reference): Change argument to tree *. * c-ubsan.c (ubsan_maybe_instrument_reference): Likewise. Handle not just NOP_EXPR to REFERENCE_TYPE, but also INTEGER_CST with REFERENCE_TYPE. * cp-gimplify.c (cp_genericize_r): Sanitize INTEGER_CSTs with REFERENCE_TYPE. Adjust ubsan_maybe_instrument_reference caller for NOP_EXPR to REFERENCE_TYPE. * g++.dg/ubsan/null-8.C: New test. From-SVN: r246621 --- gcc/c-family/ChangeLog | 9 +++++++++ gcc/c-family/c-ubsan.c | 17 +++++++++++++---- gcc/c-family/c-ubsan.h | 2 +- gcc/cp/ChangeLog | 5 +++++ gcc/cp/cp-gimplify.c | 15 ++++++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/ubsan/null-8.C | 19 +++++++++++++++++++ 7 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ubsan/null-8.C diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 0f0bd49714a..0d5a16f6609 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,12 @@ +2017-03-31 Jakub Jelinek + + PR c++/79572 + * c-ubsan.h (ubsan_maybe_instrument_reference): Change argument to + tree *. + * c-ubsan.c (ubsan_maybe_instrument_reference): Likewise. Handle + not just NOP_EXPR to REFERENCE_TYPE, but also INTEGER_CST with + REFERENCE_TYPE. + 2017-03-31 David Malcolm PR documentation/78732 diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 36aa919a872..91bdef88320 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -458,17 +458,26 @@ ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype, return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op); } -/* Instrument a NOP_EXPR to REFERENCE_TYPE if needed. */ +/* Instrument a NOP_EXPR to REFERENCE_TYPE or INTEGER_CST with REFERENCE_TYPE + type if needed. */ void -ubsan_maybe_instrument_reference (tree stmt) +ubsan_maybe_instrument_reference (tree *stmt_p) { - tree op = TREE_OPERAND (stmt, 0); + tree stmt = *stmt_p; + tree op = stmt; + if (TREE_CODE (stmt) == NOP_EXPR) + op = TREE_OPERAND (stmt, 0); op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op, TREE_TYPE (stmt), UBSAN_REF_BINDING); if (op) - TREE_OPERAND (stmt, 0) = op; + { + if (TREE_CODE (stmt) == NOP_EXPR) + TREE_OPERAND (stmt, 0) = op; + else + *stmt_p = op; + } } /* Instrument a CALL_EXPR to a method if needed. */ diff --git a/gcc/c-family/c-ubsan.h b/gcc/c-family/c-ubsan.h index dc0897d605f..3c3ffc7f7a2 100644 --- a/gcc/c-family/c-ubsan.h +++ b/gcc/c-family/c-ubsan.h @@ -28,7 +28,7 @@ extern tree ubsan_instrument_return (location_t); extern tree ubsan_instrument_bounds (location_t, tree, tree *, bool); extern bool ubsan_array_ref_instrumented_p (const_tree); extern void ubsan_maybe_instrument_array_ref (tree *, bool); -extern void ubsan_maybe_instrument_reference (tree); +extern void ubsan_maybe_instrument_reference (tree *); extern void ubsan_maybe_instrument_member_call (tree, bool); /* Declare this here as well as in ubsan.h. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 14eee1c3340..743847908d0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2017-03-31 Jakub Jelinek + PR c++/79572 + * cp-gimplify.c (cp_genericize_r): Sanitize INTEGER_CSTs with + REFERENCE_TYPE. Adjust ubsan_maybe_instrument_reference caller + for NOP_EXPR to REFERENCE_TYPE. + PR libstdc++/80251 * cp-tree.h (enum cp_trait_kind): Add CPTK_IS_AGGREGATE. * cxx-pretty-print.c (pp_cxx_trait_expression): Handle diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 354ae1af852..6e49daf8499 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1130,6 +1130,19 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) } } + if (TREE_CODE (stmt) == INTEGER_CST + && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE + && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) + && !wtd->no_sanitize_p) + { + ubsan_maybe_instrument_reference (stmt_p); + if (*stmt_p != stmt) + { + *walk_subtrees = 0; + return NULL_TREE; + } + } + /* Other than invisiref parms, don't walk the same tree twice. */ if (p_set->contains (stmt)) { @@ -1477,7 +1490,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) && TREE_CODE (stmt) == NOP_EXPR && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE) - ubsan_maybe_instrument_reference (stmt); + ubsan_maybe_instrument_reference (stmt_p); else if (TREE_CODE (stmt) == CALL_EXPR) { tree fn = CALL_EXPR_FN (stmt); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 02581a2ca65..134fc2a309c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-31 Jakub Jelinek + + PR c++/79572 + * g++.dg/ubsan/null-8.C: New test. + 2017-03-31 Pat Haugen PR target/80107 diff --git a/gcc/testsuite/g++.dg/ubsan/null-8.C b/gcc/testsuite/g++.dg/ubsan/null-8.C new file mode 100644 index 00000000000..259a213183a --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/null-8.C @@ -0,0 +1,19 @@ +// PR c++/79572 +// { dg-do run } +// { dg-options "-fsanitize=null -std=c++14" } +// { dg-output "reference binding to null pointer of type 'const int'" } + +void +foo (const int &iref) +{ + if (&iref) + __builtin_printf ("iref %d\n", iref); + else + __builtin_printf ("iref is NULL\n"); +} + +int +main () +{ + foo (*((int*) __null)); +} -- 2.30.2