@@ -1,5 +1,27 @@
2014-01-30 David Malcolm <dmalcolm@redhat.com>
+ * TODO.rst: Label-placement is now checked.
+
+ * internal-api.c (gcc::jit::recording::context::replay_into): Give
+ up if any errors occur during the playback.
+ (gcc::jit::recording::label::replay_into): Issue an error if the
+ label has not yet been placed (at playback time).
+ (gcc::jit::recording::place_label::place_label): Move this here
+ from internal-api.h. Issue an error if the label has already
+ been placed (at recording time).
+
+ * internal-api.h (gcc::jit::recording::label): Add an
+ m_has_been_placed field, and make class place_label a friend so
+ it can set it.
+ (gcc::jit::recording::label::has_been_placed): New accessor.
+ (gcc::jit::recording::place_label::place_label): Move to
+ internal-api.c.
+
+ (gcc::jit::playback::context::errors_occurred): Make public, for
+ use by gcc::jit::recording::context::replay_into.
+
+2014-01-30 David Malcolm <dmalcolm@redhat.com>
+
* internal-api.c (gcc::jit::recording::type::get_pointer):
Ensure that repeated calls yield the same type.
(gcc::jit::recording::memento_of_get_pointer::
@@ -127,18 +127,12 @@ Initial Release
* gcc_jit_function_new_local: type must not be void
- * gcc_jit_function_place_forward_label: must not already have been
- placed
-
* gcc_jit_function_add_assignment_op: check the types
* gcc_jit_function_add_conditional: boolval must be of numeric type
* gcc_jit_loop_end: verify that loops are validly nested?
- * verify that all used labels have been placed when attempting to
- compile
-
Future milestones
=================
* try porting llvmpipe to gcc
@@ -131,6 +131,9 @@ recording::context::replay_into (replayer *r)
if (m_parent_ctxt)
m_parent_ctxt->replay_into (r);
+ if (r->errors_occurred ())
+ return;
+
/* Replay this context's saved operations into r. */
FOR_EACH_VEC_ELT (m_mementos, i, m)
{
@@ -145,6 +148,9 @@ recording::context::replay_into (replayer *r)
(void *)this, (void *)m, m->get_debug_string ());
m->replay_into (r);
+
+ if (r->errors_occurred ())
+ return;
}
}
@@ -989,8 +995,13 @@ recording::function::make_debug_string ()
/* gcc::jit::recording::label:: */
void
-recording::label::replay_into (replayer *)
+recording::label::replay_into (replayer *r)
{
+ if (!m_has_been_placed)
+ {
+ r->add_error ("unplaced label: %s", get_debug_string ());
+ return;
+ }
set_playback_obj (m_func->playback_function ()
->new_forward_label (playback_string (m_name)));
}
@@ -1458,6 +1469,18 @@ recording::conditional::make_debug_string ()
m_on_true->get_debug_string ());
}
+recording::place_label::place_label (function *func,
+ location *loc,
+ label *lab)
+: statement (func, loc),
+ m_label (lab)
+{
+ if (lab->m_has_been_placed)
+ m_ctxt->add_error ("label %s has already been placed",
+ lab->get_debug_string ());
+ lab->m_has_been_placed = true;
+}
+
void
recording::place_label::replay_into (replayer *)
{
@@ -745,7 +745,8 @@ public:
label (function *func, string *name)
: memento (func->m_ctxt),
m_func (func),
- m_name (name)
+ m_name (name),
+ m_has_been_placed (false)
{
}
@@ -757,12 +758,17 @@ public:
return static_cast <playback::label *> (m_playback_obj);
}
+ bool has_been_placed () { return m_has_been_placed; }
+
private:
string * make_debug_string ();
private:
function *m_func;
string *m_name;
+ bool m_has_been_placed;
+
+ friend class place_label;
};
class global : public lvalue
@@ -1230,9 +1236,7 @@ class place_label : public statement
public:
place_label (function *func,
location *loc,
- label *lab)
- : statement (func, loc),
- m_label (lab) {}
+ label *lab);
void replay_into (replayer *r);
@@ -1498,6 +1502,11 @@ public:
tree
as_truth_value (tree expr, location *loc);
+ bool errors_occurred () const
+ {
+ return m_recording_ctxt->errors_occurred ();
+ }
+
private:
void dump_generated_code ();
@@ -1506,11 +1515,6 @@ private:
void handle_locations ();
- bool errors_occurred () const
- {
- return m_recording_ctxt->errors_occurred ();
- }
-
private:
::gcc::jit::recording::context *m_recording_ctxt;
@@ -1,5 +1,10 @@
2014-01-30 David Malcolm <dmalcolm@redhat.com>
+ * jit.dg/test-error-label-already-placed.c: New test case.
+ * jit.dg/test-error-unplaced-label.c: New test case.
+
+2014-01-30 David Malcolm <dmalcolm@redhat.com>
+
* jit.dg/test-error-call-with-mismatching-args.c: New test case.
2014-01-30 David Malcolm <dmalcolm@redhat.com>
new file mode 100644
@@ -0,0 +1,59 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ int
+ test_fn (void)
+ {
+ foo:
+ return 0;
+
+ foo:
+ return 1;
+
+ }
+
+ and verify that the 2nd attempt to place the label fails.
+ */
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "test_fn",
+ 0, NULL, 0);
+
+ /* Create forward label: */
+ gcc_jit_label *label =
+ gcc_jit_function_new_forward_label (func, "foo");
+
+ gcc_jit_function_place_forward_label (func, NULL, label);
+ gcc_jit_function_add_return (func, NULL,
+ gcc_jit_context_zero (ctxt, int_type));
+
+ /* Erroneous 2nd placement of label: */
+ gcc_jit_function_place_forward_label (func, NULL, label);
+ gcc_jit_function_add_return (func, NULL,
+ gcc_jit_context_one (ctxt, int_type));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "label foo has already been placed");
+}
new file mode 100644
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ void
+ test_fn (void)
+ {
+ goto foo;
+ }
+
+ and verify that an error is issued due to label "foo" not being
+ placed.
+ */
+ gcc_jit_type *void_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ "test_fn",
+ 0, NULL, 0);
+
+ /* Create forward label: */
+ gcc_jit_label *unplaced_label =
+ gcc_jit_function_new_forward_label (func, "foo");
+
+ /* Use it (but never place it): */
+ gcc_jit_function_add_jump (func, NULL, unplaced_label);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "unplaced label: foo");
+}
+