return new lvalue (get_context (), datum);
}
+/* Mark EXP saying that we need to be able to take the
+ address of it; it should not be allocated in a register.
+ Compare with e.g. c/c-typeck.c: c_mark_addressable. */
+
+static void
+jit_mark_addressable (tree exp)
+{
+ tree x = exp;
+
+ while (1)
+ switch (TREE_CODE (x))
+ {
+ case COMPONENT_REF:
+ /* (we don't yet support bitfields) */
+ /* fallthrough */
+ case ADDR_EXPR:
+ case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case COMPOUND_LITERAL_EXPR:
+ case CONSTRUCTOR:
+ TREE_ADDRESSABLE (x) = 1;
+ return;
+
+ case VAR_DECL:
+ case CONST_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ /* (we don't have a concept of a "register" declaration) */
+ /* fallthrough */
+ case FUNCTION_DECL:
+ TREE_ADDRESSABLE (x) = 1;
+ /* fallthrough */
+ default:
+ return;
+ }
+}
+
/* Construct a playback::rvalue instance (wrapping a tree) for an
address-lookup. */
tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue);
if (loc)
get_context ()->set_tree_location (ptr, loc);
+ jit_mark_addressable (t_lvalue);
return new rvalue (get_context (), ptr);
}
#undef create_code
#undef verify_code
+/* test-pr66700-observing-write-through-ptr.c */
+#define create_code create_code_pr66700_observing_write_through_ptr
+#define verify_code verify_code_pr66700_observing_write_through_ptr
+#include "test-pr66700-observing-write-through-ptr.c"
+#undef create_code
+#undef verify_code
+
/* test-reading-struct.c */
#define create_code create_code_reading_struct
#define verify_code verify_code_reading_struct
{"nested_loop",
create_code_nested_loop,
verify_code_nested_loop},
+ {"pr66700_observing_write_through_ptr",
+ create_code_pr66700_observing_write_through_ptr,
+ verify_code_pr66700_observing_write_through_ptr},
{"reading_struct ",
create_code_reading_struct ,
verify_code_reading_struct },
--- /dev/null
+/* Test of PR jit/66700. */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern void
+ write_back_through_ptr (double *d);
+
+#ifdef __cplusplus
+}
+#endif
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ double
+ test_caller_of_write_back_through_ptr (void)
+ {
+ double d;
+ d = 4.0;
+ write_back_through_ptr (&d);
+ return d;
+ }
+ */
+ gcc_jit_type *t_void =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+ gcc_jit_type *t_double =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
+ gcc_jit_type *t_ptr_to_double =
+ gcc_jit_type_get_pointer (t_double);
+
+ /* Declare the imported function. */
+ gcc_jit_param *params[1];
+ params[0] =
+ gcc_jit_context_new_param (ctxt, NULL, t_ptr_to_double, "d");
+ gcc_jit_function *called_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_IMPORTED,
+ t_void,
+ "write_back_through_ptr",
+ 1, params,
+ 0);
+
+ /* Build the test_fn. */
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ t_double,
+ "test_caller_of_write_back_through_ptr",
+ 0, NULL,
+ 0);
+ gcc_jit_lvalue *d =
+ gcc_jit_function_new_local (test_fn, NULL, t_double, "d");
+
+ gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+
+ /* "d = 0.0" */
+ gcc_jit_block_add_assignment (
+ block, NULL, d,
+ gcc_jit_context_new_rvalue_from_int (ctxt, t_double, 4));
+
+ /* "write_back_through_ptr (&d);" */
+ gcc_jit_rvalue *args[1];
+ args[0] = gcc_jit_lvalue_get_address (d, NULL);
+ gcc_jit_block_add_eval (
+ block, NULL,
+ gcc_jit_context_new_call (ctxt,
+ NULL,
+ called_fn,
+ 1, args));
+ gcc_jit_block_end_with_return (block,
+ NULL,
+ gcc_jit_lvalue_as_rvalue (d));
+}
+
+extern void
+write_back_through_ptr (double *d)
+{
+ *d = 5.600000;
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef double (*fn_type) (void);
+ CHECK_NON_NULL (result);
+
+ fn_type test_caller_of_write_back_through_ptr =
+ (fn_type)gcc_jit_result_get_code (result,
+ "test_caller_of_write_back_through_ptr");
+ CHECK_NON_NULL (test_caller_of_write_back_through_ptr);
+
+ /* Call the JIT-generated function. */
+ double d = test_caller_of_write_back_through_ptr ();
+
+ /* Verify that it correctly called "write_back_through_ptr". */
+ CHECK_VALUE (d, 5.600000);
+}
+