re PR c++/29917 (%s substituted with actual words can not be translated correctly (op_error))

2009-12-02  Paolo Bonzini  <bonzini@gnu.org>
	    Shujing Zhao  <pearly.zhao@oracle.com>

	PR c++/29917
	* call.c (op_error): Accept a boolean to indicate no match/ambiguous
	match, instead of a string. Callers adjusted.

	PR c++/34836
	* cp-tree.h (readonly_error_kind): New type.
	(readonly_error): Adjust prototype with new argument.
	* typeck2.c (readonly_error): Accept readonly_error_kind as argument
	and add macro ERROR_FOR_ASSIGNMENT to emit diagnostics.
	* semantics.c (finish_asm_stmt): Adjust readonly_error call.
	* typeck.c (cp_build_unary_op, cp_build_modify_expr): Likewise.

	* decl.c (grokparms, grok_op_properties): Put the diagnostics in full
	sentences for easy translation and wrap the diagnostics into G_() when
	needed.
	(create_array_type_for_decl): Likewise.
	* pt.c (tsubst): Likewise.
	* typeck2.c (cp_build_unary_op): Wrap diagnostic into _().
	* rtti.c (build_dynamic_cast_1): Likewise.

Co-Authored-By: Shujing Zhao <pearly.zhao@oracle.com>

From-SVN: r154915
This commit is contained in:
Paolo Bonzini 2009-12-02 15:49:20 +00:00 committed by Paolo Carlini
parent 2f697bc476
commit 4cd5a50a09
10 changed files with 267 additions and 86 deletions

View File

@ -1,3 +1,26 @@
2009-12-02 Paolo Bonzini <bonzini@gnu.org>
Shujing Zhao <pearly.zhao@oracle.com>
PR c++/29917
* call.c (op_error): Accept a boolean to indicate no match/ambiguous
match, instead of a string. Callers adjusted.
PR c++/34836
* cp-tree.h (readonly_error_kind): New type.
(readonly_error): Adjust prototype with new argument.
* typeck2.c (readonly_error): Accept readonly_error_kind as argument
and add macro ERROR_FOR_ASSIGNMENT to emit diagnostics.
* semantics.c (finish_asm_stmt): Adjust readonly_error call.
* typeck.c (cp_build_unary_op, cp_build_modify_expr): Likewise.
* decl.c (grokparms, grok_op_properties): Put the diagnostics in full
sentences for easy translation and wrap the diagnostics into G_() when
needed.
(create_array_type_for_decl): Likewise.
* pt.c (tsubst): Likewise.
* typeck2.c (cp_build_unary_op): Wrap diagnostic into _().
* rtti.c (build_dynamic_cast_1): Likewise.
2009-12-02 Jakub Jelinek <jakub@redhat.com>
* g++spec.c (lang_specific_driver): Remove unused saw_verbose_flag

View File

@ -254,7 +254,8 @@ cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \
debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H) $(PLUGIN_H)
debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H) $(PLUGIN_H) \
intl.h
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(RTL_H) $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \
$(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H) $(POINTER_SET_H)
@ -263,7 +264,7 @@ cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \
langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \
$(CXX_PRETTY_PRINT_H) cp/cp-objcp-common.h gt-cp-cp-objcp-common.h
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h output.h \
$(TM_P_H) $(DIAGNOSTIC_H) gt-cp-typeck2.h $(REAL_H)
$(TM_P_H) $(DIAGNOSTIC_H) gt-cp-typeck2.h $(REAL_H) intl.h
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) $(EXPR_H) \
toplev.h $(DIAGNOSTIC_H) convert.h $(C_COMMON_H) $(TARGET_H)
cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \
@ -284,7 +285,7 @@ cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \
$(TARGET_H) debug.h $(TREE_FLOW_H) $(CGRAPH_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 \
$(TARGET_H) $(C_PRAGMA_H) gt-cp-rtti.h
$(TARGET_H) $(C_PRAGMA_H) gt-cp-rtti.h intl.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) $(TARGET_H)
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) $(FLAGS_H) $(EXPR_H) \

View File

