Yet more Objective-C++...

* cp-objcp-common.h (cxx_get_alias_set): Move from
        here...
        (cxx_warn_unused_global_decl): Likewise.
        (cp_expr_size): Likewise.
        (cp_tree_size): Likewise.
        (cp_var_mod_type_p): Likewise.
        (cxx_initialize_diagnostics): Likewise.
        (cxx_types_compatible_p): Likewise.
        * cp-tree.h: to here.
        (do_poplevel): Add.
        * lex.c (D_OBJC): Add.
        (init_reswords): Add.
        * Make-lang.in (cp/pt.o): Add cp/cp-objcp-common.h.
        * parser.c: Add c-common.h include.
        * pt.c: Add c-common.h and cp-objcp-common.h includes.
        (template_args_equal): Use objc_comptypes as well.
        (tsubst_copy_and_build): Use objcp_tsubst_copy_and_build as well.
        * semantics.c (do_poplevel): Remove static.

        * decl.c (objc_mark_locals_volatile): Don't change decls that are
        already ok.
        * decl2.c (generate_ctor_or_dtor_function): Add code to initialize
        Objective C++ early enough.
        * lex.c (struct resword reswords): Add Objective-C++ support.
        * parser.c (cp_lexer_get_preprocessor_token): Add Objective-C++.
        (cp_parser_objc_message_receiver): Add.
        (cp_parser_objc_message_args): Likewise.
        (cp_parser_objc_message_expression): Likewise.
        (cp_parser_objc_encode_expression): Likewise.
        (cp_parser_objc_defs_expression): Likewise.
        (cp_parser_objc_protocol_expression): Likewise.
        (cp_parser_objc_selector_expression): Likewise.
        (cp_parser_objc_expression): Likewise.
        (cp_parser_objc_visibility_spec): Likewise.
        (cp_parser_objc_method_type): Likewise.
        (cp_parser_objc_protocol_qualifiers): Likewise.
        (cp_parser_objc_typename): Likewise.
        (cp_parser_objc_selector_p): Likewise.
        (cp_parser_objc_selector): Likewise.
        (cp_parser_objc_method_keyword_params): Likewise.
        (cp_parser_objc_method_tail_params_opt): Likewise.
        (cp_parser_objc_interstitial_code): Likewise.
        (cp_parser_objc_method_signature): Likewise.
        (cp_parser_objc_method_prototype_list): Likewise.
        (cp_parser_objc_method_definition_list): Likewise.
        (cp_parser_objc_class_ivars): Likewise.
        (cp_parser_objc_identifier_list): Likewise.
        (cp_parser_objc_alias_declaration): Likewise.
        (cp_parser_objc_class_declaration): Likewise.
        (cp_parser_objc_protocol_declaration): Likewise.
        (cp_parser_objc_protocol_refs_opt): Likewise.
        (cp_parser_objc_superclass_or_category): Likewise.
        (cp_parser_objc_class_interface): Likewise.
        (cp_parser_objc_class_implementation): Likewise.
        (cp_parser_objc_end_implementation): Likewise.
        (cp_parser_objc_declaration): Likewise.
        (cp_parser_objc_try_catch_finally_statement): Likewise.
        (cp_parser_objc_synchronized_statement): Likewise.
        (cp_parser_objc_throw_statement): Likewise.
        (cp_parser_objc_statement): Likewise.
        (cp_parser_primary_expression): Add Objective-C++.
        (cp_parser_statement): Likewise.
        (cp_parser_declaration): Likewise.
        (cp_parser_simple_type_specifier): Likewise.
        (cp_parser_type_name): Likewise.
        (cp_parser_parameter_declaration_list): Likewise.
        (cp_parser_member_declaration) Likewise.
        * tree.c: Include debug.h.
        * typeck.c (composite_pointer_type): Add Objective-C++ support.
        (finish_class_member_access_expr): Likewise.
        (build_function_call): Allow objc to rewrite FUNCTION_DECLs.
        (build_modify_expr): Allow objc to generate write barriers.

        * Make-lang.in (cp/tree.o): Add debug.h.
        * tree.c (lvalue_p_1, case CONST_DECL): Add.

From-SVN: r99855
This commit is contained in:
Ziemowit Laski 2005-05-17 20:05:24 +00:00 committed by Mike Stump
parent b4838d2947
commit e58a9aa1f6
12 changed files with 1431 additions and 23 deletions

