From f6f2b01933268f73bf439ead94a1a72416a36cd5 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 12 Jan 2015 22:25:37 +0000 Subject: 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::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 --- gcc/jit/jit-recording.h | 90 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 11 deletions(-) (limited to 'gcc/jit/jit-recording.h') 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 (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 &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 { -- cgit v1.2.1