@ -144,7 +144,7 @@ static tree build_java_interface_fn_ref (tree, tree);
static tree convert_like_real (conversion *, tree, tree, int, int, bool,
bool, tsubst_flags_t);
static void op_error (enum tree_code, enum tree_code, tree, tree,
tree, const char *);
tree, bool);
static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
static void print_z_candidate (const char *, struct z_candidate *);
@ -3489,7 +3489,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
static void
op_error (enum tree_code code, enum tree_code code2,
tree arg1, tree arg2, tree arg3, const char *problem)
tree arg1, tree arg2, tree arg3, bool match)
{
const char *opname;
@ -3501,31 +3501,58 @@ op_error (enum tree_code code, enum tree_code code2,
switch (code)
{
case COND_EXPR:
error ("%s for ternary %<operator?:%> in %<%E ? %E : %E%>",
problem, arg1, arg2, arg3);
if (match)
error ("ambiguous overload for ternary %<operator?:%> "
"in %<%E ? %E : %E%>", arg1, arg2, arg3);
else
error ("no match for ternary %<operator?:%> "
"in %<%E ? %E : %E%>", arg1, arg2, arg3);
break;
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
error ("%s for %<operator%s%> in %<%E%s%>", problem, opname, arg1, opname);
if (match)
error ("ambiguous overload for %<operator%s%> in %<%E%s%>",
opname, arg1, opname);
else
error ("no match for %<operator%s%> in %<%E%s%>",
opname, arg1, opname);
break;
case ARRAY_REF:
error ("%s for %<operator[]%> in %<%E[%E]%>", problem, arg1, arg2);
if (match)
error ("ambiguous overload for %<operator[]%> in %<%E[%E]%>",
arg1, arg2);
else
error ("no match for %<operator[]%> in %<%E[%E]%>",
arg1, arg2);
break;
case REALPART_EXPR:
case IMAGPART_EXPR:
error ("%s for %qs in %<%s %E%>", problem, opname, opname, arg1);
if (match)
error ("ambiguous overload for %qs in %<%s %E%>",
opname, opname, arg1);
else
error ("no match for %qs in %<%s %E%>",
opname, opname, arg1);
break;
default:
if (arg2)
error ("%s for %<operator%s%> in %<%E %s %E%>",
problem, opname, arg1, opname, arg2);
if (match)
error ("ambiguous overload for %<operator%s%> in %<%E %s %E%>",
opname, arg1, opname, arg2);
else
error ("no match for %<operator%s%> in %<%E %s %E%>",
opname, arg1, opname, arg2);
else
error ("%s for %<operator%s%> in %<%s%E%>",
problem, opname, opname, arg1);
if (match)
error ("ambiguous overload for %<operator%s%> in %<%s%E%>",
opname, opname, arg1);
else
error ("no match for %<operator%s%> in %<%s%E%>",
opname, opname, arg1);
break;
}
}
@ -3852,7 +3879,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
{
if (complain & tf_error)
{
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
print_z_candidates (candidates);
}
return error_mark_node;
@ -3862,7 +3889,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
{
if (complain & tf_error)
{
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
print_z_candidates (candidates);
}
return error_mark_node;
@ -4330,7 +4357,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
{
/* ... Otherwise, report the more generic
"no matching operator found" error */
op_error (code, code2, arg1, arg2, arg3, "no match");
op_error (code, code2, arg1, arg2, arg3, FALSE);
print_z_candidates (candidates);
}
}
@ -4345,7 +4372,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
{
if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
{
op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
op_error (code, code2, arg1, arg2, arg3, TRUE);
print_z_candidates (candidates);
}
result = error_mark_node;

View File

@ -415,6 +415,19 @@ typedef enum composite_pointer_operation
CPO_CONDITIONAL_EXPR
} composite_pointer_operation;
/* The various readonly error string used by readonly_error. */
typedef enum readonly_error_kind
{
/* assignment */
REK_ASSIGNMENT,
/* assignment (via 'asm' output) */
REK_ASSIGNMENT_ASM,
/* increment */
REK_INCREMENT,
/* decrement */
REK_DECREMENT
} readonly_error_kind;
/* Macros for access to language-specific slots in an identifier. */
#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \
@ -5360,7 +5373,7 @@ extern void cxx_incomplete_type_error (const_tree, const_tree);
(cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR))
extern tree error_not_base_type (tree, tree);
extern tree binfo_or_else (tree, tree);
extern void readonly_error (tree, const char *);
extern void readonly_error (tree, readonly_error_kind);
extern void complete_type_check_abstract (tree);
extern int abstract_virtuals_error (tree, tree);

View File

@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "cp-tree.h"
#include "tree-inline.h"
#include "decl.h"
#include "intl.h"
#include "output.h"
#include "except.h"
#include "toplev.h"
@ -7431,40 +7432,46 @@ create_array_type_for_decl (tree name, tree type, tree size)
/* Assume that everything will go OK. */
error_msg = NULL;
/* There are some types which cannot be array elements. */
/* If there are some types which cannot be array elements,
issue an error-message and return. */
switch (TREE_CODE (type))
{
case VOID_TYPE:
error_msg = "array of void";
if (name)
error ("declaration of %qD as array of void", name);
else
error ("creating array of void");
return error_mark_node;
break;
case FUNCTION_TYPE:
error_msg = "array of functions";
if (name)
error ("declaration of %qD as array of functions", name);
else
error ("creating array of functions");
return error_mark_node;
break;
case REFERENCE_TYPE:
error_msg = "array of references";
if (name)
error ("declaration of %qD as array of references", name);
else
error ("creating array of references");
return error_mark_node;
break;
case METHOD_TYPE:
error_msg = "array of function members";
if (name)
error ("declaration of %qD as array of function members", name);
else
error ("creating array of function members");
return error_mark_node;
break;
default:
break;
}
/* If something went wrong, issue an error-message and return. */
if (error_msg)
{
if (name)
error ("declaration of %qD as %s", name, error_msg);
else
error ("creating %s", error_msg);
return error_mark_node;
}
/* [dcl.array]
The constant expressions that specify the bounds of the arrays
@ -9904,9 +9911,12 @@ grokparms (tree parmlist, tree *parms)
t = TREE_TYPE (t);
}
if (TREE_CODE (t) == ARRAY_TYPE)
error ("parameter %qD includes %s to array of unknown "
"bound %qT",
decl, ptr ? "pointer" : "reference", t);
error (ptr
? G_("parameter %qD includes pointer to array of "
"unknown bound %qT")
: G_("parameter %qD includes reference to array of "
"unknown bound %qT"),
decl, t);
}
if (any_error)
@ -10353,28 +10363,38 @@ grok_op_properties (tree decl, bool complain)
{
tree t = TREE_TYPE (name);
int ref = (TREE_CODE (t) == REFERENCE_TYPE);
const char *what = 0;
if (ref)
t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
if (TREE_CODE (t) == VOID_TYPE)
what = "void";
warning (OPT_Wconversion,
ref
? G_("conversion to a reference to void "
"will never use a type conversion operator")
: G_("conversion to void "
"will never use a type conversion operator"));
else if (class_type)
{
if (t == class_type)
what = "the same type";
warning (OPT_Wconversion,
ref
? G_("conversion to a reference to the same type "
"will never use a type conversion operator")
: G_("conversion to the same type "
"will never use a type conversion operator"));
/* Don't force t to be complete here. */
else if (MAYBE_CLASS_TYPE_P (t)
&& COMPLETE_TYPE_P (t)
&& DERIVED_FROM_P (t, class_type))
what = "a base class";
warning (OPT_Wconversion,
ref
? G_("conversion to a reference to a base class "
"will never use a type conversion operator")
: G_("conversion to a base class "
"will never use a type conversion operator"));
}
if (what)
warning (OPT_Wconversion, "conversion to %s%s will never use a type "
"conversion operator",
ref ? "a reference to " : "", what);
}
if (operator_code == COND_EXPR)

