summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-14 11:22:12 +0000
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-14 11:22:12 +0000
commitf6b540af02190c7c3e07a26eb5864f9a24fe7274 (patch)
treef5208d057eaf4ec81d4adff4f52bce7cd091e6de
parentf79af31817fea33a1152c0b17980db871ae8f1be (diff)
downloadgcc-f6b540af02190c7c3e07a26eb5864f9a24fe7274.tar.gz
PR sanitizer/63839
* asan.c (ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST, ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST): Define. * builtin-attrs.def (ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST): Define. * builtins.c (fold_builtin_0): Don't include ubsan.h. Don't instrument BUILT_IN_UNREACHABLE here. * sanitizer.def (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE): Make const. * sanopt.c (pass_sanopt::execute): Instrument BUILT_IN_UNREACHABLE. * tree-ssa-ccp.c (optimize_unreachable): Bail out if SANITIZE_UNREACHABLE. * ubsan.c (ubsan_instrument_unreachable): Rewrite for GIMPLE. * ubsan.h (ubsan_instrument_unreachable): Adjust declaration. testsuite/ * c-c++-common/ubsan/pr63839.c: New test. * c-c++-common/ubsan/unreachable-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217553 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/asan.c6
-rw-r--r--gcc/builtin-attrs.def2
-rw-r--r--gcc/builtins.c9
-rw-r--r--gcc/sanitizer.def2
-rw-r--r--gcc/sanopt.c15
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr63839.c23
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/unreachable-2.c14
-rw-r--r--gcc/tree-ssa-ccp.c3
-rw-r--r--gcc/ubsan.c27
-rw-r--r--gcc/ubsan.h2
12 files changed, 106 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5e4a6686dd6..58efc772d66 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2014-11-14 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/63839
+ * asan.c (ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST,
+ ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST): Define.
+ * builtin-attrs.def (ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST):
+ Define.
+ * builtins.c (fold_builtin_0): Don't include ubsan.h. Don't
+ instrument BUILT_IN_UNREACHABLE here.
+ * sanitizer.def (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE): Make
+ const.
+ * sanopt.c (pass_sanopt::execute): Instrument BUILT_IN_UNREACHABLE.
+ * tree-ssa-ccp.c (optimize_unreachable): Bail out if
+ SANITIZE_UNREACHABLE.
+ * ubsan.c (ubsan_instrument_unreachable): Rewrite for GIMPLE.
+ * ubsan.h (ubsan_instrument_unreachable): Adjust declaration.
+
2014-11-14 Alan Lawrence <alan.lawrence@arm.com>
* config/rs6000/vector.md (vec_shl_<mode>): Remove.
diff --git a/gcc/asan.c b/gcc/asan.c
index 79dede71418..2961b4460de 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -2346,6 +2346,9 @@ initialize_sanitizer_builtins (void)
#define ATTR_TMPURE_NOTHROW_LEAF_LIST ECF_TM_PURE | ATTR_NOTHROW_LEAF_LIST
#undef ATTR_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
+#undef ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
+#define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST \
+ ECF_CONST | ATTR_NORETURN_NOTHROW_LEAF_LIST
#undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
@@ -2355,6 +2358,9 @@ initialize_sanitizer_builtins (void)
#undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
/* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
+#undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
+#define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
+ /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
#undef DEF_SANITIZER_BUILTIN
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM, \
diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index 9c05a949039..c707367d4e7 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -145,6 +145,8 @@ DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LIST, ATTR_SENTINEL, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LEAF_LIST, ATTR_SENTINEL, \
ATTR_NULL, ATTR_NOTHROW_LEAF_LIST)
+DEF_ATTR_TREE_LIST (ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST, ATTR_CONST,\
+ ATTR_NULL, ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
/* Functions whose pointer parameter(s) are all nonnull. */
DEF_ATTR_TREE_LIST (ATTR_NONNULL_LIST, ATTR_NONNULL, ATTR_NULL, ATTR_NULL)
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1cd65edb194..311c0e38279 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -64,7 +64,6 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "builtins.h"
#include "asan.h"
-#include "ubsan.h"
#include "cilk.h"
#include "ipa-ref.h"
#include "lto-streamer.h"
@@ -9803,14 +9802,6 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
case BUILT_IN_CLASSIFY_TYPE:
return fold_builtin_classify_type (NULL_TREE);
- case BUILT_IN_UNREACHABLE:
- if (flag_sanitize & SANITIZE_UNREACHABLE
- && (current_function_decl == NULL
- || !lookup_attribute ("no_sanitize_undefined",
- DECL_ATTRIBUTES (current_function_decl))))
- return ubsan_instrument_unreachable (loc);
- break;
-
default:
break;
}
diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def
index cddc5ea4935..3fc8c8396be 100644
--- a/gcc/sanitizer.def
+++ b/gcc/sanitizer.def
@@ -394,7 +394,7 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS,
DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE,
"__ubsan_handle_builtin_unreachable",
BT_FN_VOID_PTR,
- ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
+ ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_MISSING_RETURN,
"__ubsan_handle_missing_return",
BT_FN_VOID_PTR,
diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index 0fc032a7a30..fe2e42d121c 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -312,6 +312,21 @@ pass_sanopt::execute (function *fun)
break;
}
}
+ else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+ {
+ tree callee = gimple_call_fndecl (stmt);
+ switch (DECL_FUNCTION_CODE (callee))
+ {
+ case BUILT_IN_UNREACHABLE:
+ if (flag_sanitize & SANITIZE_UNREACHABLE
+ && !lookup_attribute ("no_sanitize_undefined",
+ DECL_ATTRIBUTES (fun->decl)))
+ no_next = ubsan_instrument_unreachable (&gsi);
+ break;
+ default:
+ break;
+ }
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5ffb5d445b4..1d3ef947bf2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-14 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/63839
+ * c-c++-common/ubsan/pr63839.c: New test.
+ * c-c++-common/ubsan/unreachable-2.c: New test.
+
2014-11-14 Richard Biener <rguenther@suse.de>
* gcc.c-torture/execute/shiftopt-1.c: XFAIL invalid parts.
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr63839.c b/gcc/testsuite/c-c++-common/ubsan/pr63839.c
new file mode 100644
index 00000000000..e3933f7fe66
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/pr63839.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=unreachable" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+/* { dg-shouldfail "ubsan" } */
+
+static void __attribute__ ((noreturn))
+bar ()
+{
+} /* { dg-warning "function does return" } */
+
+void
+foo ()
+{
+ bar ();
+}
+
+int
+main (void)
+{
+ foo ();
+}
+
+/* { dg-output "execution reached a __builtin_unreachable\\(\\) call" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/unreachable-2.c b/gcc/testsuite/c-c++-common/ubsan/unreachable-2.c
new file mode 100644
index 00000000000..783ebc24913
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/unreachable-2.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=unreachable" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+/* { dg-shouldfail "ubsan" } */
+
+int e;
+
+int
+main (void)
+{
+ return e ? 0 : (__builtin_unreachable (), 1);
+}
+
+/* { dg-output "execution reached a __builtin_unreachable\\(\\) call" } */
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 52d85036e1f..31ca0e120e3 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2568,6 +2568,9 @@ optimize_unreachable (gimple_stmt_iterator i)
edge e;
bool ret;
+ if (flag_sanitize & SANITIZE_UNREACHABLE)
+ return false;
+
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
stmt = gsi_stmt (gsi);
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 41cf546cde3..b5b1b924c67 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -588,17 +588,26 @@ ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
/* Instrument the __builtin_unreachable call. We just call the libubsan
routine instead. */
-tree
-ubsan_instrument_unreachable (location_t loc)
+bool
+ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
{
- if (flag_sanitize_undefined_trap_on_error)
- return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
+ gimple g;
+ location_t loc = gimple_location (gsi_stmt (*gsi));
- initialize_sanitizer_builtins ();
- tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc, NULL_TREE,
- NULL_TREE);
- tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
- return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
+ if (flag_sanitize_undefined_trap_on_error)
+ g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
+ else
+ {
+ tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
+ NULL_TREE, NULL_TREE);
+ data = build_fold_addr_expr_loc (loc, data);
+ tree fn
+ = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
+ g = gimple_build_call (fn, 1, data);
+ }
+ gimple_set_location (g, loc);
+ gsi_replace (gsi, g, false);
+ return false;
}
/* Return true if T is a call to a libubsan routine. */
diff --git a/gcc/ubsan.h b/gcc/ubsan.h
index 27c18eb00f8..dcdbb4fa4c9 100644
--- a/gcc/ubsan.h
+++ b/gcc/ubsan.h
@@ -41,7 +41,7 @@ enum ubsan_print_style {
extern bool ubsan_expand_bounds_ifn (gimple_stmt_iterator *);
extern bool ubsan_expand_null_ifn (gimple_stmt_iterator *);
extern bool ubsan_expand_objsize_ifn (gimple_stmt_iterator *);
-extern tree ubsan_instrument_unreachable (location_t);
+extern bool ubsan_instrument_unreachable (gimple_stmt_iterator *);
extern tree ubsan_create_data (const char *, int, const location_t *, ...);
extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NORMAL);
extern tree ubsan_encode_value (tree, bool = false);