Fixed Objective-C dotsyntax with a constant type right-hand side
From-SVN: r170342
This commit is contained in:
parent
869b0af5c5
commit
3890ce93e2
5 changed files with 99 additions and 27 deletions
|
@ -1,3 +1,9 @@
|
|||
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.
|
||||
|
|
|
@ -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
|
||||
compound statement which does the setter call (to set the
|
||||
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)
|
||||
|
||||
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
|
||||
compound expression. */
|
||||
tree s1, s2, s3, compound_expr;
|
||||
|
||||
/* TODO: If 'rhs' is a constant, we could maybe do without the
|
||||
'temp' variable ? */
|
||||
|
||||
/* Declare __objc_property_temp in a local bind. */
|
||||
temp_variable_decl = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
|
||||
DECL_SOURCE_LOCATION (temp_variable_decl) = input_location;
|
||||
bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
|
||||
SET_EXPR_LOCATION (bind, input_location);
|
||||
TREE_SIDE_EFFECTS (bind) = 1;
|
||||
add_stmt (bind);
|
||||
if (TREE_SIDE_EFFECTS (rhs))
|
||||
{
|
||||
tree bind;
|
||||
|
||||
/* Declare __objc_property_temp in a local bind. */
|
||||
setter_argument = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
|
||||
DECL_SOURCE_LOCATION (setter_argument) = input_location;
|
||||
bind = build3 (BIND_EXPR, void_type_node, setter_argument, NULL, NULL);
|
||||
SET_EXPR_LOCATION (bind, input_location);
|
||||
TREE_SIDE_EFFECTS (bind) = 1;
|
||||
add_stmt (bind);
|
||||
|
||||
/* s1: x = rhs */
|
||||
s1 = build_modify_expr (input_location, setter_argument, NULL_TREE,
|
||||
NOP_EXPR,
|
||||
input_location, rhs, NULL_TREE);
|
||||
SET_EXPR_LOCATION (s1, input_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No s1. */
|
||||
setter_argument = rhs;
|
||||
s1 = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Now build the compound statement. */
|
||||
|
||||
/* s1: __objc_property_temp = rhs */
|
||||
s1 = build_modify_expr (input_location, temp_variable_decl, NULL_TREE,
|
||||
NOP_EXPR,
|
||||
input_location, rhs, NULL_TREE);
|
||||
SET_EXPR_LOCATION (s1, input_location);
|
||||
|
||||
/* s2: [object setProperty: __objc_property_temp] */
|
||||
s2 = objc_build_setter_call (lhs, temp_variable_decl);
|
||||
|
||||
/* This happens if building the setter failed because the property
|
||||
is readonly. */
|
||||
/* s2: [object setProperty: x] */
|
||||
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)
|
||||
return error_mark_node;
|
||||
|
||||
SET_EXPR_LOCATION (s2, input_location);
|
||||
|
||||
/* s3: __objc_property_temp */
|
||||
s3 = convert (TREE_TYPE (lhs), temp_variable_decl);
|
||||
/* s3: x */
|
||||
s3 = convert (TREE_TYPE (lhs), setter_argument);
|
||||
|
||||
/* Now build the compound statement (s1, s2, s3) */
|
||||
compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, 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);
|
||||
else
|
||||
compound_expr = build_compound_expr (input_location, s2, s3);
|
||||
|
||||
/* Without this, with -Wall you get a 'valued computed is not
|
||||
used' every time there is a "object.property = x" where the
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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>
|
||||
|
||||
PR c++/46394
|
||||
|
|
19
gcc/testsuite/obj-c++.dg/property/dotsyntax-22.mm
Normal file
19
gcc/testsuite/obj-c++.dg/property/dotsyntax-22.mm
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* 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;
|
||||
}
|
||||
|
19
gcc/testsuite/objc.dg/property/dotsyntax-22.m
Normal file
19
gcc/testsuite/objc.dg/property/dotsyntax-22.m
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* 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;
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue