aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2017-11-06 10:02:15 +0100
committerMartin Liska <marxin@gcc.gnu.org>2017-11-06 09:02:15 +0000
commit1b6fa695ab5e6f6fd57ed9264b336f06f440125b (patch)
tree34f2706dd509a58f25ed69fda30793e918703da2 /gcc/cp/constexpr.c
parent3232f0521cda16efeff012f65bc4d0b15d02a7e2 (diff)
downloadgcc-1b6fa695ab5e6f6fd57ed9264b336f06f440125b.zip
gcc-1b6fa695ab5e6f6fd57ed9264b336f06f440125b.tar.gz
gcc-1b6fa695ab5e6f6fd57ed9264b336f06f440125b.tar.bz2
Instrument function exit with __builtin_unreachable in C++
2017-11-06 Martin Liska <mliska@suse.cz> PR middle-end/82404 * c-opts.c (c_common_post_options): Set -Wreturn-type for C++ FE. * c.opt: Set default value of warn_return_type. 2017-11-06 Martin Liska <mliska@suse.cz> PR middle-end/82404 * constexpr.c (cxx_eval_builtin_function_call): Handle __builtin_unreachable call. (get_function_named_in_call): Declare function earlier. (constexpr_fn_retval): Skip __builtin_unreachable. * cp-gimplify.c (cp_ubsan_maybe_instrument_return): Rename to ... (cp_maybe_instrument_return): ... this. (cp_genericize): Call the function unconditionally. 2017-11-06 Martin Liska <mliska@suse.cz> PR middle-end/82404 * options.c (gfc_post_options): Set default value of -Wreturn-type to false. From-SVN: r254437
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 483f731..670aae2 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -628,6 +628,20 @@ build_constexpr_constructor_member_initializers (tree type, tree body)
return error_mark_node;
}
+/* We have an expression tree T that represents a call, either CALL_EXPR
+ or AGGR_INIT_EXPR. If the call is lexically to a named function,
+ retrun the _DECL for that function. */
+
+static tree
+get_function_named_in_call (tree t)
+{
+ tree fun = cp_get_callee (t);
+ if (fun && TREE_CODE (fun) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL)
+ fun = TREE_OPERAND (fun, 0);
+ return fun;
+}
+
/* Subroutine of register_constexpr_fundef. BODY is the body of a function
declared to be constexpr, or a sub-statement thereof. Returns the
return value if suitable, error_mark_node for a statement not allowed in
@@ -682,6 +696,15 @@ constexpr_fn_retval (tree body)
case USING_STMT:
return NULL_TREE;
+ case CALL_EXPR:
+ {
+ tree fun = get_function_named_in_call (body);
+ if (fun != NULL_TREE
+ && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
+ return NULL_TREE;
+ }
+ /* Fallthru. */
+
default:
return error_mark_node;
}
@@ -1098,20 +1121,6 @@ save_fundef_copy (tree fun, tree copy)
}
/* We have an expression tree T that represents a call, either CALL_EXPR
- or AGGR_INIT_EXPR. If the call is lexically to a named function,
- retrun the _DECL for that function. */
-
-static tree
-get_function_named_in_call (tree t)
-{
- tree fun = cp_get_callee (t);
- if (fun && TREE_CODE (fun) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL)
- fun = TREE_OPERAND (fun, 0);
- return fun;
-}
-
-/* We have an expression tree T that represents a call, either CALL_EXPR
or AGGR_INIT_EXPR. Return the Nth argument. */
static inline tree
@@ -1180,9 +1189,18 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
{
if (!*non_constant_p && !ctx->quiet)
{
- new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
- CALL_EXPR_FN (t), nargs, args);
- error ("%q+E is not a constant expression", new_call);
+ /* Do not allow__builtin_unreachable in constexpr function.
+ The __builtin_unreachable call with BUILTINS_LOCATION
+ comes from cp_maybe_instrument_return. */
+ if (DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
+ && EXPR_LOCATION (t) == BUILTINS_LOCATION)
+ error ("constexpr call flows off the end of the function");
+ else
+ {
+ new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
+ CALL_EXPR_FN (t), nargs, args);
+ error ("%q+E is not a constant expression", new_call);
+ }
}
*non_constant_p = true;
return t;