Commit ee118c14 by Andrea Corallo Committed by Andrea Corallo

introduce gcc_jit_context_new_bitfield

gcc/jit/ChangeLog:
2019-07-04  Andrea Corallo <andrea.corallo@arm.com>

	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_12): New ABI tag.
	* docs/topics/types.rst: Add gcc_jit_context_new_bitfield.
	* jit-common.h (namespace recording): Add class bitfield.
	* jit-playback.c:
	(DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): Add macros.
	(playback::context::new_bitfield): New method.
	(playback::compound_type::set_fields): Add bitfield support.
	(playback::lvalue::mark_addressable): Was jit_mark_addressable make this
	a method of lvalue plus return a bool to communicate success.
	(playback::lvalue::get_address): Check for jit_mark_addressable return
	value.
	* jit-playback.h (new_bitfield): New method.
	(class bitfield): New class.
	(class lvalue): Add jit_mark_addressable method.
	* jit-recording.c (recording::context::new_bitfield): New method.
	(recording::bitfield::replay_into): New method.
	(recording::bitfield::write_to_dump): Likewise.
	(recording::bitfield::make_debug_string): Likewise.
	(recording::bitfield::write_reproducer): Likewise.
	* jit-recording.h (class context): Add new_bitfield method.
	(class field): Make it derivable by class bitfield.
	(class bitfield): Add new class.
	* libgccjit++.h (class context): Add new_bitfield method.
	* libgccjit.c (struct gcc_jit_bitfield): New structure.
	(gcc_jit_context_new_bitfield): New function.
	* libgccjit.h
	(LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield) New macro.
	(gcc_jit_context_new_bitfield): New function.
	* libgccjit.map (LIBGCCJIT_ABI_12) New ABI tag.

gcc/testsuite/ChangeLog:
2019-07-04  Andrea Corallo <andrea.corallo@arm.com>

	* jit.dg/all-non-failing-tests.h: Add test-accessing-bitfield.c.
	* jit.dg/test-accessing-bitfield.c: New testcase.
	* jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c:
	Likewise.
	* jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c:
	Likewise.
	* jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c:
	Likewise.

