Skip to content

Commit

Permalink
Only output dimension information for struct members that are passed …
Browse files Browse the repository at this point in the history
…by reference
  • Loading branch information
positively-charged committed May 15, 2017
1 parent 593e994 commit f4b3c32
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/codegen/phase.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static void setup_diminfo( struct codegen* codegen ) {
struct structure* structure = list_data( &i );
struct structure_member* member = structure->member;
while ( member ) {
if ( member->dim ) {
if ( member->dim && member->addr_taken ) {
member->diminfo_start = append_dim( codegen, member->dim );
}
member = member->next;
Expand Down
10 changes: 8 additions & 2 deletions src/semantic/dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1391,13 +1391,16 @@ static bool test_scalar_initz( struct semantic* semantic,
value->type = VALUE_FUNC;
}
if ( s_is_ref_type( &test->initz_type ) && expr.var ) {
expr.var->addr_taken = true;
if ( ! expr.var->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &value->expr->pos,
"non-private initializer (references only work with private map "
"variables)" );
s_bail( semantic );
}
expr.var->addr_taken = true;
if ( expr.structure_member ) {
expr.structure_member->addr_taken = true;
}
}
return true;
}
Expand Down Expand Up @@ -2145,13 +2148,16 @@ static bool test_param_default_value( struct semantic* semantic,
s_bail( semantic );
}
if ( s_is_ref_type( &expr.type ) && expr.var ) {
expr.var->addr_taken = true;
if ( ! expr.var->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &param->default_value->pos,
"non-private default argument (references only work with private "
"map variables)" );
s_bail( semantic );
}
expr.var->addr_taken = true;
if ( expr.structure_member ) {
expr.structure_member->addr_taken = true;
}
}
param->default_value_tested = true;
return true;
Expand Down
26 changes: 22 additions & 4 deletions src/semantic/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ struct result {
struct type_info type;
struct func* func;
struct var* data_origin;
struct structure_member* data_origin_member;
struct object* object;
struct dim* dim;
int value;
Expand Down Expand Up @@ -263,6 +264,7 @@ void s_init_expr_test( struct expr_test* test, bool result_required,
s_init_type_info_scalar( &test->type, SPEC_VOID );
test->name_offset = NULL;
test->var = NULL;
test->structure_member = NULL;
test->func = NULL;
test->result_required = result_required;
test->has_str = false;
Expand Down Expand Up @@ -335,6 +337,7 @@ static void test_root_with_result( struct semantic* semantic,
s_bail( semantic );
}
test->var = result->data_origin;
test->structure_member = result->data_origin_member;
test->func = result->func;
expr->spec = result->type.spec;
expr->folded = result->folded;
Expand All @@ -347,6 +350,7 @@ static void init_result( struct result* result ) {
s_init_type_info_scalar( &result->type, SPEC_VOID );
result->func = NULL;
result->data_origin = NULL;
result->data_origin_member = NULL;
result->object = NULL;
result->dim = NULL;
result->value = 0;
Expand Down Expand Up @@ -932,13 +936,16 @@ static void test_assign( struct semantic* semantic, struct expr_test* test,
s_bail( semantic );
}
if ( s_is_ref_type( &lside.type ) && rside.data_origin ) {
rside.data_origin->addr_taken = true;
if ( ! rside.data_origin->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &assign->pos,
"non-private right operand (references only work with private map "
"variables)" );
s_bail( semantic );
}
rside.data_origin->addr_taken = true;
if ( rside.data_origin_member ) {
rside.data_origin_member->addr_taken = true;
}
}
// Record the fact that the object was modified.
if ( lside.object ) {
Expand Down Expand Up @@ -1124,23 +1131,29 @@ static void test_conditional( struct semantic* semantic,
cond->left_spec = left.type.spec;
if ( s_is_ref_type( &middle.type ) ) {
if ( middle.data_origin ) {
middle.data_origin->addr_taken = true;
if ( ! middle.data_origin->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &cond->pos,
"non-private %s (references only work with private "
"map variables)", cond->middle ? "middle operand" :
"left operand" );
s_bail( semantic );
}
middle.data_origin->addr_taken = true;
if ( middle.data_origin_member ) {
middle.data_origin_member->addr_taken = true;
}
}
if ( right.data_origin ) {
right.data_origin->addr_taken = true;
if ( ! right.data_origin->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &cond->pos,
"non-private right operand (references only work with private "
"map variables)" );
s_bail( semantic );
}
right.data_origin->addr_taken = true;
if ( right.data_origin_member ) {
right.data_origin_member->addr_taken = true;
}
}
}
// Compile-time evaluation.
Expand Down Expand Up @@ -2184,13 +2197,16 @@ static void test_remaining_arg( struct semantic* semantic,
}
++test->num_args;
if ( s_is_ref_type( &arg.type ) && arg.var ) {
arg.var->addr_taken = true;
if ( ! arg.var->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &expr->pos,
"non-private argument (references only work with private "
"map variables)" );
s_bail( semantic );
}
arg.var->addr_taken = true;
if ( arg.structure_member ) {
arg.structure_member->addr_taken = true;
}
}
if ( test->call->constant && ! expr->folded ) {
s_diag( semantic, DIAG_POS_ERR, &expr->pos,
Expand Down Expand Up @@ -2772,6 +2788,7 @@ static void select_structure_member( struct semantic* semantic,
s_decay( semantic, &result->type );
result->dim = member->dim;
result->data_origin = lside->data_origin;
result->data_origin_member = member;
}
// Reference member.
else if ( member->ref ) {
Expand All @@ -2785,6 +2802,7 @@ static void select_structure_member( struct semantic* semantic,
member->spec, storage );
s_decay( semantic, &result->type );
result->data_origin = lside->data_origin;
result->data_origin_member = member;
}
// Primitive member.
else {
Expand Down
1 change: 1 addition & 0 deletions src/semantic/phase.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct expr_test {
struct buildmsg* buildmsg;
struct name* name_offset;
struct var* var;
struct structure_member* structure_member;
struct func* func;
union {
struct ref ref;
Expand Down
10 changes: 8 additions & 2 deletions src/semantic/stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,13 +768,16 @@ static void test_foreach( struct semantic* semantic, struct stmt_test* test,
s_bail( semantic );
}
if ( s_is_ref_type( &iter.value ) && expr.var ) {
expr.var->addr_taken = true;
if ( ! expr.var->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &stmt->collection->pos,
"non-private collection (references only work with private map "
"variables)" );
s_bail( semantic );
}
expr.var->addr_taken = true;
if ( expr.structure_member ) {
expr.structure_member->addr_taken = true;
}
}
// Key.
if ( stmt->key ) {
Expand Down Expand Up @@ -979,13 +982,16 @@ static void test_return_value( struct semantic* semantic,
}
}
if ( s_is_ref_type( &expr.type ) && expr.var ) {
expr.var->addr_taken = true;
if ( ! expr.var->hidden ) {
s_diag( semantic, DIAG_POS_ERR, &stmt->return_value->pos,
"non-private return-value (references only work with private map "
"variables)" );
s_bail( semantic );
}
expr.var->addr_taken = true;
if ( expr.structure_member ) {
expr.structure_member->addr_taken = true;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,7 @@ struct structure_member* t_alloc_structure_member( void ) {
member->size = 0;
member->diminfo_start = 0;
member->head_instance = false;
member->addr_taken = false;
return member;
}

Expand Down
1 change: 1 addition & 0 deletions src/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ struct structure_member {
int size;
int diminfo_start;
bool head_instance;
bool addr_taken;
};

struct ref {
Expand Down

0 comments on commit f4b3c32

Please sign in to comment.