View File

@ -10041,10 +10041,10 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
if (TREE_CODE (type) == VOID_TYPE)
error ("forming reference to void");
else
error ("forming %s to reference type %qT",
(code == POINTER_TYPE) ? "pointer" : "reference",
type);
else if (code == POINTER_TYPE)
error ("forming pointer to reference type %qT", type);
else
error ("forming reference to reference type %qT", type);
last_loc = input_location;
}

View File

@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "intl.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
@ -525,18 +526,18 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
case REFERENCE_TYPE:
if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (type)))
{
errstr = "target is not pointer or reference to class";
errstr = _("target is not pointer or reference to class");
goto fail;
}
if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
{
errstr = "target is not pointer or reference to complete type";
errstr = _("target is not pointer or reference to complete type");
goto fail;
}
break;
default:
errstr = "target is not pointer or reference";
errstr = _("target is not pointer or reference");
goto fail;
}
@ -547,17 +548,17 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
if (TREE_CODE (exprtype) != POINTER_TYPE)
{
errstr = "source is not a pointer";
errstr = _("source is not a pointer");
goto fail;
}
if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype)))
{
errstr = "source is not a pointer to class";
errstr = _("source is not a pointer to class");
goto fail;
}
if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
{
errstr = "source is a pointer to incomplete type";
errstr = _("source is a pointer to incomplete type");
goto fail;
}
}
@ -570,12 +571,12 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (exprtype)))
{
errstr = "source is not of class type";
errstr = _("source is not of class type");
goto fail;
}
if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (exprtype))))
{
errstr = "source is of incomplete class type";
errstr = _("source is of incomplete class type");
goto fail;
}
@ -588,7 +589,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
if (!at_least_as_qualified_p (TREE_TYPE (type),
TREE_TYPE (exprtype)))
{
errstr = "conversion casts away constness";
errstr = _("conversion casts away constness");
goto fail;
}
@ -748,7 +749,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
}
}
else
errstr = "source type is not polymorphic";
errstr = _("source type is not polymorphic");
fail:
if (complain & tf_error)

