This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PING][PATCH] New plugin event when evaluating a constexpr call
- From: Andres Tiraboschi <andres dot tiraboschi at tallertechnologies dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 25 Apr 2016 11:08:38 -0300
- Subject: [PING][PATCH] New plugin event when evaluating a constexpr call
- Authentication-results: sourceware.org; auth=none
Hi
This patch adds a plugin event when evaluating a call expression in constexpr.
The goal of this patch is to allow the plugins to analyze and or
modify the evaluation of constant expressions.
Changelog 2016-4-25 Andres Tiraboschi
<andres.tiraboschi@tallertechnologies.com>
*gcc/plugin.c (PLUGIN_EVAL_CALL_CONSTEXPR): New event.
*gcc/plugin.def (PLUGIN_EVAL_CALL_CONSTEXPR): New event.
*gcc/cp/constexpr.c (constexpr_fundef): Moved to gcc/cp/cp-tree.h.
*gcc/cp/constexpr.c (constexpr_call): Ditto.
*gcc/cp/constexpr.c (constexpr_ctx): Ditto.
*gcc/cp/constexpr.c (cxx_eval_constant_expression): Not static anymore.
*gcc/pc/cp-tree.h (constexpr_call_info): New Type.
*gcc/pc/cp-tree.h (constexpr_fundef): Moved type from gcc/cp/constexpr.c.
*gcc/pc/cp-tree.h (constexpr_call): Ditto.
*gcc/pc/cp-tree.h (constexpr_ctx): Ditto.
*gcc/pc/cp-tree.h (cxx_eval_constant_expression): Declared.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 5f97c9d..5562e44 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "tree-inline.h"
#include "ubsan.h"
+#include "plugin-api.h"
+#include "plugin.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@@ -112,13 +114,6 @@ ensure_literal_type_for_constexpr_object (tree decl)
return decl;
}
-/* Representation of entries in the constexpr function definition table. */
-
-struct GTY((for_user)) constexpr_fundef {
- tree decl;
- tree body;
-};
-
struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
{
static hashval_t hash (constexpr_fundef *);
@@ -856,62 +851,12 @@ explain_invalid_constexpr_fn (tree fun)
input_location = save_loc;
}
-/* Objects of this type represent calls to constexpr functions
- along with the bindings of parameters to their arguments, for
- the purpose of compile time evaluation. */
-
-struct GTY((for_user)) constexpr_call {
- /* Description of the constexpr function definition. */
- constexpr_fundef *fundef;
- /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
- is a parameter _DECL and the TREE_VALUE is the value of the parameter.
- Note: This arrangement is made to accommodate the use of
- iterative_hash_template_arg (see pt.c). If you change this
- representation, also change the hash calculation in
- cxx_eval_call_expression. */
- tree bindings;
- /* Result of the call.
- NULL means the call is being evaluated.
- error_mark_node means that the evaluation was erroneous;
- otherwise, the actuall value of the call. */
- tree result;
- /* The hash of this call; we remember it here to avoid having to
- recalculate it when expanding the hash table. */
- hashval_t hash;
-};
-
struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call>
{
static hashval_t hash (constexpr_call *);
static bool equal (constexpr_call *, constexpr_call *);
};
-/* The constexpr expansion context. CALL is the current function
- expansion, CTOR is the current aggregate initializer, OBJECT is the
- object being initialized by CTOR, either a VAR_DECL or a _REF. VALUES
- is a map of values of variables initialized within the expression. */
-
-struct constexpr_ctx {
- /* The innermost call we're evaluating. */
- constexpr_call *call;
- /* Values for any temporaries or local variables within the
- constant-expression. */
- hash_map<tree,tree> *values;
- /* SAVE_EXPRs that we've seen within the current LOOP_EXPR. NULL if we
- aren't inside a loop. */
- hash_set<tree> *save_exprs;
- /* The CONSTRUCTOR we're currently building up for an aggregate
- initializer. */
- tree ctor;
- /* The object we're building the CONSTRUCTOR for. */
- tree object;
- /* Whether we should error on a non-constant expression or fail quietly. */
- bool quiet;
- /* Whether we are strictly conforming to constant expression rules or
- trying harder to get a constant value. */
- bool strict;
-};
-
/* A table of all constexpr calls that have been evaluated by the
compiler in this translation unit. */
@@ -1303,6 +1248,22 @@ cxx_eval_call_expression (const constexpr_ctx
*ctx, tree t,
bool non_constant_args = false;
cxx_bind_parameters_in_call (ctx, t, &new_call,
non_constant_p, overflow_p, &non_constant_args);
+
+ constexpr_call_info call_info;
+ call_info.function = t;
+ call_info.lval = lval;
+ call_info.call = &new_call;
+ call_info.call_stack = call_stack;
+ call_info.non_constant_args = &non_constant_args;
+ call_info.non_const_p = non_constant_p;
+ call_info.ctx = ctx;
+ call_info.result = NULL_TREE;
+ invoke_plugin_callbacks (PLUGIN_EVAL_CALL_CONSTEXPR, &call_info);
+ if (call_info.result != NULL_TREE)
+ {
+ return call_info.result;
+ }
+
if (*non_constant_p)
return t;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 15b004d..00856ec 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6946,6 +6946,77 @@ extern tree cp_ubsan_maybe_instrument_downcast
(location_t, tree, tree, tree);
extern tree cp_ubsan_maybe_instrument_cast_to_vbase (location_t, tree, tree);
extern void cp_ubsan_maybe_initialize_vtbl_ptrs (tree);
+/* Representation of entries in the constexpr function definition table. */
+
+struct GTY((for_user)) constexpr_fundef {
+ tree decl;
+ tree body;
+};
+
+/* Objects of this type represent calls to constexpr functions
+ along with the bindings of parameters to their arguments, for
+ the purpose of compile time evaluation. */
+
+struct GTY((for_user)) constexpr_call {
+ /* Description of the constexpr function definition. */
+ constexpr_fundef *fundef;
+ /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
+ is a parameter _DECL and the TREE_VALUE is the value of the parameter.
+ Note: This arrangement is made to accommodate the use of
+ iterative_hash_template_arg (see pt.c). If you change this
+ representation, also change the hash calculation in
+ cxx_eval_call_expression. */
+ tree bindings;
+ /* Result of the call.
+ NULL means the call is being evaluated.
+ error_mark_node means that the evaluation was erroneous;
+ otherwise, the actuall value of the call. */
+ tree result;
+ /* The hash of this call; we remember it here to avoid having to
+ recalculate it when expanding the hash table. */
+ hashval_t hash;
+};
+
+/* The constexpr expansion context. CALL is the current function
+ expansion, CTOR is the current aggregate initializer, OBJECT is the
+ object being initialized by CTOR, either a VAR_DECL or a _REF. VALUES
+ is a map of values of variables initialized within the expression. */
+
+struct constexpr_ctx {
+ /* The innermost call we're evaluating. */
+ constexpr_call *call;
+ /* Values for any temporaries or local variables within the
+ constant-expression. */
+ hash_map<tree,tree> *values;
+ /* SAVE_EXPRs that we've seen within the current LOOP_EXPR. NULL if we
+ aren't inside a loop. */
+ hash_set<tree> *save_exprs;
+ /* The CONSTRUCTOR we're currently building up for an aggregate
+ initializer. */
+ tree ctor;
+ /* The object we're building the CONSTRUCTOR for. */
+ tree object;
+ /* Whether we should error on a non-constant expression or fail quietly. */
+ bool quiet;
+ /* Whether we are strictly conforming to constant expression rules or
+ trying harder to get a constant value. */
+ bool strict;
+};
+
+/* This type represents a function call into a constant expression.*/
+typedef struct constexpr_call_info_st
+{
+ tree function; //Function named in call.
+ tree result; //Function call result.
+ vec<tree> call_stack; //Call stack.
+ bool lval;
+ bool* non_constant_args; //The function arguments are constant.
+ bool* non_const_p; //Is constant.
+ bool* overflow;
+ constexpr_call* call; //Call to the constexpr function.
+ const struct constexpr_ctx* ctx; //constexpr expansion context.
+} constexpr_call_info;
+
/* -- end of C++ */
#endif /* ! GCC_CP_TREE_H */
diff --git a/gcc/plugin.c b/gcc/plugin.c
index 60081a5..34c60ed 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -427,6 +427,7 @@ register_callback (const char *plugin_name,
return;
}
/* Fall through. */
+ case PLUGIN_EVAL_CALL_CONSTEXPR:
case PLUGIN_START_PARSE_FUNCTION:
case PLUGIN_FINISH_PARSE_FUNCTION:
case PLUGIN_FINISH_TYPE:
@@ -507,6 +508,7 @@ invoke_plugin_callbacks_full (int event, void *gcc_data)
gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC);
gcc_assert (event < event_last);
/* Fall through. */
+ case PLUGIN_EVAL_CALL_CONSTEXPR:
case PLUGIN_START_PARSE_FUNCTION:
case PLUGIN_FINISH_PARSE_FUNCTION:
case PLUGIN_FINISH_TYPE:
diff --git a/gcc/plugin.def b/gcc/plugin.def
index c926d41..824f807 100644
--- a/gcc/plugin.def
+++ b/gcc/plugin.def
@@ -17,6 +17,9 @@ You should have received a copy of the GNU General
Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+/* Called when evaluating a constexpr call. */
+DEFEVENT (PLUGIN_EVAL_CALL_CONSTEXPR)
+
/* Called before parsing the body of a function. */
DEFEVENT (PLUGIN_START_PARSE_FUNCTION)