View File

@ -1,3 +1,83 @@
2005-05-17 Mike Stump <mrs@apple.com>
Yet more Objective-C++...
* cp-objcp-common.h (cxx_get_alias_set): Move from
here...
(cxx_warn_unused_global_decl): Likewise.
(cp_expr_size): Likewise.
(cp_tree_size): Likewise.
(cp_var_mod_type_p): Likewise.
(cxx_initialize_diagnostics): Likewise.
(cxx_types_compatible_p): Likewise.
* cp-tree.h: to here.
(do_poplevel): Add.
* lex.c (D_OBJC): Add.
(init_reswords): Add.
* Make-lang.in (cp/pt.o): Add cp/cp-objcp-common.h.
* parser.c: Add c-common.h include.
* pt.c: Add c-common.h and cp-objcp-common.h includes.
(template_args_equal): Use objc_comptypes as well.
(tsubst_copy_and_build): Use objcp_tsubst_copy_and_build as well.
* semantics.c (do_poplevel): Remove static.
* decl.c (objc_mark_locals_volatile): Don't change decls that are
already ok.
* decl2.c (generate_ctor_or_dtor_function): Add code to initialize
Objective C++ early enough.
* lex.c (struct resword reswords): Add Objective-C++ support.
* parser.c (cp_lexer_get_preprocessor_token): Add Objective-C++.
(cp_parser_objc_message_receiver): Add.
(cp_parser_objc_message_args): Likewise.
(cp_parser_objc_message_expression): Likewise.
(cp_parser_objc_encode_expression): Likewise.
(cp_parser_objc_defs_expression): Likewise.
(cp_parser_objc_protocol_expression): Likewise.
(cp_parser_objc_selector_expression): Likewise.
(cp_parser_objc_expression): Likewise.
(cp_parser_objc_visibility_spec): Likewise.
(cp_parser_objc_method_type): Likewise.
(cp_parser_objc_protocol_qualifiers): Likewise.
(cp_parser_objc_typename): Likewise.
(cp_parser_objc_selector_p): Likewise.
(cp_parser_objc_selector): Likewise.
(cp_parser_objc_method_keyword_params): Likewise.
(cp_parser_objc_method_tail_params_opt): Likewise.
(cp_parser_objc_interstitial_code): Likewise.
(cp_parser_objc_method_signature): Likewise.
(cp_parser_objc_method_prototype_list): Likewise.
(cp_parser_objc_method_definition_list): Likewise.
(cp_parser_objc_class_ivars): Likewise.
(cp_parser_objc_identifier_list): Likewise.
(cp_parser_objc_alias_declaration): Likewise.
(cp_parser_objc_class_declaration): Likewise.
(cp_parser_objc_protocol_declaration): Likewise.
(cp_parser_objc_protocol_refs_opt): Likewise.
(cp_parser_objc_superclass_or_category): Likewise.
(cp_parser_objc_class_interface): Likewise.
(cp_parser_objc_class_implementation): Likewise.
(cp_parser_objc_end_implementation): Likewise.
(cp_parser_objc_declaration): Likewise.
(cp_parser_objc_try_catch_finally_statement): Likewise.
(cp_parser_objc_synchronized_statement): Likewise.
(cp_parser_objc_throw_statement): Likewise.
(cp_parser_objc_statement): Likewise.
(cp_parser_primary_expression): Add Objective-C++.
(cp_parser_statement): Likewise.
(cp_parser_declaration): Likewise.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_type_name): Likewise.
(cp_parser_parameter_declaration_list): Likewise.
(cp_parser_member_declaration) Likewise.
* tree.c: Include debug.h.
* typeck.c (composite_pointer_type): Add Objective-C++ support.
(finish_class_member_access_expr): Likewise.
(build_function_call): Allow objc to rewrite FUNCTION_DECLs.
(build_modify_expr): Allow objc to generate write barriers.
* Make-lang.in (cp/tree.o): Add debug.h.
* tree.c (lvalue_p_1, case CONST_DECL): Add.
2005-05-17 Jakub Jelinek <jakub@redhat.com> 2005-05-17 Jakub Jelinek <jakub@redhat.com>
PR c++/21454 PR c++/21454

View File