View File

@ -1254,7 +1254,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
effectively const. */
|| (CLASS_TYPE_P (TREE_TYPE (operand))
&& C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
readonly_error (operand, "assignment (via 'asm' output)");
readonly_error (operand, REK_ASSIGNMENT_ASM);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
oconstraints[i] = constraint;

View File

@ -4462,8 +4462,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
arg = build_expr_type_conversion (flags, arg, true);
if (!arg)
errstring = (code == NEGATE_EXPR
? "wrong type argument to unary minus"
: "wrong type argument to unary plus");
? _("wrong type argument to unary minus")
: _("wrong type argument to unary plus"));
else
{
if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
@ -4486,14 +4486,14 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
| WANT_VECTOR,
arg, true)))
errstring = "wrong type argument to bit-complement";
errstring = _("wrong type argument to bit-complement");
else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
arg = perform_integral_promotions (arg);
break;
case ABS_EXPR:
if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
errstring = "wrong type argument to abs";
errstring = _("wrong type argument to abs");
else if (!noconvert)
arg = default_conversion (arg);
break;
@ -4501,7 +4501,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
case CONJ_EXPR:
/* Conjugating a real value is a no-op, but allow it anyway. */
if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
errstring = "wrong type argument to conjugation";
errstring = _("wrong type argument to conjugation");
else if (!noconvert)
arg = default_conversion (arg);
break;
@ -4512,7 +4512,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
val = invert_truthvalue_loc (input_location, arg);
if (arg != error_mark_node)
return val;
errstring = "in argument to unary !";
errstring = _("in argument to unary !");
break;
case NOP_EXPR:
@ -4573,13 +4573,13 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
arg, true)))
{
if (code == PREINCREMENT_EXPR)
errstring ="no pre-increment operator for type";
errstring = _("no pre-increment operator for type");
else if (code == POSTINCREMENT_EXPR)
errstring ="no post-increment operator for type";
errstring = _("no post-increment operator for type");
else if (code == PREDECREMENT_EXPR)
errstring ="no pre-decrement operator for type";
errstring = _("no pre-decrement operator for type");
else
errstring ="no post-decrement operator for type";
errstring = _("no post-decrement operator for type");
break;
}
else if (arg == error_mark_node)
@ -4593,7 +4593,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
if (complain & tf_error)
readonly_error (arg, ((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
? "increment" : "decrement"));
? REK_INCREMENT : REK_DECREMENT));
else
return error_mark_node;
}
@ -6327,7 +6327,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
&& C_TYPE_FIELDS_READONLY (lhstype))))
{
if (complain & tf_error)
readonly_error (lhs, "assignment");
readonly_error (lhs, REK_ASSIGNMENT);
else
return error_mark_node;
}

View File

