summaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-03 17:59:31 +0000
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-03 17:59:31 +0000
commit2c4c347700af66c7e5ce7c0f998270613e62b988 (patch)
tree47ea0e1220f5468397f6fdb89cae25257bd9e763 /gcc/cp/decl.c
parentea151fae4de4aca6d2ce029bd7fe00ded77b0e9c (diff)
downloadgcc-2c4c347700af66c7e5ce7c0f998270613e62b988.tar.gz
Implement -fsanitize=vla-bound.
* opts.c (common_handle_option): Handle vla-bound. * sanitizer.def (BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE): Define. * flag-types.h (enum sanitize_code): Add SANITIZE_VLA. * asan.c (initialize_sanitizer_builtins): Build BT_FN_VOID_PTR_PTR. c-family/ * c-ubsan.c: Don't include hash-table.h. (ubsan_instrument_vla): New function. * c-ubsan.h: Declare it. cp/ * decl.c (cp_finish_decl): Move C++1y bounds checking... (compute_array_index_type): ...here. Add VLA instrumentation. Call stabilize_vla_size. (grokdeclarator): Don't call stabilize_vla_size here. c/ * c-decl.c (grokdeclarator): Add VLA instrumentation. testsuite/ * g++.dg/ubsan/cxx1y-vla.C: New test. * c-c++-common/ubsan/vla-3.c: New test. * c-c++-common/ubsan/vla-2.c: New test. * c-c++-common/ubsan/vla-4.c: New test. * c-c++-common/ubsan/vla-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204334 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c55
1 files changed, 30 insertions, 25 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 09c1daaa243..e662764da85 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-objc.h"
#include "c-family/c-pragma.h"
#include "c-family/c-target.h"
+#include "c-family/c-ubsan.h"
#include "diagnostic.h"
#include "intl.h"
#include "debug.h"
@@ -6399,17 +6400,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
&& TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
error ("non-static data member %qD has Java class type", decl);
- if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
- {
- /* If the VLA bound is larger than half the address space, or less
- than zero, throw std::bad_array_length. */
- tree max = convert (ssizetype, TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
- tree comp = build2 (LT_EXPR, boolean_type_node, max, ssize_int (-1));
- comp = build3 (COND_EXPR, void_type_node, comp,
- throw_bad_array_length (), void_zero_node);
- finish_expr_stmt (comp);
- }
-
/* Add this declaration to the statement-tree. This needs to happen
after the call to check_initializer so that the DECL_EXPR for a
reference temp is added before the DECL_EXPR for the reference itself. */
@@ -8379,6 +8369,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
{
/* A variable sized array. */
itype = variable_size (itype);
+
if (TREE_CODE (itype) != SAVE_EXPR)
{
/* Look for SIZEOF_EXPRs in itype and fold them, otherwise
@@ -8390,6 +8381,32 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
if (found)
itype = variable_size (fold (newitype));
}
+
+ stabilize_vla_size (itype);
+
+ if (cxx_dialect >= cxx1y)
+ {
+ /* If the VLA bound is larger than half the address space,
+ or less than zero, throw std::bad_array_length. */
+ tree comp = build2 (LT_EXPR, boolean_type_node, itype,
+ ssize_int (-1));
+ comp = build3 (COND_EXPR, void_type_node, comp,
+ throw_bad_array_length (), void_zero_node);
+ finish_expr_stmt (comp);
+ }
+ else if (flag_sanitize & SANITIZE_VLA)
+ {
+ /* From C++1y onwards, we throw an exception on a negative
+ length size of an array; see above. */
+
+ /* We have to add 1 -- in the ubsan routine we generate
+ LE_EXPR rather than LT_EXPR. */
+ tree t = fold_build2 (PLUS_EXPR, TREE_TYPE (itype), itype,
+ build_one_cst (TREE_TYPE (itype)));
+ t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t),
+ ubsan_instrument_vla (input_location, t), t);
+ finish_expr_stmt (t);
+ }
}
/* Make sure that there was no overflow when creating to a signed
index type. (For example, on a 32-bit machine, an array with
@@ -9790,12 +9807,8 @@ grokdeclarator (const cp_declarator *declarator,
&& (decl_context == NORMAL || decl_context == FIELD)
&& at_function_scope_p ()
&& variably_modified_type_p (type, NULL_TREE))
- {
- /* First break out any side-effects. */
- stabilize_vla_size (TYPE_SIZE (type));
- /* And then force evaluation of the SAVE_EXPR. */
- finish_expr_stmt (TYPE_SIZE (type));
- }
+ /* Force evaluation of the SAVE_EXPR. */
+ finish_expr_stmt (TYPE_SIZE (type));
if (declarator->kind == cdk_reference)
{
@@ -9886,14 +9899,6 @@ grokdeclarator (const cp_declarator *declarator,
}
}
- /* We need to stabilize side-effects in VLA sizes for regular array
- declarations too, not just pointers to arrays. */
- if (type != error_mark_node && !TYPE_NAME (type)
- && (decl_context == NORMAL || decl_context == FIELD)
- && at_function_scope_p ()
- && variably_modified_type_p (type, NULL_TREE))
- stabilize_vla_size (TYPE_SIZE (type));
-
/* A `constexpr' specifier used in an object declaration declares
the object as `const'. */
if (constexpr_p && innermost_code != cdk_function)