Skip to content

Commit

Permalink
vala: Improve accessibility check inside member initializer
Browse files Browse the repository at this point in the history
  • Loading branch information
ricotz committed Apr 4, 2022
1 parent 53b003b commit f56bbc7
Show file tree
Hide file tree
Showing 9 changed files with 738 additions and 4 deletions.
4 changes: 4 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ TESTS = \
control-semantic/member-incompatible-type.test \
control-semantic/member-invalid.test \
control-semantic/member-private.test \
control-semantic/member-protected.test \
control-semantic/member-readonly.test \
control-semantic/printf-too-few.test \
control-semantic/printf-too-many.test \
Expand Down Expand Up @@ -527,8 +528,10 @@ TESTS = \
objects/member-initializer-base-properties.vala \
objects/member-initializer-chained.vala \
objects/member-initializer-chained-2.vala \
objects/member-initializer-private.vala \
objects/member-initializer-property.vala \
objects/member-initializer-property-owned-setter.vala \
objects/member-initializer-protected.vala \
objects/methods.vala \
objects/paramspec.vala \
objects/plugin-module-init.vala \
Expand Down Expand Up @@ -1150,6 +1153,7 @@ TESTS = \
semantic/member-access-capture-valist-parameter.test \
semantic/member-access-capture-valist-variable.test \
semantic/member-access-not-found.test \
semantic/member-access-private-invalid.test \
semantic/member-access-protected-invalid.test \
semantic/member-access-this-invalid.test \
semantic/member-access-undefined.test \
Expand Down
11 changes: 11 additions & 0 deletions tests/control-semantic/member-protected.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Invalid Code

class Foo {
protected string foo { get; set; }
}

void main () {
var foo = new Foo () {
foo = "foo"
};
}
329 changes: 329 additions & 0 deletions tests/objects/member-initializer-private.c-expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
/* objects_member_initializer_private.c generated by valac, the Vala compiler
* generated from objects_member_initializer_private.vala, do not modify */

#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gobject/gvaluecollector.h>

#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define TYPE_FOO (foo_get_type ())
#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_FOO, Foo))
#define FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_FOO, FooClass))
#define IS_FOO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_FOO))
#define IS_FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_FOO))
#define FOO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_FOO, FooClass))

typedef struct _Foo Foo;
typedef struct _FooClass FooClass;
typedef struct _FooPrivate FooPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _foo_unref0(var) ((var == NULL) ? NULL : (var = (foo_unref (var), NULL)))
typedef struct _ParamSpecFoo ParamSpecFoo;

struct _Foo {
GTypeInstance parent_instance;
volatile int ref_count;
FooPrivate * priv;
};

struct _FooClass {
GTypeClass parent_class;
void (*finalize) (Foo *self);
};

struct _FooPrivate {
gchar* baz;
};

struct _ParamSpecFoo {
GParamSpec parent_instance;
};

static gint Foo_private_offset;
static gpointer foo_parent_class = NULL;

VALA_EXTERN gpointer foo_ref (gpointer instance);
VALA_EXTERN void foo_unref (gpointer instance);
VALA_EXTERN GParamSpec* param_spec_foo (const gchar* name,
const gchar* nick,
const gchar* blurb,
GType object_type,
GParamFlags flags);
VALA_EXTERN void value_set_foo (GValue* value,
gpointer v_object);
VALA_EXTERN void value_take_foo (GValue* value,
gpointer v_object);
VALA_EXTERN gpointer value_get_foo (const GValue* value);
VALA_EXTERN GType foo_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Foo, foo_unref)
static void foo_bar (Foo* self);
VALA_EXTERN Foo* foo_new (void);
VALA_EXTERN Foo* foo_construct (GType object_type);
static void foo_finalize (Foo * obj);
static GType foo_get_type_once (void);
static void _vala_main (void);

static inline gpointer
foo_get_instance_private (Foo* self)
{
return G_STRUCT_MEMBER_P (self, Foo_private_offset);
}

static void
foo_bar (Foo* self)
{
Foo* foo = NULL;
const gchar* _tmp0_;
gchar* _tmp1_;
Foo* _tmp2_ = NULL;
g_return_if_fail (IS_FOO (self));
_tmp0_ = self->priv->baz;
_tmp1_ = g_strdup (_tmp0_);
_tmp2_ = foo_new ();
_g_free0 (_tmp2_->priv->baz);
_tmp2_->priv->baz = _tmp1_;
foo = _tmp2_;
_foo_unref0 (foo);
}

Foo*
foo_construct (GType object_type)
{
Foo* self = NULL;
self = (Foo*) g_type_create_instance (object_type);
return self;
}

Foo*
foo_new (void)
{
return foo_construct (TYPE_FOO);
}

static void
value_foo_init (GValue* value)
{
value->data[0].v_pointer = NULL;
}

static void
value_foo_free_value (GValue* value)
{
if (value->data[0].v_pointer) {
foo_unref (value->data[0].v_pointer);
}
}

