Fixed Objective-C dotsyntax with a constant type right-hand side
authorNicola Pero <nicola.pero@meta-innovation.com>
Sun, 20 Feb 2011 17:41:36 +0000 (17:41 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Sun, 20 Feb 2011 17:41:36 +0000 (17:41 +0000)
From-SVN: r170342

gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/property/dotsyntax-22.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/property/dotsyntax-22.m [new file with mode: 0644]

index eda00dfdd9a5c912c23d221ccf7e4dec661a52fa..9b92980db56a6d373054c2b1d20dcaa1c5e216c8 100644 (file)
@@ -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.
index 7a329219f38c553900eda15eaad9e963e27cfc60..0cabc52b3b66a7e75471e32a1976b4c41fde08c7 100644 (file)
@@ -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;
+
+      if (TREE_SIDE_EFFECTS (rhs))
+       {
+         tree bind;
       
-      /* 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);
+         /* 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
index ff5650a0815a6a148271c9865146fbc86990092a..6c422367072610cfab2f5a00a454ed34d6d82289 100644 (file)
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-22.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-22.mm
new file mode 100644 (file)
index 0000000..cc58348
--- /dev/null
@@ -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;
+}
+
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-22.m b/gcc/testsuite/objc.dg/property/dotsyntax-22.m
new file mode 100644 (file)
index 0000000..cc58348
--- /dev/null
@@ -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;
+}
+