Recognize the __builtin_dynamic_object_size builtin, but simply replace it with -1 or 0 for now.
gcc/ChangeLog: * builtins.c (expand_builtin, fold_builtin_2): Add BUILT_IN_DYN_OBJECT_SIZE. (fold_builtin_dyn_object_size): New function. (valid_object_size_args): New function. (fold_builtin_object_size): Use it. * builtins.def (BUILT_IN_DYN_OBJECT_SIZE): New builtin. --- gcc/builtins.c | 63 +++++++++++++++++++++++++++++++++++++++--------- gcc/builtins.def | 1 + 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/gcc/builtins.c b/gcc/builtins.c index 3e57eb03af0..894d62359b4 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -180,6 +180,7 @@ static rtx expand_builtin_memory_chk (tree, rtx, machine_mode, static void maybe_emit_chk_warning (tree, enum built_in_function); static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function); static tree fold_builtin_object_size (tree, tree); +static tree fold_builtin_dyn_object_size (tree, tree); unsigned HOST_WIDE_INT target_newline; unsigned HOST_WIDE_INT target_percent; @@ -7910,6 +7911,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, return const0_rtx; case BUILT_IN_OBJECT_SIZE: + case BUILT_IN_DYN_OBJECT_SIZE: return expand_builtin_object_size (exp); case BUILT_IN_MEMCPY_CHK: @@ -9318,6 +9320,9 @@ fold_builtin_2 (location_t loc, tree expr, tree fndecl, tree arg0, tree arg1) case BUILT_IN_OBJECT_SIZE: return fold_builtin_object_size (arg0, arg1); + case BUILT_IN_DYN_OBJECT_SIZE: + return fold_builtin_dyn_object_size (arg0, arg1); + case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE: return fold_builtin_atomic_always_lock_free (arg0, arg1); @@ -9964,7 +9969,10 @@ fold_builtin_next_arg (tree exp, bool va_start_p) } -/* Expand a call EXP to __builtin_object_size. */ +/* Expand a call EXP to __builtin_object_size or + __builtin_dynamic_object_size. If the builtin survived up to this point + then it means we have failed to get an object size, so replace the call with + 0 or -1 depending on the object size type argument. */ static rtx expand_builtin_object_size (tree exp) @@ -10250,27 +10258,40 @@ maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode) access_write_only); } -/* Fold a call to __builtin_object_size with arguments PTR and OST, - if possible. */ +/* Validate arguments to __builtin_object_size and + __builtin_dynamic_object_size. If both arguments are valid, return the + object size type in OSTP. */ -static tree -fold_builtin_object_size (tree ptr, tree ost) +static bool +valid_object_size_args (const tree ptr, tree ost, int *ostp) { - unsigned HOST_WIDE_INT bytes; - int object_size_type; - if (!validate_arg (ptr, POINTER_TYPE) || !validate_arg (ost, INTEGER_TYPE)) - return NULL_TREE; + return false; STRIP_NOPS (ost); if (TREE_CODE (ost) != INTEGER_CST || tree_int_cst_sgn (ost) < 0 || compare_tree_int (ost, 3) > 0) - return NULL_TREE; + return false; - object_size_type = tree_to_shwi (ost); + *ostp = tree_to_shwi (ost); + + return true; +} + +/* Fold a call to __builtin_object_size with arguments PTR and OST, + if possible. */ + +static tree +fold_builtin_object_size (tree ptr, tree ost) +{ + unsigned HOST_WIDE_INT bytes; + int object_size_type; + + if (!valid_object_size_args (ptr, ost, &object_size_type)) + return NULL_TREE; /* __builtin_object_size doesn't evaluate side-effects in its arguments; if there are any side-effects, it returns (size_t) -1 for types 0 and 1 @@ -10297,6 +10318,26 @@ fold_builtin_object_size (tree ptr, tree ost) return NULL_TREE; } +/* Fold a call to __builtin_dynamic_object_size with arguments PTR and OST, + if possible. */ + +static tree +fold_builtin_dyn_object_size (tree ptr, tree ost) +{ + int object_size_type; + + if (!valid_object_size_args (ptr, ost, &object_size_type)) + return NULL_TREE; + + /* __builtin_dynamic_object_size doesn't evaluate side-effects in its + arguments; if there are any side-effects, it returns (size_t) -1 for types + 0 and 1 and (size_t) 0 for types 2 and 3. */ + if (TREE_SIDE_EFFECTS (ptr)) + return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0); + + return NULL_TREE; +} + /* Builtins with folding operations that operate on "..." arguments need special handling; we need to store the arguments in a convenient data structure before attempting any folding. Fortunately there are diff --git a/gcc/builtins.def b/gcc/builtins.def index 45a09b4d42d..ae94caab921 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -972,6 +972,7 @@ DEF_BUILTIN_STUB (BUILT_IN_STRNCMP_EQ, "__builtin_strncmp_eq") /* Object size checking builtins. */ DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_DYN_OBJECT_SIZE, "dynamic_object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_NOTHROW_LEAF_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF) -- 2.31.1