@ -255,14 +255,14 @@ cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \
cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h
cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H)
cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \ cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \
insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H) insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H) debug.h
cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H) cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H)
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h convert.h cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h convert.h
cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev.h \ cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev.h \
cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \ cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \
except.h $(TM_P_H) except.h $(TM_P_H)
cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h \ cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \
toplev.h $(RTL_H) except.h tree-inline.h pointer-set.h gt-cp-pt.h toplev.h $(RTL_H) except.h tree-inline.h pointer-set.h gt-cp-pt.h
cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \ cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \
flags.h real.h $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) flags.h real.h $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H)

View File

@ -22,16 +22,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_CP_OBJCP_COMMON #ifndef GCC_CP_OBJCP_COMMON
#define GCC_CP_OBJCP_COMMON #define GCC_CP_OBJCP_COMMON
/* In cp/cp-objcp-common.c. */
extern HOST_WIDE_INT cxx_get_alias_set (tree);
extern bool cxx_warn_unused_global_decl (tree);
extern tree cp_expr_size (tree);
extern size_t cp_tree_size (enum tree_code);
extern bool cp_var_mod_type_p (tree, tree);
extern void cxx_initialize_diagnostics (struct diagnostic_context *);
extern int cxx_types_compatible_p (tree, tree);
/* In cp/cp-lang.c and objcp/objcp-lang.c. */ /* In cp/cp-lang.c and objcp/objcp-lang.c. */
extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,

View File

@ -4063,6 +4063,7 @@ extern void pop_to_parent_deferring_access_checks (void);
extern void perform_deferred_access_checks (void); extern void perform_deferred_access_checks (void);
extern void perform_or_defer_access_check (tree, tree); extern void perform_or_defer_access_check (tree, tree);
extern void init_cp_semantics (void); extern void init_cp_semantics (void);
extern tree do_poplevel (tree);
extern void add_decl_expr (tree); extern void add_decl_expr (tree);
extern tree finish_expr_stmt (tree); extern tree finish_expr_stmt (tree);
extern tree begin_if_stmt (void); extern tree begin_if_stmt (void);
@ -4329,6 +4330,16 @@ extern tree mangle_ref_init_variable (tree);
/* in dump.c */ /* in dump.c */
extern bool cp_dump_tree (void *, tree); extern bool cp_dump_tree (void *, tree);
/* In cp/cp-objcp-common.c. */
extern HOST_WIDE_INT cxx_get_alias_set (tree);
extern bool cxx_warn_unused_global_decl (tree);
extern tree cp_expr_size (tree);
extern size_t cp_tree_size (enum tree_code);
extern bool cp_var_mod_type_p (tree, tree);
extern void cxx_initialize_diagnostics (struct diagnostic_context *);
extern int cxx_types_compatible_p (tree, tree);
/* in cp-gimplify.c */ /* in cp-gimplify.c */
extern int cp_gimplify_expr (tree *, tree *, tree *); extern int cp_gimplify_expr (tree *, tree *, tree *);
extern void cp_genericize (tree); extern void cp_genericize (tree);

View File

@ -419,19 +419,32 @@ objc_mark_locals_volatile (void *enclosing_blk)
struct cp_binding_level *scope; struct cp_binding_level *scope;
for (scope = current_binding_level; for (scope = current_binding_level;
scope && scope != enclosing_blk && scope->kind == sk_block; scope && scope != enclosing_blk;
scope = scope->level_chain) scope = scope->level_chain)
{ {
tree decl; tree decl;
for (decl = scope->names; decl; decl = TREE_CHAIN (decl)) for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
{ {
if (TREE_CODE (decl) == VAR_DECL) /* Do not mess with variables that are 'static' or (already)
'volatile'. */
if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
&& (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == PARM_DECL))
{ {
DECL_REGISTER (decl) = 0; TREE_TYPE (decl)
TREE_THIS_VOLATILE (decl) = 1; = build_qualified_type (TREE_TYPE (decl),
(TYPE_QUALS (TREE_TYPE (decl))
| TYPE_QUAL_VOLATILE));
TREE_THIS_VOLATILE (decl) = 1;
TREE_SIDE_EFFECTS (decl) = 1;
DECL_REGISTER (decl) = 0;
} }
} }
/* Do not climb up past the current function. */
if (scope->kind == sk_function_parms)
break;
} }
} }

View File

