Commit 3890ce93 by Nicola Pero Committed by Nicola Pero

Fixed Objective-C dotsyntax with a constant type right-hand side

From-SVN: r170342
parent 869b0af5
2011-01-19 Nicola Pero <nicola.pero@meta-innovation.com> 2011-01-19 Nicola Pero <nicola.pero@meta-innovation.com>
PR objc/47784
* objc-act.c (objc_maybe_build_modify_expr): If 'rhs' has side
effects, do not use a temporary variable.
2011-01-19 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-next-runtime-abi-01.c: Updated comments. * objc-next-runtime-abi-01.c: Updated comments.
* objc-next-runtime-abi-02.c: Same. * objc-next-runtime-abi-02.c: Same.
......
...@@ -1790,49 +1790,71 @@ objc_maybe_build_modify_expr (tree lhs, tree rhs) ...@@ -1790,49 +1790,71 @@ objc_maybe_build_modify_expr (tree lhs, tree rhs)
to get these to work with very little effort, we build a to get these to work with very little effort, we build a
compound statement which does the setter call (to set the compound statement which does the setter call (to set the
property to 'rhs'), but which can also be evaluated returning property to 'rhs'), but which can also be evaluated returning
the 'rhs'. So, we want to create the following: the 'rhs'. If the 'rhs' has no side effects, we can simply
evaluate it twice, building
([object setProperty: rhs]; rhs)
If it has side effects, we put it in a temporary variable first,
so we create the following:
(temp = rhs; [object setProperty: temp]; temp) (temp = rhs; [object setProperty: temp]; temp)
setter_argument is rhs in the first case, and temp in the second
case.
*/ */
tree temp_variable_decl, bind; tree setter_argument;
/* s1, s2 and s3 are the tree statements that we need in the /* s1, s2 and s3 are the tree statements that we need in the
compound expression. */ compound expression. */
tree s1, s2, s3, compound_expr; tree s1, s2, s3, compound_expr;
/* TODO: If 'rhs' is a constant, we could maybe do without the if (TREE_SIDE_EFFECTS (rhs))
'temp' variable ? */ {
tree bind;
/* Declare __objc_property_temp in a local bind. */ /* Declare __objc_property_temp in a local bind. */
temp_variable_decl = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp"); setter_argument = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
DECL_SOURCE_LOCATION (temp_variable_decl) = input_location; DECL_SOURCE_LOCATION (setter_argument) = input_location;
bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL); bind = build3 (BIND_EXPR, void_type_node, setter_argument, NULL, NULL);
SET_EXPR_LOCATION (bind, input_location); SET_EXPR_LOCATION (bind, input_location);
TREE_SIDE_EFFECTS (bind) = 1; TREE_SIDE_EFFECTS (bind) = 1;
add_stmt (bind); add_stmt (bind);
/* Now build the compound statement. */ /* s1: x = rhs */
s1 = build_modify_expr (input_location, setter_argument, NULL_TREE,
/* s1: __objc_property_temp = rhs */
s1 = build_modify_expr (input_location, temp_variable_decl, NULL_TREE,
NOP_EXPR, NOP_EXPR,
input_location, rhs, NULL_TREE); input_location, rhs, NULL_TREE);
SET_EXPR_LOCATION (s1, input_location); SET_EXPR_LOCATION (s1, input_location);
}
else
{
/* No s1. */
setter_argument = rhs;
s1 = NULL_TREE;
}
/* s2: [object setProperty: __objc_property_temp] */ /* Now build the compound statement. */
s2 = objc_build_setter_call (lhs, temp_variable_decl);
/* This happens if building the setter failed because the property /* s2: [object setProperty: x] */
is readonly. */ s2 = objc_build_setter_call (lhs, setter_argument);
/* This happens if building the setter failed because the
property is readonly. */
if (s2 == error_mark_node) if (s2 == error_mark_node)
return error_mark_node; return error_mark_node;
SET_EXPR_LOCATION (s2, input_location); SET_EXPR_LOCATION (s2, input_location);
/* s3: __objc_property_temp */ /* s3: x */
s3 = convert (TREE_TYPE (lhs), temp_variable_decl); s3 = convert (TREE_TYPE (lhs), setter_argument);
/* Now build the compound statement (s1, s2, s3) */ /* Now build the compound statement (s1, s2, s3) or (s2, s3) as
appropriate. */
if (s1)
compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, s1, s2), s3); compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, s1, s2), s3);
else
compound_expr = build_compound_expr (input_location, s2, s3);
/* Without this, with -Wall you get a 'valued computed is not /* Without this, with -Wall you get a 'valued computed is not
used' every time there is a "object.property = x" where the used' every time there is a "object.property = x" where the
......
2011-02-19 Nicola Pero <nicola.pero@meta-innovation.com>
PR objc/47784
* objc.dg/property/dotsyntax-22.m: New.
* obj-c++.dg/property/dotsyntax-22.mm: New.
2011-02-20 Dodji Seketeli <dodji@redhat.com> 2011-02-20 Dodji Seketeli <dodji@redhat.com>
PR c++/46394 PR c++/46394
......
/* PR objc/47784. This testcase used to crash the compiler. */
typedef struct {
float x;
} SomeType;
@interface MyClass
@property(assign,readwrite) SomeType position;
@end
void example (MyClass *x)
{
const SomeType SomeTypeZero = {0.0f};
x.position= SomeTypeZero;
}
/* PR objc/47784. This testcase used to crash the compiler. */
typedef struct {
float x;
} SomeType;
@interface MyClass
@property(assign,readwrite) SomeType position;
@end
void example (MyClass *x)
{
const SomeType SomeTypeZero = {0.0f};
x.position= SomeTypeZero;
}
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