From 5c892d4a05f59896e924a64c2db11630ada5c263 Mon Sep 17 00:00:00 2001 From: paolo Date: Wed, 2 Dec 2009 15:49:20 +0000 Subject: [PATCH] 2009-12-02 Paolo Bonzini Shujing Zhao 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154915 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 23 ++++++++++ gcc/cp/Make-lang.in | 7 +-- gcc/cp/call.c | 57 +++++++++++++++++------- gcc/cp/cp-tree.h | 15 ++++++- gcc/cp/decl.c | 74 +++++++++++++++++++------------ gcc/cp/pt.c | 8 ++-- gcc/cp/rtti.c | 21 ++++----- gcc/cp/semantics.c | 2 +- gcc/cp/typeck.c | 24 +++++------ gcc/cp/typeck2.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++------ 10 files changed, 267 insertions(+), 86 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7b2afd3..edecdaa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,26 @@ +2009-12-02 Paolo Bonzini + Shujing Zhao + + 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 * g++spec.c (lang_specific_driver): Remove unused saw_verbose_flag diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index ef44201..913993a 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -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) \ diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 837a65d..a6041f5 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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 % in %<%E ? %E : %E%>", - problem, arg1, arg2, arg3); + if (match) + error ("ambiguous overload for ternary % " + "in %<%E ? %E : %E%>", arg1, arg2, arg3); + else + error ("no match for ternary % " + "in %<%E ? %E : %E%>", arg1, arg2, arg3); break; case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: - error ("%s for % in %<%E%s%>", problem, opname, arg1, opname); + if (match) + error ("ambiguous overload for % in %<%E%s%>", + opname, arg1, opname); + else + error ("no match for % in %<%E%s%>", + opname, arg1, opname); break; case ARRAY_REF: - error ("%s for % in %<%E[%E]%>", problem, arg1, arg2); + if (match) + error ("ambiguous overload for % in %<%E[%E]%>", + arg1, arg2); + else + error ("no match for % 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 % in %<%E %s %E%>", - problem, opname, arg1, opname, arg2); + if (match) + error ("ambiguous overload for % in %<%E %s %E%>", + opname, arg1, opname, arg2); + else + error ("no match for % in %<%E %s %E%>", + opname, arg1, opname, arg2); else - error ("%s for % in %<%s%E%>", - problem, opname, opname, arg1); + if (match) + error ("ambiguous overload for % in %<%s%E%>", + opname, opname, arg1); + else + error ("no match for % 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; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2d8f409..dc563e2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8f6d33c..5b37ef7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b843400..97a2f80 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 383c96c..7378f89 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index aa79b22..b382108 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 2530695..36c0b8a 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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; } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 07c2ffc..348c657 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -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); } -- 2.7.4