@ -2601,6 +2601,15 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
global constructors and destructors. */ global constructors and destructors. */
body = NULL_TREE; body = NULL_TREE;
/* For Objective-C++, we may need to initialize metadata found in this module.
This must be done _before_ any other static initializations. */
if (c_dialect_objc () && (priority == DEFAULT_INIT_PRIORITY)
&& constructor_p && objc_static_init_needed_p ())
{
body = start_objects (function_key, priority);
static_ctors = objc_generate_static_init_call (static_ctors);
}
/* Call the static storage duration function with appropriate /* Call the static storage duration function with appropriate
arguments. */ arguments. */
for (i = 0; VEC_iterate (tree, ssdf_decls, i, fndecl); ++i) for (i = 0; VEC_iterate (tree, ssdf_decls, i, fndecl); ++i)

View File

@ -175,6 +175,7 @@ struct resword
_true_. */ _true_. */
#define D_EXT 0x01 /* GCC extension */ #define D_EXT 0x01 /* GCC extension */
#define D_ASM 0x02 /* in C99, but has a switch to turn it off */ #define D_ASM 0x02 /* in C99, but has a switch to turn it off */
#define D_OBJC 0x04 /* Objective C++ only */
CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT); CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT);
@ -279,6 +280,31 @@ static const struct resword reswords[] =
{ "wchar_t", RID_WCHAR, 0 }, { "wchar_t", RID_WCHAR, 0 },
{ "while", RID_WHILE, 0 }, { "while", RID_WHILE, 0 },
/* The remaining keywords are specific to Objective-C++. NB:
All of them will remain _disabled_, since they are context-
sensitive. */
/* These ObjC keywords are recognized only immediately after
an '@'. NB: The following C++ keywords double as
ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
RID_PROTECTED, RID_PUBLIC, RID_THROW, RID_TRY and RID_CATCH. */
{ "compatibility_alias", RID_AT_ALIAS, D_OBJC },
{ "defs", RID_AT_DEFS, D_OBJC },
{ "encode", RID_AT_ENCODE, D_OBJC },
{ "end", RID_AT_END, D_OBJC },
{ "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
{ "interface", RID_AT_INTERFACE, D_OBJC },
{ "protocol", RID_AT_PROTOCOL, D_OBJC },
{ "selector", RID_AT_SELECTOR, D_OBJC },
{ "finally", RID_AT_FINALLY, D_OBJC },
{ "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
/* These are recognized only in protocol-qualifier context. */
{ "bycopy", RID_BYCOPY, D_OBJC },
{ "byref", RID_BYREF, D_OBJC },
{ "in", RID_IN, D_OBJC },
{ "inout", RID_INOUT, D_OBJC },
{ "oneway", RID_ONEWAY, D_OBJC },
{ "out", RID_OUT, D_OBJC },
}; };
void void
@ -287,6 +313,7 @@ init_reswords (void)
unsigned int i; unsigned int i;
tree id; tree id;
int mask = ((flag_no_asm ? D_ASM : 0) int mask = ((flag_no_asm ? D_ASM : 0)
| D_OBJC
| (flag_no_gnu_keywords ? D_EXT : 0)); | (flag_no_gnu_keywords ? D_EXT : 0));
ridpointers = ggc_calloc ((int) RID_MAX, sizeof (tree)); ridpointers = ggc_calloc ((int) RID_MAX, sizeof (tree));

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,9 @@ Boston, MA 02111-1307, USA. */
#include "tree.h" #include "tree.h"
#include "pointer-set.h" #include "pointer-set.h"
#include "flags.h" #include "flags.h"
#include "c-common.h"
#include "cp-tree.h" #include "cp-tree.h"
#include "cp-objcp-common.h"
#include "tree-inline.h" #include "tree-inline.h"
#include "decl.h" #include "decl.h"
#include "output.h" #include "output.h"
@ -4024,7 +4026,24 @@ template_args_equal (tree ot, tree nt)
/* For member templates */ /* For member templates */
return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt); return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt);
else if (TYPE_P (nt)) else if (TYPE_P (nt))
return TYPE_P (ot) && same_type_p (ot, nt); {
int c1, c2;
if (!TYPE_P (ot))
return 0;
/* We must handle ObjC types specially because they may differ
only in protocol qualifications (e.g., 'NSObject *' vs.
'NSObject <Foo> *') that must be taken into account here.
See also cp/typeck.c:build_c_cast(), where a similar problem
arises. We must call objc_comptypes() twice, since its
comparisons are _not_ symmetric. */
if ((c1 = objc_comptypes (ot, nt, 0)) >= 0
&& (c2 = objc_comptypes (nt, ot, 0)) >= 0)
return (c1 && c2);
return same_type_p (ot, nt);
}
else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot)) else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
return 0; return 0;
else else
@ -8880,6 +8899,14 @@ tsubst_copy_and_build (tree t,
return t; return t;
default: default:
/* Handle Objective-C++ constructs, if appropriate. */
{
tree subst
= objcp_tsubst_copy_and_build (t, args, complain,
in_decl, /*function_p=*/false);
if (subst)
return subst;
}
return tsubst_copy (t, args, complain, in_decl); return tsubst_copy (t, args, complain, in_decl);
} }

