2009-12-02 Paolo Bonzini <bonzini@gnu.org>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Dec 2009 15:49:20 +0000 (15:49 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Dec 2009 15:49:20 +0000 (15:49 +0000)
    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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154915 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 7b2afd3..edecdaa 100644 (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
index ef44201..913993a 100644 (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) \
index 837a65d..a6041f5 100644 (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;
index 2d8f409..dc563e2 100644 (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);
 
index 8f6d33c..5b37ef7 100644 (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)
index b843400..97a2f80 100644 (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;
              }
 
index 383c96c..7378f89 100644 (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)
index aa79b22..b382108 100644 (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;
index 2530695..36c0b8a 100644 (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;
     }
index 07c2ffc..348c657 100644 (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);
 }
 
 \f