diff options
author | David Malcolm <dmalcolm@redhat.com> | 2015-01-12 22:25:37 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2015-01-12 22:25:37 +0000 |
commit | f6f2b01933268f73bf439ead94a1a72416a36cd5 (patch) | |
tree | d71d1bb61a2a2fc41e045a009e7486b70d2b7b9f /gcc/jit/jit-recording.h | |
parent | 16ba620346c945cddbd0ad49ef5c628e693cad33 (diff) | |
download | gcc-f6f2b01933268f73bf439ead94a1a72416a36cd5.tar.gz |
libgccjit: detect various kinds of errors relating to params and locals
gcc/jit/ChangeLog:
* jit-recording.c (class gcc::jit::rvalue_usage_validator): New.
(gcc::jit::rvalue_usage_validator::rvalue_usage_validator): New
ctor.
(gcc::jit::rvalue_usage_validator::visit): New function.
(gcc::jit::recording::rvalue::verify_valid_within_stmt): New
function.
(gcc::jit::recording::rvalue::set_scope): New function.
(gcc::jit::recording::function::function): Call set_scope on each
param, issuing errors for any params that already have a function.
(gcc::jit::recording::block::add_eval): Return the new statement;
update the comment given that some error-checking now happens after
this returns.
(gcc::jit::recording::block::add_assignment): Likewise.
(gcc::jit::recording::block::add_assignment_op): Likewise.
(gcc::jit::recording::block::add_comment): Likewise.
(gcc::jit::recording::block::end_with_conditional): Likewise.
(gcc::jit::recording::block::end_with_jump): Likewise.
(gcc::jit::recording::block::end_with_return): Likewise.
(gcc::jit::recording::block::validate): Add a comment.
(gcc::jit::recording::unary_op::visit_children): New function.
(gcc::jit::recording::binary_op::visit_children): New function.
(gcc::jit::recording::comparison::visit_children): New function.
(gcc::jit::recording::cast::visit_children): New function.
(gcc::jit::recording::call::visit_children): New function.
(gcc::jit::recording::call_through_ptr::visit_children): New function.
(gcc::jit::recording::array_access::visit_children): New function.
(gcc::jit::recording::access_field_of_lvalue::visit_children): New
function.
(gcc::jit::recording::access_field_rvalue::visit_children): New
function.
(gcc::jit::recording::dereference_field_rvalue::visit_children):
New function.
(gcc::jit::recording::dereference_rvalue::visit_children): New
function.
(gcc::jit::recording::get_address_of_lvalue::visit_children): New
function.
* jit-recording.h: Within namespace gcc::jit::recording...
(class rvalue_visitor): New.
(rvalue::rvalue): Initialize m_scope.
(rvalue::get_loc): New accessor.
(rvalue::verify_valid_within_stmt): New function.
(rvalue::visit_children): New pure virtual function.
(rvalue::set_scope): New function.
(rvalue::get_scope): New function.
(rvalue::dyn_cast_param): New function.
(rvalue::m_scope): New field.
(param::visit_children): New empty function.
(param::dyn_cast_param): New function.
(function::get_loc): New function.
(block::add_eval): Return the new statement.
(block::add_assignment): Likewise.
(block::add_assignment_op): Likewise.
(block::add_comment): Likewise.
(block::end_with_conditional): Likewise.
(block::end_with_jump): Likewise.
(block::end_with_return): Likewise.
(global::visit_children): New function.
(memento_of_new_rvalue_from_const<HOST_TYPE>::visit_children):
New function.
(memento_of_new_string_literal::visit_children): New function.
(unary_op::visit_children): New function.
(binary_op::visit_children): New function.
(comparison::visit_children): New function.
(cast::visit_children): New function.
(call::visit_children): New function.
(call_through_ptr::visit_children): New function.
(array_access::visit_children): New function.
(access_field_of_lvalue::visit_children): New function.
(access_field_rvalue::visit_children): New function.
(dereference_field_rvalue::visit_children): New function.
(dereference_rvalue::visit_children): New function.
(get_address_of_lvalue::visit_children): New function.
(local::local): Call set_scope.
(local::visit_children): New function.
(statement::get_block): Make public.
* libgccjit.c (RETURN_VAL_IF_FAIL_PRINTF5): New macro.
(RETURN_NULL_IF_FAIL_PRINTF5): New macro.
(gcc_jit_context_new_function): Verify that each param has
not yet been used for creating another function.
(gcc_jit_block_add_eval): After creating the stmt, verify
that the rvalue expression tree is valid to use within it.
(gcc_jit_block_add_assignment): Likewise for the lvalue and
rvalue expression trees.
(gcc_jit_block_add_assignment_op): Likewise.
(gcc_jit_block_end_with_conditional): Likewise for the boolval
expression tree.
(gcc_jit_block_end_with_return): Likewise for the rvalue
expression tree.
(gcc_jit_block_end_with_void_return): Remove return of "void",
now that block::end_with_return is now non-void.
gcc/testsuite/ChangeLog:
* jit.dg/test-error-local-used-from-other-function.c: New test
case.
* jit.dg/test-error-param-reuse.c: New test case.
* jit.dg/test-error-param-sharing.c: New test case.
* jit.dg/test-error-param-used-from-other-function.c: New test
case.
* jit.dg/test-error-param-used-without-a-function.c: New test
case.
From-SVN: r219498
Diffstat (limited to 'gcc/jit/jit-recording.h')
-rw-r--r-- | gcc/jit/jit-recording.h | 90 |
1 files changed, 79 insertions, 11 deletions
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 43e99bae0fd..812205c0a1b 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -800,6 +800,18 @@ private: fields *m_fields; }; +/* An abstract base class for operations that visit all rvalues within an + expression tree. + Currently the only implementation is class rvalue_usage_validator within + jit-recording.c. */ + +class rvalue_visitor +{ + public: + virtual ~rvalue_visitor () {} + virtual void visit (rvalue *rvalue) = 0; +}; + class rvalue : public memento { public: @@ -808,11 +820,14 @@ public: type *type_) : memento (ctxt), m_loc (loc), - m_type (type_) + m_type (type_), + m_scope (NULL) { gcc_assert (type_); } + location * get_loc () const { return m_loc; } + /* Get the recording::type of this rvalue. Implements the post-error-checking part of @@ -835,9 +850,23 @@ public: lvalue * dereference (location *loc); + void + verify_valid_within_stmt (const char *api_funcname, statement *s); + + virtual void visit_children (rvalue_visitor *v) = 0; + + void set_scope (function *scope); + function *get_scope () const { return m_scope; } + + /* Dynamic cast. */ + virtual param *dyn_cast_param () { return NULL; } + protected: location *m_loc; type *m_type; + + private: + function *m_scope; /* NULL for globals, non-NULL for locals/params */ }; class lvalue : public rvalue @@ -881,12 +910,16 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *) {} + playback::param * playback_param () const { return static_cast <playback::param *> (m_playback_obj); } + param *dyn_cast_param () { return this; } + private: string * make_debug_string () { return m_name; } @@ -925,6 +958,7 @@ public: block* new_block (const char *name); + location *get_loc () const { return m_loc; } type *get_return_type () const { return m_return_type; } string * get_name () const { return m_name; } const vec<param *> &get_params () const { return m_params; } @@ -979,36 +1013,36 @@ public: bool has_been_terminated () { return m_has_been_terminated; } bool is_reachable () { return m_is_reachable; } - void + statement * add_eval (location *loc, rvalue *rvalue); - void + statement * add_assignment (location *loc, lvalue *lvalue, rvalue *rvalue); - void + statement * add_assignment_op (location *loc, lvalue *lvalue, enum gcc_jit_binary_op op, rvalue *rvalue); - void + statement * add_comment (location *loc, const char *text); - void + statement * end_with_conditional (location *loc, rvalue *boolval, block *on_true, block *on_false); - void + statement * end_with_jump (location *loc, block *target); - void + statement * end_with_return (location *loc, rvalue *rvalue); @@ -1063,6 +1097,8 @@ public: void replay_into (replayer *); + void visit_children (rvalue_visitor *) {} + void write_to_dump (dump &d); private: @@ -1086,6 +1122,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *) {} + private: string * make_debug_string (); @@ -1104,6 +1142,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *) {} + private: string * make_debug_string (); @@ -1126,6 +1166,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1149,6 +1191,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1173,6 +1217,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1195,6 +1241,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1213,6 +1261,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1232,6 +1282,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1254,6 +1306,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1276,6 +1330,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1298,6 +1354,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1320,6 +1378,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1339,6 +1399,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1358,6 +1420,8 @@ public: void replay_into (replayer *r); + void visit_children (rvalue_visitor *v); + private: string * make_debug_string (); @@ -1371,10 +1435,15 @@ public: local (function *func, location *loc, type *type_, string *name) : lvalue (func->m_ctxt, loc, type_), m_func (func), - m_name (name) {} + m_name (name) + { + set_scope (func); + } void replay_into (replayer *r); + void visit_children (rvalue_visitor *) {} + void write_to_dump (dump &d); private: @@ -1393,6 +1462,7 @@ public: void write_to_dump (dump &d); + block *get_block () const { return m_block; } location *get_loc () const { return m_loc; } protected: @@ -1401,8 +1471,6 @@ protected: m_block (b), m_loc (loc) {} - block *get_block () const { return m_block; } - playback::location * playback_location (replayer *r) const { |