View File

@ -401,7 +401,7 @@ anon_aggr_type_p (tree node)
/* Finish a scope. */ /* Finish a scope. */
static tree tree
do_poplevel (tree stmt_list) do_poplevel (tree stmt_list)
{ {
tree block = NULL; tree block = NULL;

View File

@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */
#include "insn-config.h" #include "insn-config.h"
#include "integrate.h" #include "integrate.h"
#include "tree-inline.h" #include "tree-inline.h"
#include "debug.h"
#include "target.h" #include "target.h"
static tree bot_manip (tree *, int *, void *); static tree bot_manip (tree *, int *, void *);
@ -111,6 +112,7 @@ lvalue_p_1 (tree ref,
case STRING_CST: case STRING_CST:
return clk_ordinary; return clk_ordinary;
case CONST_DECL:
case VAR_DECL: case VAR_DECL:
if (TREE_READONLY (ref) && ! TREE_STATIC (ref) if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
&& DECL_LANG_SPECIFIC (ref) && DECL_LANG_SPECIFIC (ref)

View File

@ -514,10 +514,12 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
class1 = TREE_TYPE (t1); class1 = TREE_TYPE (t1);
class2 = TREE_TYPE (t2); class2 = TREE_TYPE (t2);
if (DERIVED_FROM_P (class1, class2)) if (DERIVED_FROM_P (class1, class2) ||
(c_dialect_objc () && objc_comptypes (class1, class2, 0) == 1))
t2 = (build_pointer_type t2 = (build_pointer_type
(cp_build_qualified_type (class1, TYPE_QUALS (class2)))); (cp_build_qualified_type (class1, TYPE_QUALS (class2))));
else if (DERIVED_FROM_P (class2, class1)) else if (DERIVED_FROM_P (class2, class1) ||
(c_dialect_objc () && objc_comptypes (class2, class1, 0) == 1))
t1 = (build_pointer_type t1 = (build_pointer_type
(cp_build_qualified_type (class2, TYPE_QUALS (class1)))); (cp_build_qualified_type (class2, TYPE_QUALS (class1))));
else else
@ -1849,6 +1851,10 @@ finish_class_member_access_expr (tree object, tree name)
if (object == error_mark_node || name == error_mark_node) if (object == error_mark_node || name == error_mark_node)
return error_mark_node; return error_mark_node;
/* If OBJECT is an ObjC class instance, we must obey ObjC access rules. */
if (!objc_is_public (object, name))
return error_mark_node;
object_type = TREE_TYPE (object); object_type = TREE_TYPE (object);
if (processing_template_decl) if (processing_template_decl)
@ -2395,6 +2401,10 @@ build_function_call (tree function, tree params)
int is_method; int is_method;
tree original = function; tree original = function;
/* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
expressions, like those used for ObjC messenger dispatches. */
function = objc_rewrite_function_call (function, params);
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context. */ Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context. */
if (TREE_CODE (function) == NOP_EXPR if (TREE_CODE (function) == NOP_EXPR
@ -5441,6 +5451,14 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
if (newrhs == error_mark_node) if (newrhs == error_mark_node)
return error_mark_node; return error_mark_node;
if (c_dialect_objc () && flag_objc_gc)
{
result = objc_generate_write_barrier (lhs, modifycode, newrhs);
if (result)
return result;
}
result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR, result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
lhstype, lhs, newrhs); lhstype, lhs, newrhs);