static void
value_foo_copy_value (const GValue* src_value,
GValue* dest_value)
{
if (src_value->data[0].v_pointer) {
dest_value->data[0].v_pointer = foo_ref (src_value->data[0].v_pointer);
} else {
dest_value->data[0].v_pointer = NULL;
}
}

static gpointer
value_foo_peek_pointer (const GValue* value)
{
return value->data[0].v_pointer;
}

static gchar*
value_foo_collect_value (GValue* value,
guint n_collect_values,
GTypeCValue* collect_values,
guint collect_flags)
{
if (collect_values[0].v_pointer) {
Foo * object;
object = collect_values[0].v_pointer;
if (object->parent_instance.g_class == NULL) {
return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
}
value->data[0].v_pointer = foo_ref (object);
} else {
value->data[0].v_pointer = NULL;
}
return NULL;
}

static gchar*
value_foo_lcopy_value (const GValue* value,
guint n_collect_values,
GTypeCValue* collect_values,
guint collect_flags)
{
Foo ** object_p;
object_p = collect_values[0].v_pointer;
if (!object_p) {
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
}
if (!value->data[0].v_pointer) {
*object_p = NULL;
} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
*object_p = value->data[0].v_pointer;
} else {
*object_p = foo_ref (value->data[0].v_pointer);
}
return NULL;
}

GParamSpec*
param_spec_foo (const gchar* name,
const gchar* nick,
const gchar* blurb,
GType object_type,
GParamFlags flags)
{
ParamSpecFoo* spec;
g_return_val_if_fail (g_type_is_a (object_type, TYPE_FOO), NULL);
spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
G_PARAM_SPEC (spec)->value_type = object_type;
return G_PARAM_SPEC (spec);
}

gpointer
value_get_foo (const GValue* value)
{
g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_FOO), NULL);
return value->data[0].v_pointer;
}

void
value_set_foo (GValue* value,
gpointer v_object)
{
Foo * old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_FOO));
old = value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_FOO));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
value->data[0].v_pointer = v_object;
foo_ref (value->data[0].v_pointer);
} else {
value->data[0].v_pointer = NULL;
}
if (old) {
foo_unref (old);
}
}

void
value_take_foo (GValue* value,
gpointer v_object)
{
Foo * old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_FOO));
old = value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_FOO));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
value->data[0].v_pointer = v_object;
} else {
value->data[0].v_pointer = NULL;
}
if (old) {
foo_unref (old);
}
}

static void
foo_class_init (FooClass * klass,
gpointer klass_data)
{
foo_parent_class = g_type_class_peek_parent (klass);
((FooClass *) klass)->finalize = foo_finalize;
g_type_class_adjust_private_offset (klass, &Foo_private_offset);
}

static void
foo_instance_init (Foo * self,
gpointer klass)
{
self->priv = foo_get_instance_private (self);
self->ref_count = 1;
}

static void
foo_finalize (Foo * obj)
{
Foo * self;
self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_FOO, Foo);
g_signal_handlers_destroy (self);
_g_free0 (self->priv->baz);
}

static GType
foo_get_type_once (void)
{
static const GTypeValueTable g_define_type_value_table = { value_foo_init, value_foo_free_value, value_foo_copy_value, value_foo_peek_pointer, "p", value_foo_collect_value, "p", value_foo_lcopy_value };
static const GTypeInfo g_define_type_info = { sizeof (FooClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) foo_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Foo), 0, (GInstanceInitFunc) foo_instance_init, &g_define_type_value_table };
static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
GType foo_type_id;
foo_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Foo", &g_define_type_info, &g_define_type_fundamental_info, 0);
Foo_private_offset = g_type_add_instance_private (foo_type_id, sizeof (FooPrivate));
return foo_type_id;
}

GType
foo_get_type (void)
{
static volatile gsize foo_type_id__once = 0;
if (g_once_init_enter (&foo_type_id__once)) {
GType foo_type_id;
foo_type_id = foo_get_type_once ();
g_once_init_leave (&foo_type_id__once, foo_type_id);
}
return foo_type_id__once;
}

gpointer
foo_ref (gpointer instance)
{
Foo * self;
self = instance;
g_atomic_int_inc (&self->ref_count);
return instance;
}

void
foo_unref (gpointer instance)
{
Foo * self;
self = instance;
if (g_atomic_int_dec_and_test (&self->ref_count)) {
FOO_GET_CLASS (self)->finalize (self);
g_type_free_instance ((GTypeInstance *) self);
}
}

static void
_vala_main (void)
{
}

int
main (int argc,
char ** argv)
{
_vala_main ();
return 0;
}

12 changes: 12 additions & 0 deletions tests/objects/member-initializer-private.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Foo {
private string baz;

void bar () {
var foo = new Foo () {
baz = baz
};
}
}

void main () {
}
Loading

0 comments on commit f56bbc7

Please sign in to comment.