@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "intl.h"
#include "cp-tree.h"
#include "flags.h"
#include "toplev.h"
@ -71,41 +72,136 @@ binfo_or_else (tree base, tree type)
value may not be changed thereafter. */
void
readonly_error (tree arg, const char* string)
readonly_error (tree arg, readonly_error_kind errstring)
{
const char *fmt;
/* This macro is used to emit diagnostics to ensure that all format
strings are complete sentences, visible to gettext and checked at
compile time. */
#define ERROR_FOR_ASSIGNMENT(AS, ASM, IN, DE, ARG) \
do { \
switch (errstring) \
{ \
case REK_ASSIGNMENT: \
error(AS, ARG); \
break; \
case REK_ASSIGNMENT_ASM: \
error(ASM, ARG); \
break; \
case REK_INCREMENT: \
error (IN, ARG); \
break; \
case REK_DECREMENT: \
error (DE, ARG); \
break; \
default: \
gcc_unreachable (); \
} \
} while (0)
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
fmt = "%s of data-member %qD in read-only structure";
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"data-member %qD in read-only structure"),
G_("assignment (via 'asm' output) of "
"data-member %qD in read-only structure"),
G_("increment of "
"data-member %qD in read-only structure"),
G_("decrement of "
"data-member %qD in read-only structure"),
TREE_OPERAND (arg, 1));
else
fmt = "%s of read-only data-member %qD";
error (fmt, string, TREE_OPERAND (arg, 1));
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"read-only data-member %qD"),
G_("assignment (via 'asm' output) of "
"read-only data-member %qD"),
G_("increment of "
"read-only data-member %qD"),
G_("decrement of "
"read-only data-member %qD"),
TREE_OPERAND (arg, 1));
}
else if (TREE_CODE (arg) == VAR_DECL)
{
if (DECL_LANG_SPECIFIC (arg)
&& DECL_IN_AGGR_P (arg)
&& !TREE_STATIC (arg))
fmt = "%s of constant field %qD";
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"constant field %qD"),
G_("assignment (via 'asm' output) of "
"constant field %qD"),
G_("increment of "
"constant field %qD"),
G_("decrement of "
"constant field %qD"),
arg);
else
fmt = "%s of read-only variable %qD";
error (fmt, string, arg);
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"read-only variable %qD"),
G_("assignment (via 'asm' output) of "
"read-only variable %qD"),
G_("increment of "
"read-only variable %qD"),
G_("decrement of "
"read-only variable %qD"),
arg);
}
else if (TREE_CODE (arg) == PARM_DECL)
error ("%s of read-only parameter %qD", string, arg);
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"read-only parameter %qD"),
G_("assignment (via 'asm' output) of "
"read-only parameter %qD"),
G_("increment of "
"read-only parameter %qD"),
G_("decrement of "
"read-only parameter %qD"),
arg);
else if (TREE_CODE (arg) == INDIRECT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE
&& (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
|| TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
error ("%s of read-only reference %qD", string, TREE_OPERAND (arg, 0));
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"read-only reference %qD"),
G_("assignment (via 'asm' output) of "
"read-only reference %qD"),
G_("increment of "
"read-only reference %qD"),
G_("decrement of "
"read-only reference %qD"),
TREE_OPERAND (arg, 0));
else if (TREE_CODE (arg) == RESULT_DECL)
error ("%s of read-only named return value %qD", string, arg);
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"read-only named return value %qD"),
G_("assignment (via 'asm' output) of "
"read-only named return value %qD"),
G_("increment of "
"read-only named return value %qD"),
G_("decrement of "
"read-only named return value %qD"),
arg);
else if (TREE_CODE (arg) == FUNCTION_DECL)
error ("%s of function %qD", string, arg);
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"function %qD"),
G_("assignment (via 'asm' output) of "
"function %qD"),
G_("increment of "
"function %qD"),
G_("decrement of "
"function %qD"),
arg);
else
error ("%s of read-only location %qE", string, arg);
ERROR_FOR_ASSIGNMENT (G_("assignment of "
"read-only location %qE"),
G_("assignment (via 'asm' output) of "
"read-only location %qE"),
G_("increment of "
"read-only location %qE"),
G_("decrement of "
"read-only location %qE"),
arg);
}