+2010-06-11 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * 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 <froydnj@codesourcery.com>
* cp-tree.h (struct saved_scope): Change decl_ns_list field type
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.
+
{
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
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);
}
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) \
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);
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);
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;
#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);
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 *);
}
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)
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);
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 %<virtual%> %s", object, type);
- if (inlinep)
- error ("%qD declared as an %<inline%> %s", object, type);
- if (quals)
- error ("%<const%> and %<volatile%> function specifiers on "
- "%qD invalid in %s declaration",
- object, type);
+ switch (type)
+ {
+ case BSP_VAR:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> variable", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> variable", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> function specifiers on "
+ "%qD invalid in variable declaration", object);
+ break;
+ case BSP_PARM:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> parameter", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> parameter", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> function specifiers on "
+ "%qD invalid in parameter declaration", object);
+ break;
+ case BSP_TYPE:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> type", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> type", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> function specifiers on "
+ "%qD invalid in type declaration", object);
+ break;
+ case BSP_FIELD:
+ if (virtualp)
+ error ("%qD declared as a %<virtual%> field", object);
+ if (inlinep)
+ error ("%qD declared as an %<inline%> field", object);
+ if (quals)
+ error ("%<const%> and %<volatile%> 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
|| (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);
{
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);
}
}
}
- bad_specifiers (decl, "field", virtualp,
+ bad_specifiers (decl, BSP_FIELD, virtualp,
memfn_quals != TYPE_UNQUALIFIED,
inlinep, friendp, raises != NULL_TREE);
}
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);
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,
{
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);
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,
{
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);
}
/* 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),
/* 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))
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;
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))
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;
}
&& 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
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);
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);
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");
}
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. */
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;
return convert_for_initialization (NULL_TREE, type, init,
flags,
- "initialization", NULL_TREE, 0,
+ ICR_INIT, NULL_TREE, 0,
tf_warning_or_error);
}
}
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);
}