From 183407eee40eeb1aa710d1b41eb7e68a2664849b Mon Sep 17 00:00:00 2001 From: pzhao Date: Fri, 11 Jun 2010 03:54:28 +0000 Subject: [PATCH] 2010-06-11 Shujing Zhao * cp-tree.h (expr_list_kind): New type. (impl_conv_rhs): New type. (build_x_compound_expr_from_list, convert_for_initialization): Adjust prototype. (typeck.c (convert_arguments): Use impl_conv_rhs and emit the diagnostics for easy translation. Change caller. (convert_for_initialization): Use impl_conv_rhs and change caller. (build_x_compound_expr_from_list): Use expr_list_kind and emit the diagnostics for easy translation. Change caller. * decl.c (bad_spec_place): New enum. (bad_specifiers): Use it and emit the diagnostics for easy translation. Change caller. * pt.c (coerce_template_parms): Put the diagnostics in full sentence. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160591 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 17 +++++++ gcc/cp/call.c | 4 +- gcc/cp/cp-tree.h | 21 ++++++++- gcc/cp/cvt.c | 2 +- gcc/cp/decl.c | 73 ++++++++++++++++++++++------- gcc/cp/init.c | 2 +- gcc/cp/pt.c | 10 ++-- gcc/cp/typeck.c | 138 +++++++++++++++++++++++++++++++++++++++++++------------ gcc/cp/typeck2.c | 15 +++--- 9 files changed, 217 insertions(+), 65 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8a261416f1c..75a76005b92 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2010-06-11 Shujing Zhao + + * cp-tree.h (expr_list_kind): New type. + (impl_conv_rhs): New type. + (build_x_compound_expr_from_list, convert_for_initialization): Adjust + prototype. + (typeck.c (convert_arguments): Use impl_conv_rhs and emit the + diagnostics for easy translation. Change caller. + (convert_for_initialization): Use impl_conv_rhs and change caller. + (build_x_compound_expr_from_list): Use expr_list_kind and emit the + diagnostics for easy translation. Change caller. + * decl.c (bad_spec_place): New enum. + (bad_specifiers): Use it and emit the diagnostics for easy + translation. Change caller. + * pt.c (coerce_template_parms): Put the diagnostics in full sentence. + 2010-06-09 Nathan Froyd * cp-tree.h (struct saved_scope): Change decl_ns_list field type @@ -1736,3 +1752,4 @@ Copyright (C) 2010 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. + diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e432f7490bf..f46fbf7bce7 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5387,7 +5387,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) { arg = digest_init (type, arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", fn, parmnum, + ICR_DEFAULT_ARGUMENT, fn, parmnum, tf_warning_or_error); } else @@ -5401,7 +5401,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) if (!CONSTANT_CLASS_P (arg)) arg = unshare_expr (arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", fn, parmnum, + ICR_DEFAULT_ARGUMENT, fn, parmnum, tf_warning_or_error); arg = convert_for_arg_passing (type, arg); } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index adff6168b80..b71f8af0a0c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -418,6 +418,23 @@ typedef enum readonly_error_kind REK_DECREMENT } readonly_error_kind; +/* Possible cases of expression list used by build_x_compound_expr_from_list. */ +typedef enum expr_list_kind { + ELK_INIT, /* initializer */ + ELK_MEM_INIT, /* member initializer */ + ELK_FUNC_CAST /* functional cast */ +} expr_list_kind; + +/* Possible cases of implicit bad rhs conversions. */ +typedef enum impl_conv_rhs { + ICR_DEFAULT_ARGUMENT, /* default argument */ + ICR_CONVERTING, /* converting */ + ICR_INIT, /* initialization */ + ICR_ARGPASS, /* argument passing */ + ICR_RETURN, /* return */ + ICR_ASSIGN /* assignment */ +} impl_conv_rhs; + /* Macros for access to language-specific slots in an identifier. */ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ @@ -5400,7 +5417,7 @@ extern tree cp_build_unary_op (enum tree_code, tree, int, extern tree unary_complex_lvalue (enum tree_code, tree); extern tree build_x_conditional_expr (tree, tree, tree, tsubst_flags_t); -extern tree build_x_compound_expr_from_list (tree, const char *); +extern tree build_x_compound_expr_from_list (tree, expr_list_kind); extern tree build_x_compound_expr_from_vec (VEC(tree,gc) *, const char *); extern tree build_x_compound_expr (tree, tree, tsubst_flags_t); extern tree build_compound_expr (location_t, tree, tree); @@ -5415,7 +5432,7 @@ extern tree build_x_modify_expr (tree, enum tree_code, tree, extern tree cp_build_modify_expr (tree, enum tree_code, tree, tsubst_flags_t); extern tree convert_for_initialization (tree, tree, tree, int, - const char *, tree, int, + impl_conv_rhs, tree, int, tsubst_flags_t); extern int comp_ptr_ttypes (tree, tree); extern bool comp_ptr_ttypes_const (tree, tree); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 04c068cb3e8..40a635153bc 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -481,7 +481,7 @@ convert_to_reference (tree reftype, tree expr, int convtype, else { rval = convert_for_initialization (NULL_TREE, type, expr, flags, - "converting", 0, 0, + ICR_CONVERTING, 0, 0, tf_warning_or_error); if (rval == NULL_TREE || rval == error_mark_node) return rval; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0c4ad496db3..3108f9d0363 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -56,6 +56,14 @@ along with GCC; see the file COPYING3. If not see #include "splay-tree.h" #include "plugin.h" +/* Possible cases of bad specifiers type used by bad_specifiers. */ +enum bad_spec_place { + BSP_VAR, /* variable */ + BSP_PARM, /* parameter */ + BSP_TYPE, /* type */ + BSP_FIELD /* field */ +}; + static tree grokparms (tree parmlist, tree *); static const char *redeclaration_error_message (tree, tree); @@ -71,7 +79,7 @@ static void record_unknown_type (tree, const char *); static tree builtin_function_1 (tree, tree, bool); static tree build_library_fn_1 (tree, enum tree_code, tree); static int member_function_or_else (tree, tree, enum overload_flags); -static void bad_specifiers (tree, const char *, int, int, int, int, +static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int, int); static void check_for_uninitialized_const_var (tree); static hashval_t typename_hash (const void *); @@ -4450,7 +4458,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) } if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, "initializer"); + init = build_x_compound_expr_from_list (init, ELK_INIT); if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) @@ -5671,7 +5679,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, return; } if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, "initializer"); + init = build_x_compound_expr_from_list (init, ELK_INIT); if (describable_type (init)) { type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node); @@ -6592,21 +6600,54 @@ member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags) static void bad_specifiers (tree object, - const char* type, + enum bad_spec_place type, int virtualp, int quals, int inlinep, int friendp, int raises) { - if (virtualp) - error ("%qD declared as a % %s", object, type); - if (inlinep) - error ("%qD declared as an % %s", object, type); - if (quals) - error ("% and % function specifiers on " - "%qD invalid in %s declaration", - object, type); + switch (type) + { + case BSP_VAR: + if (virtualp) + error ("%qD declared as a % variable", object); + if (inlinep) + error ("%qD declared as an % variable", object); + if (quals) + error ("% and % function specifiers on " + "%qD invalid in variable declaration", object); + break; + case BSP_PARM: + if (virtualp) + error ("%qD declared as a % parameter", object); + if (inlinep) + error ("%qD declared as an % parameter", object); + if (quals) + error ("% and % function specifiers on " + "%qD invalid in parameter declaration", object); + break; + case BSP_TYPE: + if (virtualp) + error ("%qD declared as a % type", object); + if (inlinep) + error ("%qD declared as an % type", object); + if (quals) + error ("% and % function specifiers on " + "%qD invalid in type declaration", object); + break; + case BSP_FIELD: + if (virtualp) + error ("%qD declared as a % field", object); + if (inlinep) + error ("%qD declared as an % field", object); + if (quals) + error ("% and % function specifiers on " + "%qD invalid in field declaration", object); + break; + default: + gcc_unreachable(); + } if (friendp) error ("%q+D declared as a friend", object); if (raises @@ -9128,7 +9169,7 @@ grokdeclarator (const cp_declarator *declarator, || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; - bad_specifiers (decl, "type", virtualp, + bad_specifiers (decl, BSP_TYPE, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); @@ -9314,7 +9355,7 @@ grokdeclarator (const cp_declarator *declarator, { decl = cp_build_parm_decl (unqualified_id, type); - bad_specifiers (decl, "parameter", virtualp, + bad_specifiers (decl, BSP_PARM, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); } @@ -9592,7 +9633,7 @@ grokdeclarator (const cp_declarator *declarator, } } - bad_specifiers (decl, "field", virtualp, + bad_specifiers (decl, BSP_FIELD, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); } @@ -9715,7 +9756,7 @@ grokdeclarator (const cp_declarator *declarator, initialized, (type_quals & TYPE_QUAL_CONST) != 0, ctype ? ctype : in_namespace); - bad_specifiers (decl, "variable", virtualp, + bad_specifiers (decl, BSP_VAR, virtualp, memfn_quals != TYPE_UNQUALIFIED, inlinep, friendp, raises != NULL_TREE); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 66451b1e356..84e486cea46 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -526,7 +526,7 @@ perform_member_init (tree member, tree init) else if (TREE_CODE (init) == TREE_LIST) /* There was an explicit member initialization. Do some work in that case. */ - init = build_x_compound_expr_from_list (init, "member initializer"); + init = build_x_compound_expr_from_list (init, ELK_MEM_INIT); if (init) finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 69216cf6e43..55ea5397d8a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5921,15 +5921,15 @@ coerce_template_parms (tree parms, { if (complain & tf_error) { - const char *or_more = ""; if (variadic_p) { - or_more = " or more"; --nparms; + error ("wrong number of template arguments " + "(%d, should be %d or more)", nargs, nparms); } - - error ("wrong number of template arguments (%d, should be %d%s)", - nargs, nparms, or_more); + else + error ("wrong number of template arguments " + "(%d, should be %d)", nargs, nparms); if (in_decl) error ("provided for %q+D", in_decl); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a43c432bd22..75448d56f15 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -44,7 +44,7 @@ along with GCC; see the file COPYING3. If not see static tree pfn_from_ptrmemfunc (tree); static tree delta_from_ptrmemfunc (tree); -static tree convert_for_assignment (tree, tree, const char *, tree, int, +static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int, tsubst_flags_t, int); static tree cp_pointer_int_sum (enum tree_code, tree, tree); static tree rationalize_conditional_expr (enum tree_code, tree, @@ -3493,7 +3493,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, { parmval = convert_for_initialization (NULL_TREE, type, val, flags, - "argument passing", fndecl, i, complain); + ICR_ARGPASS, fndecl, i, complain); parmval = convert_for_arg_passing (type, parmval); } @@ -5486,14 +5486,30 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2, /* Given a list of expressions, return a compound expression that performs them all and returns the value of the last of them. */ -tree build_x_compound_expr_from_list (tree list, const char *msg) +tree +build_x_compound_expr_from_list (tree list, expr_list_kind exp) { tree expr = TREE_VALUE (list); if (TREE_CHAIN (list)) { - if (msg) - permerror (input_location, "%s expression list treated as compound expression", msg); + switch (exp) + { + case ELK_INIT: + permerror (input_location, "expression list treated as compound " + "expression in initializer"); + break; + case ELK_MEM_INIT: + permerror (input_location, "expression list treated as compound " + "expression in mem-initializer"); + break; + case ELK_FUNC_CAST: + permerror (input_location, "expression list treated as compound " + "expression in functional cast"); + break; + default: + gcc_unreachable (); + } for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list)) expr = build_x_compound_expr (expr, TREE_VALUE (list), @@ -6767,10 +6783,10 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, /* Calls with INIT_EXPR are all direct-initialization, so don't set LOOKUP_ONLYCONVERTING. */ newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL, - "initialization", NULL_TREE, 0, + ICR_INIT, NULL_TREE, 0, complain); else - newrhs = convert_for_assignment (olhstype, newrhs, "assignment", + newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN, NULL_TREE, 0, complain, LOOKUP_IMPLICIT); if (!same_type_p (lhstype, olhstype)) @@ -7177,7 +7193,7 @@ delta_from_ptrmemfunc (tree t) static tree convert_for_assignment (tree type, tree rhs, - const char *errtype, tree fndecl, int parmnum, + impl_conv_rhs errtype, tree fndecl, int parmnum, tsubst_flags_t complain, int flags) { tree rhstype; @@ -7214,23 +7230,25 @@ convert_for_assignment (tree type, tree rhs, if (c_dialect_objc ()) { int parmno; + tree selector; tree rname = fndecl; - if (!strcmp (errtype, "assignment")) - parmno = -1; - else if (!strcmp (errtype, "initialization")) - parmno = -2; - else - { - tree selector = objc_message_selector (); - - parmno = parmnum; - - if (selector && parmno > 1) - { - rname = selector; - parmno -= 1; - } + switch (errtype) + { + case ICR_ASSIGN: + parmno = -1; + break; + case ICR_INIT: + parmno = -2; + break; + default: + selector = objc_message_selector (); + parmno = parmnum; + if (selector && parmno > 1) + { + rname = selector; + parmno -= 1; + } } if (objc_compare_types (type, rhstype, parmno, rname)) @@ -7267,8 +7285,35 @@ convert_for_assignment (tree type, tree rhs, error ("cannot convert %qT to %qT for argument %qP to %qD", rhstype, type, parmnum, fndecl); else - error ("cannot convert %qT to %qT in %s", rhstype, type, - errtype); + switch (errtype) + { + case ICR_DEFAULT_ARGUMENT: + error ("cannot convert %qT to %qT in default argument", + rhstype, type); + break; + case ICR_ARGPASS: + error ("cannot convert %qT to %qT in argument passing", + rhstype, type); + break; + case ICR_CONVERTING: + error ("cannot convert %qT to %qT", + rhstype, type); + break; + case ICR_INIT: + error ("cannot convert %qT to %qT in initialization", + rhstype, type); + break; + case ICR_RETURN: + error ("cannot convert %qT to %qT in return", + rhstype, type); + break; + case ICR_ASSIGN: + error ("cannot convert %qT to %qT in assignment", + rhstype, type); + break; + default: + gcc_unreachable(); + } } return error_mark_node; } @@ -7280,9 +7325,42 @@ convert_for_assignment (tree type, tree rhs, && coder == codel && check_missing_format_attribute (type, rhstype) && (complain & tf_warning)) - warning (OPT_Wmissing_format_attribute, - "%s might be a candidate for a format attribute", - errtype); + switch (errtype) + { + case ICR_ARGPASS: + case ICR_DEFAULT_ARGUMENT: + if (fndecl) + warning (OPT_Wmissing_format_attribute, + "parameter %d of %qD might be a candidate " + "for a format attribute", parmnum, fndecl); + else + warning (OPT_Wmissing_format_attribute, + "parameter might be a candidate " + "for a format attribute"); + break; + case ICR_CONVERTING: + warning (OPT_Wmissing_format_attribute, + "target of conversion might be might be a candidate " + "for a format attribute"); + break; + case ICR_INIT: + warning (OPT_Wmissing_format_attribute, + "target of initialization might be a candidate " + "for a format attribute"); + break; + case ICR_RETURN: + warning (OPT_Wmissing_format_attribute, + "return type might be a candidate " + "for a format attribute"); + break; + case ICR_ASSIGN: + warning (OPT_Wmissing_format_attribute, + "left-hand side of assignment might be a candidate " + "for a format attribute"); + break; + default: + gcc_unreachable(); + } } /* If -Wparentheses, warn about a = b = c when a has type bool and b @@ -7324,7 +7402,7 @@ convert_for_assignment (tree type, tree rhs, tree convert_for_initialization (tree exp, tree type, tree rhs, int flags, - const char *errtype, tree fndecl, int parmnum, + impl_conv_rhs errtype, tree fndecl, int parmnum, tsubst_flags_t complain) { enum tree_code codel = TREE_CODE (type); @@ -7715,7 +7793,7 @@ check_return_expr (tree retval, bool *no_warning) to the type of return value's location to handle the case that functype is smaller than the valtype. */ retval = convert_for_initialization - (NULL_TREE, functype, retval, flags, "return", NULL_TREE, 0, + (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0, tf_warning_or_error); retval = convert (valtype, retval); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 335b1f3499a..2cc39862897 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -727,10 +727,9 @@ store_init_value (tree decl, tree init, int flags) else if (TREE_CODE (init) == TREE_LIST && TREE_TYPE (init) != unknown_type_node) { - if (TREE_CODE (decl) == RESULT_DECL) - init = build_x_compound_expr_from_list (init, - "return value initializer"); - else if (TREE_CODE (init) == TREE_LIST + gcc_assert (TREE_CODE (decl) != RESULT_DECL); + + if (TREE_CODE (init) == TREE_LIST && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) { error ("cannot initialize arrays using this syntax"); @@ -738,7 +737,7 @@ store_init_value (tree decl, tree init, int flags) } else /* We get here with code like `int a (2);' */ - init = build_x_compound_expr_from_list (init, "initializer"); + init = build_x_compound_expr_from_list (init, ELK_INIT); } /* End of special C++ code. */ @@ -909,7 +908,7 @@ digest_init_r (tree type, tree init, bool nested, int flags) if (cxx_dialect != cxx98 && nested) check_narrowing (type, init); init = convert_for_initialization (0, type, init, flags, - "initialization", NULL_TREE, 0, + ICR_INIT, NULL_TREE, 0, tf_warning_or_error); exp = &init; @@ -963,7 +962,7 @@ digest_init_r (tree type, tree init, bool nested, int flags) return convert_for_initialization (NULL_TREE, type, init, flags, - "initialization", NULL_TREE, 0, + ICR_INIT, NULL_TREE, 0, tf_warning_or_error); } } @@ -1596,7 +1595,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) return cp_convert (type, integer_zero_node); /* This must build a C cast. */ - parms = build_x_compound_expr_from_list (parms, "functional cast"); + parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST); return cp_build_c_cast (type, parms, complain); } -- 2.11.4.GIT