From-SVN: r273086
parent ebebc928
2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_12): New ABI tag.
* docs/topics/types.rst: Add gcc_jit_context_new_bitfield.
* jit-common.h (namespace recording): Add class bitfield.
* jit-playback.c:
(DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): Add macros.
(playback::context::new_bitfield): New method.
(playback::compound_type::set_fields): Add bitfield support.
(playback::lvalue::mark_addressable): Was jit_mark_addressable make this
a method of lvalue plus return a bool to communicate success.
(playback::lvalue::get_address): Check for jit_mark_addressable return
value.
* jit-playback.h (new_bitfield): New method.
(class bitfield): New class.
(class lvalue): Add jit_mark_addressable method.
* jit-recording.c (recording::context::new_bitfield): New method.
(recording::bitfield::replay_into): New method.
(recording::bitfield::write_to_dump): Likewise.
(recording::bitfield::make_debug_string): Likewise.
(recording::bitfield::write_reproducer): Likewise.
* jit-recording.h (class context): Add new_bitfield method.
(class field): Make it derivable by class bitfield.
(class bitfield): Add new class.
* libgccjit++.h (class context): Add new_bitfield method.
* libgccjit.c (struct gcc_jit_bitfield): New structure.
(gcc_jit_context_new_bitfield): New function.
* libgccjit.h
(LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield) New macro.
(gcc_jit_context_new_bitfield): New function.
* libgccjit.map (LIBGCCJIT_ABI_12) New ABI tag.
2019-03-21 Jakub Jelinek <jakub@redhat.com> 2019-03-21 Jakub Jelinek <jakub@redhat.com>
* jit-recording.c (reproducer::m_set_identifiers): Use false as Lazy * jit-recording.c (reproducer::m_set_identifiers): Use false as Lazy
......
...@@ -177,3 +177,8 @@ entrypoints: ...@@ -177,3 +177,8 @@ entrypoints:
-------------------- --------------------
``LIBGCCJIT_ABI_11`` covers the addition of ``LIBGCCJIT_ABI_11`` covers the addition of
:func:`gcc_jit_context_add_driver_option` :func:`gcc_jit_context_add_driver_option`
``LIBGCCJIT_ABI_12``
--------------------
``LIBGCCJIT_ABI_12`` covers the addition of
:func:`gcc_jit_context_new_bitfield`
...@@ -247,6 +247,30 @@ You can model C `struct` types by creating :c:type:`gcc_jit_struct *` and ...@@ -247,6 +247,30 @@ You can model C `struct` types by creating :c:type:`gcc_jit_struct *` and
underlying string, so it is valid to pass in a pointer to an on-stack underlying string, so it is valid to pass in a pointer to an on-stack
buffer. buffer.
.. function:: gcc_jit_field *\
gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,\
gcc_jit_location *loc,\
gcc_jit_type *type,\
int width,\
const char *name)
Construct a new bit field, with the given type width and name.
The parameter ``name`` must be non-NULL. The call takes a copy of the
underlying string, so it is valid to pass in a pointer to an on-stack
buffer.
The parameter ``type`` must be an integer type.
The parameter ``width`` must be a positive integer that does not exceed the
size of ``type``.
This API entrypoint was added in :ref:`LIBGCCJIT_ABI_12`; you can test
for its presence using
.. code-block:: c
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
.. function:: gcc_jit_object *\ .. function:: gcc_jit_object *\
gcc_jit_field_as_object (gcc_jit_field *field) gcc_jit_field_as_object (gcc_jit_field *field)
......
...@@ -119,6 +119,7 @@ namespace recording { ...@@ -119,6 +119,7 @@ namespace recording {
class union_; class union_;
class vector_type; class vector_type;
class field; class field;
class bitfield;
class fields; class fields;
class function; class function;
class block; class block;
......
...@@ -47,6 +47,13 @@ along with GCC; see the file COPYING3. If not see ...@@ -47,6 +47,13 @@ along with GCC; see the file COPYING3. If not see
#include "jit-builtins.h" #include "jit-builtins.h"
#include "jit-tempdir.h" #include "jit-tempdir.h"
/* Compare with gcc/c-family/c-common.h: DECL_C_BIT_FIELD,
SET_DECL_C_BIT_FIELD.
These are redefined here to avoid depending from the C frontend. */
#define DECL_JIT_BIT_FIELD(NODE) \
(DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1)
#define SET_DECL_JIT_BIT_FIELD(NODE) \
(DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1)
/* gcc::jit::playback::context::build_cast uses the convert.h API, /* gcc::jit::playback::context::build_cast uses the convert.h API,
which in turn requires the frontend to provide a "convert" which in turn requires the frontend to provide a "convert"
...@@ -263,6 +270,46 @@ new_field (location *loc, ...@@ -263,6 +270,46 @@ new_field (location *loc,
return new field (decl); return new field (decl);
} }
/* Construct a playback::bitfield instance (wrapping a tree). */
playback::field *
playback::context::
new_bitfield (location *loc,
type *type,
int width,
const char *name)
{
gcc_assert (type);
gcc_assert (name);
gcc_assert (width);
/* compare with c/c-decl.c:grokfield, grokdeclarator and
check_bitfield_type_and_width. */
tree tree_type = type->as_tree ();
gcc_assert (INTEGRAL_TYPE_P (tree_type));
tree tree_width = build_int_cst (integer_type_node, width);
if (compare_tree_int (tree_width, TYPE_PRECISION (tree_type)) > 0)
{
add_error (
loc,
"width of bit-field %s (width: %i) is wider than its type (width: %i)",
name, width, TYPE_PRECISION (tree_type));
return NULL;
}
tree decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
get_identifier (name), type->as_tree ());
DECL_NONADDRESSABLE_P (decl) = true;
DECL_INITIAL (decl) = tree_width;
SET_DECL_JIT_BIT_FIELD (decl);
if (loc)
set_tree_location (decl, loc);
return new field (decl);
}
/* Construct a playback::compound_type instance (wrapping a tree). */ /* Construct a playback::compound_type instance (wrapping a tree). */
playback::compound_type * playback::compound_type *
...@@ -295,8 +342,15 @@ playback::compound_type::set_fields (const auto_vec<playback::field *> *fields) ...@@ -295,8 +342,15 @@ playback::compound_type::set_fields (const auto_vec<playback::field *> *fields)
for (unsigned i = 0; i < fields->length (); i++) for (unsigned i = 0; i < fields->length (); i++)
{ {
field *f = (*fields)[i]; field *f = (*fields)[i];
DECL_CONTEXT (f->as_tree ()) = t; tree x = f->as_tree ();
fieldlist = chainon (f->as_tree (), fieldlist); DECL_CONTEXT (x) = t;
if (DECL_JIT_BIT_FIELD (x))
{
unsigned HOST_WIDE_INT width = tree_to_uhwi (DECL_INITIAL (x));
DECL_SIZE (x) = bitsize_int (width);
DECL_BIT_FIELD (x) = 1;
}
fieldlist = chainon (x, fieldlist);
} }
fieldlist = nreverse (fieldlist); fieldlist = nreverse (fieldlist);
TYPE_FIELDS (t) = fieldlist; TYPE_FIELDS (t) = fieldlist;
...@@ -1197,20 +1251,31 @@ dereference (location *loc) ...@@ -1197,20 +1251,31 @@ dereference (location *loc)
return new lvalue (get_context (), datum); return new lvalue (get_context (), datum);
} }
/* Mark EXP saying that we need to be able to take the /* Mark the lvalue saying that we need to be able to take the
address of it; it should not be allocated in a register. address of it; it should not be allocated in a register.
Compare with e.g. c/c-typeck.c: c_mark_addressable. */ Compare with e.g. c/c-typeck.c: c_mark_addressable really_atomic_lvalue.
Returns false if a failure occurred (an error will already have been
added to the active context for this case). */
static void bool
jit_mark_addressable (tree exp) playback::lvalue::
mark_addressable (location *loc)
{ {
tree x = exp; tree x = as_tree ();;
while (1) while (1)
switch (TREE_CODE (x)) switch (TREE_CODE (x))
{ {
case COMPONENT_REF: case COMPONENT_REF:
/* (we don't yet support bitfields) */ if (DECL_JIT_BIT_FIELD (TREE_OPERAND (x, 1)))
{
gcc_assert (gcc::jit::active_playback_ctxt);
gcc::jit::
active_playback_ctxt->add_error (loc,
"cannot take address of "
"bit-field");
return false;
}
/* fallthrough */ /* fallthrough */
case ADDR_EXPR: case ADDR_EXPR:
case ARRAY_REF: case ARRAY_REF:
...@@ -1222,7 +1287,7 @@ jit_mark_addressable (tree exp) ...@@ -1222,7 +1287,7 @@ jit_mark_addressable (tree exp)
case COMPOUND_LITERAL_EXPR: case COMPOUND_LITERAL_EXPR:
case CONSTRUCTOR: case CONSTRUCTOR:
TREE_ADDRESSABLE (x) = 1; TREE_ADDRESSABLE (x) = 1;
return; return true;
case VAR_DECL: case VAR_DECL:
case CONST_DECL: case CONST_DECL:
...@@ -1234,7 +1299,7 @@ jit_mark_addressable (tree exp) ...@@ -1234,7 +1299,7 @@ jit_mark_addressable (tree exp)
TREE_ADDRESSABLE (x) = 1; TREE_ADDRESSABLE (x) = 1;
/* fallthrough */ /* fallthrough */
default: default:
return; return true;
} }
} }
...@@ -1251,8 +1316,10 @@ get_address (location *loc) ...@@ -1251,8 +1316,10 @@ get_address (location *loc)
tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue); tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue);
if (loc) if (loc)
get_context ()->set_tree_location (ptr, loc); get_context ()->set_tree_location (ptr, loc);
jit_mark_addressable (t_lvalue); if (mark_addressable (loc))
return new rvalue (get_context (), ptr); return new rvalue (get_context (), ptr);
else
return NULL;
} }
/* The wrapper subclasses are GC-managed, but can own non-GC memory. /* The wrapper subclasses are GC-managed, but can own non-GC memory.
......
...@@ -75,6 +75,12 @@ public: ...@@ -75,6 +75,12 @@ public:
type *type, type *type,
const char *name); const char *name);
field *
new_bitfield (location *loc,
type *type,
int width,
const char *name);
compound_type * compound_type *
new_compound_type (location *loc, new_compound_type (location *loc,
const char *name, const char *name,
...@@ -426,6 +432,8 @@ private: ...@@ -426,6 +432,8 @@ private:
tree m_inner; tree m_inner;
}; };
class bitfield : public field {};
class function : public wrapper class function : public wrapper
{ {
public: public:
...@@ -614,6 +622,8 @@ public: ...@@ -614,6 +622,8 @@ public:
rvalue * rvalue *
get_address (location *loc); get_address (location *loc);
private:
bool mark_addressable (location *loc);
}; };
class param : public lvalue class param : public lvalue
...@@ -703,4 +713,3 @@ extern playback::context *active_playback_ctxt; ...@@ -703,4 +713,3 @@ extern playback::context *active_playback_ctxt;
} // namespace gcc } // namespace gcc
#endif /* JIT_PLAYBACK_H */ #endif /* JIT_PLAYBACK_H */
...@@ -872,6 +872,24 @@ recording::context::new_field (recording::location *loc, ...@@ -872,6 +872,24 @@ recording::context::new_field (recording::location *loc,
return result; return result;
} }
/* Create a recording::bitfield instance and add it to this context's list
of mementos.
Implements the post-error-checking part of
gcc_jit_context_new_bitfield. */
recording::field *
recording::context::new_bitfield (recording::location *loc,
recording::type *type,
int width,
const char *name)
{
recording::field *result =
new recording::bitfield (this, loc, type, width, new_string (name));
record (result);
return result;
}
/* Create a recording::struct_ instance and add it to this context's /* Create a recording::struct_ instance and add it to this context's
list of mementos and list of compound types. list of mementos and list of compound types.
...@@ -2962,7 +2980,7 @@ recording::field::replay_into (replayer *r) ...@@ -2962,7 +2980,7 @@ recording::field::replay_into (replayer *r)
recording::memento::write_to_dump. Dump each field recording::memento::write_to_dump. Dump each field
by dumping a line of the form: by dumping a line of the form:
TYPE NAME; TYPE NAME;
so that we can build up a struct/union field-byfield. */ so that we can build up a struct/union field by field. */
void void
recording::field::write_to_dump (dump &d) recording::field::write_to_dump (dump &d)
...@@ -2999,6 +3017,66 @@ recording::field::write_reproducer (reproducer &r) ...@@ -2999,6 +3017,66 @@ recording::field::write_reproducer (reproducer &r)
m_name->get_debug_string ()); m_name->get_debug_string ());
} }
/* The implementation of class gcc::jit::recording::bitfield. */
/* Implementation of pure virtual hook recording::memento::replay_into
for recording::bitfield. */
void
recording::bitfield::replay_into (replayer *r)
{
set_playback_obj (r->new_bitfield (playback_location (r, m_loc),
m_type->playback_type (),
m_width,
playback_string (m_name)));
}
/* Override the default implementation of
recording::memento::write_to_dump. Dump each bit field
by dumping a line of the form:
TYPE NAME:WIDTH;
so that we can build up a struct/union field by field. */
void
recording::bitfield::write_to_dump (dump &d)
{
d.write (" %s %s:%d;\n",
m_type->get_debug_string (),
m_name->c_str (),
m_width);
}
/* Implementation of recording::memento::make_debug_string for
results of new_bitfield. */
recording::string *
recording::bitfield::make_debug_string ()
{
return string::from_printf (m_ctxt,
"%s:%d",
m_name->c_str (), m_width);
}
/* Implementation of recording::memento::write_reproducer for bitfields. */
void
recording::bitfield::write_reproducer (reproducer &r)
{
const char *id = r.make_identifier (this, "bitfield");
r.write (" gcc_jit_field *%s =\n"
" gcc_jit_context_new_bitfield (%s,\n"
" %s, /* gcc_jit_location *loc */\n"
" %s, /* gcc_jit_type *type, */\n"
" %d, /* int width, */\n"
" %s); /* const char *name */\n",
id,
r.get_identifier (get_context ()),
r.get_identifier (m_loc),
r.get_identifier_as_type (m_type),
m_width,
m_name->get_debug_string ());
}
/* The implementation of class gcc::jit::recording::compound_type */ /* The implementation of class gcc::jit::recording::compound_type */
/* The constructor for gcc::jit::recording::compound_type. */ /* The constructor for gcc::jit::recording::compound_type. */
......
...@@ -95,6 +95,12 @@ public: ...@@ -95,6 +95,12 @@ public:
type *type, type *type,
const char *name); const char *name);
field *
new_bitfield (location *loc,
type *type,
int width,
const char *name);
struct_ * struct_ *
new_struct_type (location *loc, new_struct_type (location *loc,
const char *name); const char *name);
...@@ -822,9 +828,9 @@ public: ...@@ -822,9 +828,9 @@ public:
compound_type * get_container () const { return m_container; } compound_type * get_container () const { return m_container; }
void set_container (compound_type *c) { m_container = c; } void set_container (compound_type *c) { m_container = c; }
void replay_into (replayer *) FINAL OVERRIDE; void replay_into (replayer *) OVERRIDE;
void write_to_dump (dump &d) FINAL OVERRIDE; void write_to_dump (dump &d) OVERRIDE;
playback::field * playback::field *
playback_field () const playback_field () const
...@@ -833,16 +839,41 @@ public: ...@@ -833,16 +839,41 @@ public:
} }
private: private:
string * make_debug_string () FINAL OVERRIDE; string * make_debug_string () OVERRIDE;
void write_reproducer (reproducer &r) FINAL OVERRIDE; void write_reproducer (reproducer &r) OVERRIDE;
private: protected:
location *m_loc; location *m_loc;
type *m_type; type *m_type;
string *m_name; string *m_name;
compound_type *m_container; compound_type *m_container;
}; };
class bitfield : public field
{
public:
bitfield (context *ctxt,
location *loc,
type *type,
int width,
string *name)
: field (ctxt, loc, type, name),
m_width (width)
{}
void replay_into (replayer *) FINAL OVERRIDE;
void write_to_dump (dump &d) FINAL OVERRIDE;
private:
string * make_debug_string () FINAL OVERRIDE;
void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
int m_width;
};
/* Base class for struct_ and union_ */ /* Base class for struct_ and union_ */
class compound_type : public type class compound_type : public type
{ {
......
...@@ -152,6 +152,9 @@ namespace gccjit ...@@ -152,6 +152,9 @@ namespace gccjit
field new_field (type type_, const std::string &name, field new_field (type type_, const std::string &name,
location loc = location ()); location loc = location ());
field new_bitfield (type type_, int width, const std::string &name,
location loc = location ());
struct_ new_struct_type (const std::string &name, struct_ new_struct_type (const std::string &name,
std::vector<field> &fields, std::vector<field> &fields,
location loc = location ()); location loc = location ());
...@@ -757,6 +760,17 @@ context::new_field (type type_, const std::string &name, location loc) ...@@ -757,6 +760,17 @@ context::new_field (type type_, const std::string &name, location loc)
name.c_str ())); name.c_str ()));
} }
inline field
context::new_bitfield (type type_, int width, const std::string &name,
location loc)
{
return field (gcc_jit_context_new_bitfield (m_inner_ctxt,
loc.get_inner_location (),
type_.get_inner_type (),
width,
name.c_str ()));
}
inline struct_ inline struct_
context::new_struct_type (const std::string &name, context::new_struct_type (const std::string &name,
std::vector<field> &fields, std::vector<field> &fields,
......
...@@ -62,6 +62,10 @@ struct gcc_jit_field : public gcc::jit::recording::field ...@@ -62,6 +62,10 @@ struct gcc_jit_field : public gcc::jit::recording::field
{ {
}; };
struct gcc_jit_bitfield : public gcc::jit::recording::bitfield
{
};
struct gcc_jit_function : public gcc::jit::recording::function struct gcc_jit_function : public gcc::jit::recording::function
{ {
}; };
...@@ -556,6 +560,42 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt, ...@@ -556,6 +560,42 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
/* Public entrypoint. See description in libgccjit.h. /* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the
gcc::jit::recording::context::new_bitfield method, in
jit-recording.c. */
gcc_jit_field *
gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
gcc_jit_location *loc,
gcc_jit_type *type,
int width,
const char *name)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
JIT_LOG_FUNC (ctxt->get_logger ());
/* LOC can be NULL. */
RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
RETURN_NULL_IF_FAIL_PRINTF2 (type->is_int () || type->is_bool (),
ctxt, loc,
"bit-field %s has non integral type %s",
name, type->get_debug_string ());
RETURN_NULL_IF_FAIL_PRINTF2 (
width > 0, ctxt, loc,
"invalid width %d for bitfield \"%s\" (must be > 0)",
width, name);
RETURN_NULL_IF_FAIL_PRINTF2 (
type->has_known_size (),
ctxt, loc,
"unknown size for field \"%s\" (type: %s)",
name,
type->get_debug_string ());
return (gcc_jit_field *)ctxt->new_bitfield (loc, type, width, name);
}
/* Public entrypoint. See description in libgccjit.h.
After error-checking, this calls the trivial After error-checking, this calls the trivial
gcc::jit::recording::memento::as_object method (a field is a gcc::jit::recording::memento::as_object method (a field is a
memento), in jit-recording.h. */ memento), in jit-recording.h. */
......
...@@ -602,6 +602,21 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt, ...@@ -602,6 +602,21 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
gcc_jit_type *type, gcc_jit_type *type,
const char *name); const char *name);
#define LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
/* Create a bit field, for use within a struct or union.
This API entrypoint was added in LIBGCCJIT_ABI_12; you can test for its
presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
*/
extern gcc_jit_field *
gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
gcc_jit_location *loc,
gcc_jit_type *type,
int width,
const char *name);
/* Upcasting from field to object. */ /* Upcasting from field to object. */
extern gcc_jit_object * extern gcc_jit_object *
gcc_jit_field_as_object (gcc_jit_field *field); gcc_jit_field_as_object (gcc_jit_field *field);
......
...@@ -174,4 +174,9 @@ LIBGCCJIT_ABI_10 { ...@@ -174,4 +174,9 @@ LIBGCCJIT_ABI_10 {
LIBGCCJIT_ABI_11 { LIBGCCJIT_ABI_11 {
global: global:
gcc_jit_context_add_driver_option; gcc_jit_context_add_driver_option;
} LIBGCCJIT_ABI_10; } LIBGCCJIT_ABI_10;
\ No newline at end of file
LIBGCCJIT_ABI_12 {
global:
gcc_jit_context_new_bitfield;
} LIBGCCJIT_ABI_11;
\ No newline at end of file
2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* jit.dg/all-non-failing-tests.h: Add test-accessing-bitfield.c.
* jit.dg/test-accessing-bitfield.c: New testcase.
* jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c:
Likewise.
* jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c:
Likewise.
* jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c:
Likewise.
2019-07-04 Jan Hubicka <jh@suse.cz> 2019-07-04 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/alias-access-path-3.c: New testcase. * gcc.dg/tree-ssa/alias-access-path-3.c: New testcase.
...@@ -122,7 +133,7 @@ ...@@ -122,7 +133,7 @@
PR tree-optimization/91033 PR tree-optimization/91033
* gcc.target/i386/pr91033.c: New test. * gcc.target/i386/pr91033.c: New test.
2019-07-03 Bob Duff <duff@adacore.com> 2019-07-03 Bob Duff <duff@adacore.com>
* gnat.dg/task2.adb, gnat.dg/task2_pkg.adb, * gnat.dg/task2.adb, gnat.dg/task2_pkg.adb,
......
...@@ -8,6 +8,13 @@ ...@@ -8,6 +8,13 @@
hooks provided by each test case. */ hooks provided by each test case. */
#define COMBINED_TEST #define COMBINED_TEST
/* test-accessing-bitfield.c */
#define create_code create_code_accessing_bitfield
#define verify_code verify_code_accessing_bitfield
#include "test-accessing-bitfield.c"
#undef create_code
#undef verify_code
/* test-accessing-struct.c */ /* test-accessing-struct.c */
#define create_code create_code_accessing_struct #define create_code create_code_accessing_struct
#define verify_code verify_code_accessing_struct #define verify_code verify_code_accessing_struct
...@@ -266,6 +273,9 @@ struct testcase ...@@ -266,6 +273,9 @@ struct testcase
}; };
const struct testcase testcases[] = { const struct testcase testcases[] = {
{"accessing_bitfield",
create_code_accessing_bitfield,
verify_code_accessing_bitfield},
{"accessing_struct", {"accessing_struct",
create_code_accessing_struct, create_code_accessing_struct,
verify_code_accessing_struct}, verify_code_accessing_struct},
......
#include <stdlib.h>
#include <stdio.h>
#include "libgccjit.h"
#include "harness.h"
struct bit_foo
{
int i:3;
int x:5;
int y:5;
int z:10;
int j:3;
};
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
/* Let's try to inject the equivalent of:
void
test_bitfield_access (struct bit_foo *f)
{
f->z = f->x + f->y;
}
*/
gcc_jit_type *void_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
gcc_jit_type *int_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
gcc_jit_field *i =
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
3,
"i");
gcc_jit_field *x =
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
5,
"x");
gcc_jit_field *y =
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
5,
"y");
gcc_jit_field *z =
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
10,
"z");
gcc_jit_field *j =
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
3,
"j");
gcc_jit_field *fields[] = {i, x, y, z, j};
gcc_jit_struct *struct_type =
gcc_jit_context_new_struct_type (ctxt, NULL, "bit_foo", 5, fields);
gcc_jit_type *ptr_type =
gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type));
/* Build the test function. */
gcc_jit_param *param_f =
gcc_jit_context_new_param (ctxt, NULL, ptr_type, "f");
gcc_jit_function *test_fn =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_EXPORTED,
void_type,
"test_bitfield_access",
1, &param_f,
0);
/* f->x + f->y */
gcc_jit_rvalue *sum =
gcc_jit_context_new_binary_op (
ctxt, NULL,
GCC_JIT_BINARY_OP_PLUS,
int_type,
gcc_jit_lvalue_as_rvalue (
gcc_jit_rvalue_dereference_field (
gcc_jit_param_as_rvalue (param_f),
NULL,
x)),
gcc_jit_lvalue_as_rvalue (
gcc_jit_rvalue_dereference_field (
gcc_jit_param_as_rvalue (param_f),
NULL,
y)));
/* f->z = ... */
gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
gcc_jit_block_add_assignment (
block,
NULL,
gcc_jit_rvalue_dereference_field (
gcc_jit_param_as_rvalue (param_f),
NULL,
z),
sum);
gcc_jit_block_end_with_void_return (block, NULL);
}
void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
typedef void (*fn_type) (struct bit_foo *);
CHECK_NON_NULL (result);
fn_type test_bitfield_access =
(fn_type)gcc_jit_result_get_code (result, "test_bitfield_access");
CHECK_NON_NULL (test_bitfield_access);
struct bit_foo tmp;
tmp.i = 3;
tmp.x = 5;
tmp.y = 7;
tmp.z = 0;
tmp.j = 3;
/* Call the JIT-generated function. */
test_bitfield_access (&tmp);
/* Verify that the code correctly modified the field "z". */
CHECK_VALUE (tmp.z, 12);
}
#include <stdlib.h>
#include <stdio.h>
#include "libgccjit.h"
#include "harness.h"
/* Try to declare a bit-field with invalid type. */
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
gcc_jit_type *bool_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL);
gcc_jit_type *int_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
gcc_jit_type *long_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG);
gcc_jit_type *float_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
gcc_jit_context_new_bitfield (ctxt,
NULL,
bool_type,
3,
"b");
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
3,
"i");
gcc_jit_context_new_bitfield (ctxt,
NULL,
long_type,
3,
"l");
gcc_jit_context_new_bitfield (ctxt,
NULL,
float_type,
5,
"f");
}
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),
"gcc_jit_context_new_bitfield: bit-field f has non "
"integral type float");
}
#include <stdlib.h>
#include <stdio.h>
#include "libgccjit.h"
#include "harness.h"
/* Try to declare a bit-field with invalid width. */
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
gcc_jit_type *short_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SHORT);
gcc_jit_field *i =
gcc_jit_context_new_bitfield (ctxt,
NULL,
short_type,
3,
"i");
gcc_jit_field *j =
gcc_jit_context_new_bitfield (ctxt,
NULL,
short_type,
157,
"j");
gcc_jit_field *fields[] = {i, j};
gcc_jit_context_new_struct_type (ctxt, NULL, "bit_foo", 2, fields);
}
void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
CHECK_VALUE (result, NULL);
char error_str[256];
snprintf (error_str, sizeof (error_str),
"width of bit-field j (width: 157) is wider than its type "
"(width: %zu)", 8 * sizeof (short));
/* Verify that the correct error message was emitted. */
CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
error_str);
}
#include <stdlib.h>
#include <stdio.h>
#include "libgccjit.h"
#include "harness.h"
/* Try to dereference a bit-field. */
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
/* Let's try to inject the equivalent of:
struct bit_foo
{
int i:3;
int j:3;
};
struct bit_foo f;
&(f.j)
*/
gcc_jit_type *int_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
gcc_jit_field *i =
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
3,
"i");
gcc_jit_field *j =
gcc_jit_context_new_bitfield (ctxt,
NULL,
int_type,
3,
"j");
gcc_jit_field *fields[] = {i, j};
gcc_jit_type *struct_type =
gcc_jit_struct_as_type (
gcc_jit_context_new_struct_type (ctxt, NULL, "bit_foo", 2, fields));
gcc_jit_lvalue *f_struct =
gcc_jit_context_new_global (ctxt,
NULL,
GCC_JIT_GLOBAL_INTERNAL,
struct_type,
"f");
gcc_jit_lvalue_get_address (
gcc_jit_lvalue_access_field (
f_struct,
NULL,
j),
NULL);
}
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),
"cannot take address of bit-field");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment