diff options
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c-typeck.c | 268 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/assign-warn-1.c | 123 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/assign-warn-2.c | 124 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/noncompile/20020213-1.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/warn-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/method-9.m | 2 |
8 files changed, 436 insertions, 112 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3ae0a94f28..2c0a9055724 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2004-10-08 Joseph S. Myers <jsm@polyomino.org.uk> + + * c-typeck.c (enum impl_conv): New. + (convert_for_assignment): Use it. Take tree for function called + instead of its name. Handle ObjC selectors for diagnostics at + start of function. Select diagnostic text within the function + using full sentences for diagnsotics. Use %qE to name functions + in diagnostics. + (convert_arguments, build_modify_expr, + c_convert_parm_for_inlining, digest_init, c_finish_return): Update + callers to convert_for_assignment. + (warn_for_assignment): Remove. + 2004-10-08 Nick Clifton <nickc@redhat.com> * config/sh/symbian.c (symbian_possibly_export_base_class): diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 6d7723394c9..64669c88ca3 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -55,6 +55,15 @@ enum lvalue_use { lv_asm }; +/* Possible cases of implicit bad conversions. Used to select + diagnostic messages in convert_for_assignment. */ +enum impl_conv { + ic_argpass, + ic_assign, + ic_init, + ic_return +}; + /* The level of nesting inside "__alignof__". */ int in_alignof; @@ -81,9 +90,8 @@ static tree default_function_array_conversion (tree); static tree lookup_field (tree, tree); static tree convert_arguments (tree, tree, tree, tree); static tree pointer_diff (tree, tree); -static tree convert_for_assignment (tree, tree, const char *, tree, tree, +static tree convert_for_assignment (tree, tree, enum impl_conv, tree, tree, int); -static void warn_for_assignment (const char *, const char *, tree, int); static tree valid_compound_expr_initializer (tree, tree); static void push_string (const char *); static void push_member_name (tree); @@ -2029,16 +2037,12 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl) tree result = NULL; int parmnum; tree selector; - tree name = NULL_TREE; - /* Determine the function name for the use of convert_for_assignment - and warn_for_assignment called from there. */ + /* Change pointer to function to the function itself for + diagnostics. */ if (TREE_CODE (function) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) - { - function = TREE_OPERAND (function, 0); - name = DECL_NAME (function); - } + function = TREE_OPERAND (function, 0); /* Handle an ObjC selector specially for diagnostics. */ selector = objc_message_selector (); @@ -2189,9 +2193,9 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl) } } - parmval = convert_for_assignment (type, val, - (char *) 0, /* arg passing */ - fundecl, name, parmnum + 1); + parmval = convert_for_assignment (type, val, ic_argpass, + fundecl, function, + parmnum + 1); if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0) && INTEGRAL_TYPE_P (type) @@ -3390,7 +3394,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) /* Convert new value to destination type. */ - newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"), + newrhs = convert_for_assignment (lhstype, newrhs, ic_assign, NULL_TREE, NULL_TREE, 0); if (TREE_CODE (newrhs) == ERROR_MARK) return error_mark_node; @@ -3407,7 +3411,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) if (olhstype == TREE_TYPE (result)) return result; - return convert_for_assignment (olhstype, result, _("assignment"), + return convert_for_assignment (olhstype, result, ic_assign, NULL_TREE, NULL_TREE, 0); } @@ -3416,21 +3420,63 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) The real work of conversion is done by `convert'. The purpose of this function is to generate error messages for assignments that are not allowed in C. - ERRTYPE is a string to use in error messages: - "assignment", "return", etc. If it is null, this is parameter passing - for a function call (and different error messages are output). + ERRTYPE says whether it is argument passing, assignment, + initialization or return. - FUNNAME is the name of the function being called, - as an IDENTIFIER_NODE, or null. + FUNCTION is a tree for the function being called. PARMNUM is the number of the argument, for printing in error messages. */ static tree -convert_for_assignment (tree type, tree rhs, const char *errtype, - tree fundecl, tree funname, int parmnum) +convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, + tree fundecl, tree function, int parmnum) { enum tree_code codel = TREE_CODE (type); tree rhstype; enum tree_code coder; + tree rname = NULL_TREE; + + if (errtype == ic_argpass) + { + tree selector; + /* Change pointer to function to the function itself for + diagnostics. */ + if (TREE_CODE (function) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) + function = TREE_OPERAND (function, 0); + + /* Handle an ObjC selector specially for diagnostics. */ + selector = objc_message_selector (); + rname = function; + if (selector && parmnum > 2) + { + rname = selector; + parmnum -= 2; + } + } + + /* 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 WARN_FOR_ASSIGNMENT(AR, AS, IN, RE) \ + do { \ + switch (errtype) \ + { \ + case ic_argpass: \ + pedwarn (AR, parmnum, rname); \ + break; \ + case ic_assign: \ + pedwarn (AS); \ + break; \ + case ic_init: \ + pedwarn (IN); \ + break; \ + case ic_return: \ + pedwarn (RE); \ + break; \ + default: \ + gcc_unreachable (); \ + } \ + } while (0) /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ /* Do not use STRIP_NOPS here. We do not want an enumerator @@ -3507,7 +3553,8 @@ convert_for_assignment (tree type, tree rhs, const char *errtype, /* Conversion to a transparent union from its member types. This applies only to function arguments. */ - else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) && !errtype) + else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) + && errtype == ic_argpass) { tree memb_types; tree marginal_memb_type = 0; @@ -3582,13 +3629,27 @@ convert_for_assignment (tree type, tree rhs, const char *errtype, function where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) - warn_for_assignment ("%s makes qualified function pointer from unqualified", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE " + "makes qualified function " + "pointer from unqualified"), + N_("assignment makes qualified " + "function pointer from " + "unqualified"), + N_("initialization makes qualified " + "function pointer from " + "unqualified"), + N_("return makes qualified function " + "pointer from unqualified")); } else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) - warn_for_assignment ("%s discards qualifiers from pointer target type", - errtype, funname, - parmnum); + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE discards " + "qualifiers from pointer target type"), + N_("assignment discards qualifiers " + "from pointer target type"), + N_("initialization discards qualifiers " + "from pointer target type"), + N_("return discards qualifiers from " + "pointer target type")); } if (pedantic && !DECL_IN_SYSTEM_HEADER (fundecl)) @@ -3630,17 +3691,29 @@ convert_for_assignment (tree type, tree rhs, const char *errtype, which are not ANSI null ptr constants. */ && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR) && TREE_CODE (ttl) == FUNCTION_TYPE))) - warn_for_assignment ("ISO C forbids %s between function " - "pointer and %<void *%>", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("ISO C forbids passing argument %d of " + "%qE between function pointer " + "and %<void *%>"), + N_("ISO C forbids assignment between " + "function pointer and %<void *%>"), + N_("ISO C forbids initialization between " + "function pointer and %<void *%>"), + N_("ISO C forbids return between function " + "pointer and %<void *%>")); /* Const and volatile mean something different for function types, so the usual warnings are not appropriate. */ else if (TREE_CODE (ttr) != FUNCTION_TYPE && TREE_CODE (ttl) != FUNCTION_TYPE) { if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) - warn_for_assignment ("%s discards qualifiers from pointer target type", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE discards " + "qualifiers from pointer target type"), + N_("assignment discards qualifiers " + "from pointer target type"), + N_("initialization discards qualifiers " + "from pointer target type"), + N_("return discards qualifiers from " + "pointer target type")); /* If this is not a case of ignoring a mismatch in signedness, no warning. */ else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) @@ -3648,8 +3721,14 @@ convert_for_assignment (tree type, tree rhs, const char *errtype, ; /* If there is a mismatch, do warn. */ else - warn_for_assignment ("pointer targets in %s differ in signedness", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("pointer targets in passing argument " + "%d of %qE differ in signedness"), + N_("pointer targets in assignment " + "differ in signedness"), + N_("pointer targets in initialization " + "differ in signedness"), + N_("pointer targets in return differ " + "in signedness")); } else if (TREE_CODE (ttl) == FUNCTION_TYPE && TREE_CODE (ttr) == FUNCTION_TYPE) @@ -3659,13 +3738,24 @@ convert_for_assignment (tree type, tree rhs, const char *errtype, it is okay to use a const or volatile function where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) - warn_for_assignment ("%s makes qualified function pointer from unqualified", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE makes " + "qualified function pointer " + "from unqualified"), + N_("assignment makes qualified function " + "pointer from unqualified"), + N_("initialization makes qualified " + "function pointer from unqualified"), + N_("return makes qualified function " + "pointer from unqualified")); } } else - warn_for_assignment ("%s from incompatible pointer type", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE from " + "incompatible pointer type"), + N_("assignment from incompatible pointer type"), + N_("initialization from incompatible " + "pointer type"), + N_("return from incompatible pointer type")); return convert (type, rhs); } else if (codel == POINTER_TYPE && coder == ARRAY_TYPE) @@ -3684,39 +3774,49 @@ convert_for_assignment (tree type, tree rhs, const char *errtype, && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST && integer_zerop (TREE_OPERAND (rhs, 0)))) - warn_for_assignment ("%s makes pointer from integer without a cast", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE makes " + "pointer from integer without a cast"), + N_("assignment makes pointer from integer " + "without a cast"), + N_("initialization makes pointer from " + "integer without a cast"), + N_("return makes pointer from integer " + "without a cast")); return convert (type, rhs); } else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) { - warn_for_assignment ("%s makes integer from pointer without a cast", - errtype, funname, parmnum); + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE makes integer " + "from pointer without a cast"), + N_("assignment makes integer from pointer " + "without a cast"), + N_("initialization makes integer from pointer " + "without a cast"), + N_("return makes integer from pointer " + "without a cast")); return convert (type, rhs); } else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE) return convert (type, rhs); - if (!errtype) + switch (errtype) { - if (funname) - { - tree selector = objc_message_selector (); - - if (selector && parmnum > 2) - error ("incompatible type for argument %d of %qs", - parmnum - 2, IDENTIFIER_POINTER (selector)); - else - error ("incompatible type for argument %d of %qs", - parmnum, IDENTIFIER_POINTER (funname)); - } - else - error ("incompatible type for argument %d of indirect function call", - parmnum); + case ic_argpass: + error ("incompatible type for argument %d of %qE", parmnum, rname); + break; + case ic_assign: + error ("incompatible types in assignment"); + break; + case ic_init: + error ("incompatible types in initialization"); + break; + case ic_return: + error ("incompatible types in return"); + break; + default: + gcc_unreachable (); } - else - error ("incompatible types in %s", errtype); return error_mark_node; } @@ -3737,56 +3837,14 @@ c_convert_parm_for_inlining (tree parm, tree value, tree fn, int argnum) type = TREE_TYPE (parm); ret = convert_for_assignment (type, value, - (char *) 0 /* arg passing */, fn, - DECL_NAME (fn), argnum); + ic_argpass, fn, + fn, argnum); if (targetm.calls.promote_prototypes (TREE_TYPE (fn)) && INTEGRAL_TYPE_P (type) && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) ret = default_conversion (ret); return ret; } - -/* Print a warning using MSGID. - It gets OPNAME as its one parameter. - If OPNAME is null, it is replaced by "passing arg ARGNUM of 'FUNCTION'". - FUNCTION and ARGNUM are handled specially if we are building an - Objective-C selector. */ - -static void -warn_for_assignment (const char *msgid, const char *opname, tree function, - int argnum) -{ - if (opname == 0) - { - tree selector = objc_message_selector (); - char * new_opname; - - if (selector && argnum > 2) - { - function = selector; - argnum -= 2; - } - gcc_assert (argnum > 0); - if (function) - { - /* Function name is known; supply it. */ - const char *const argstring = _("passing arg %d of '%s'"); - new_opname = (char *) alloca (IDENTIFIER_LENGTH (function) - + strlen (argstring) + 1 + 25 /*%d*/ + 1); - sprintf (new_opname, argstring, argnum, - IDENTIFIER_POINTER (function)); - } - else - { - /* Function name unknown (call through ptr); just give arg number. */ - const char *const argnofun = _("passing arg %d of pointer to function"); - new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1); - sprintf (new_opname, argnofun, argnum); - } - opname = new_opname; - } - pedwarn (msgid, opname); -} /* If VALUE is a compound expr all of whose expressions are constant, then return its value. Otherwise, return error_mark_node. @@ -4254,7 +4312,7 @@ digest_init (tree type, tree init, bool strict_string, int require_constant) for arrays and functions. We must not call it in the case where inside_init is a null pointer constant. */ inside_init - = convert_for_assignment (type, init, _("initialization"), + = convert_for_assignment (type, init, ic_init, NULL_TREE, NULL_TREE, 0); /* Check to see if we have already given an error message. */ @@ -6394,7 +6452,7 @@ c_finish_return (tree retval) } else { - tree t = convert_for_assignment (valtype, retval, _("return"), + tree t = convert_for_assignment (valtype, retval, ic_return, NULL_TREE, NULL_TREE, 0); tree res = DECL_RESULT (current_function_decl); tree inner; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6a0cd628625..616e74c2a60 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-10-08 Joseph S. Myers <jsm@polyomino.org.uk> + + * gcc.dg/assign-warn-1.c, gcc.dg/assign-warn-2.c: New tests. + * gcc.dg/warn-1.c, gcc.dg/noncompile/20020213-1.c, + objc.dg/method-9.m: Update expected diagnostics. + 2004-10-07 Geoffrey Keating <geoffk@apple.com> * gcc.dg/ppc-fsel-3.c: New file. diff --git a/gcc/testsuite/gcc.dg/assign-warn-1.c b/gcc/testsuite/gcc.dg/assign-warn-1.c new file mode 100644 index 00000000000..857b1a85333 --- /dev/null +++ b/gcc/testsuite/gcc.dg/assign-warn-1.c @@ -0,0 +1,123 @@ +/* Test diagnostics for bad implicit type conversions. */ +/* Origin: Joseph Myers <jsm@polyomino.org.uk> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic" } */ + +#define TESTARG(ID, TL, TR) void ID##F(TL); void ID##F2(TR x) { ID##F(x); } extern int dummy +#define TESTARP(ID, TL, TR) struct { void (*x)(TL); } ID##Fp; void ID##F2(TR x) { ID##Fp.x(x); } extern int dummy +#define TESTASS(ID, TL, TR) void ID##F(TR x) { TL y; y = x; } extern int dummy +#define TESTINI(ID, TL, TR) void ID##F(TR x) { TL y = x; } extern int dummy +#define TESTRET(ID, TL, TR) TR ID##V; TL ID##F(void) { return ID##V; } extern int dummy + +typedef void (*fp)(void); +typedef void (*nrfp)(void) __attribute__((noreturn)); + +TESTARG(fqa, nrfp, fp); /* { dg-warning "warning: passing argument 1 of 'fqaF' makes qualified function pointer from unqualified" } */ +TESTARP(fqb, nrfp, fp); /* { dg-warning "warning: passing argument 1 of 'fqbFp.x' makes qualified function pointer from unqualified" } */ +TESTASS(fqc, nrfp, fp); /* { dg-warning "warning: assignment makes qualified function pointer from unqualified" } */ +TESTINI(fqd, nrfp, fp); /* { dg-warning "warning: initialization makes qualified function pointer from unqualified" } */ +TESTRET(fqe, nrfp, fp); /* { dg-warning "warning: return makes qualified function pointer from unqualified" } */ + +TESTARG(ofqa, fp, nrfp); +TESTARP(ofqb, fp, nrfp); +TESTASS(ofqc, fp, nrfp); +TESTINI(ofqd, fp, nrfp); +TESTRET(ofqe, fp, nrfp); + +TESTARG(qa, char *, const char *); /* { dg-warning "warning: passing argument 1 of 'qaF' discards qualifiers from pointer target type" } */ +TESTARP(qb, char *, const char *); /* { dg-warning "warning: passing argument 1 of 'qbFp.x' discards qualifiers from pointer target type" } */ +TESTASS(qc, char *, const char *); /* { dg-warning "warning: assignment discards qualifiers from pointer target type" } */ +TESTINI(qd, char *, const char *); /* { dg-warning "warning: initialization discards qualifiers from pointer target type" } */ +TESTRET(qe, char *, const char *); /* { dg-warning "warning: return discards qualifiers from pointer target type" } */ + +TESTARG(oqa, const char *, char *); +TESTARP(oqb, const char *, char *); +TESTASS(oqc, const char *, char *); +TESTINI(oqd, const char *, char *); +TESTRET(oqe, const char *, char *); + +TESTARG(fda, fp, void *); /* { dg-warning "warning: ISO C forbids passing argument 1 of 'fdaF' between function pointer and 'void \\*'" } */ +TESTARP(fdb, fp, void *); /* { dg-warning "warning: ISO C forbids passing argument 1 of 'fdbFp.x' between function pointer and 'void \\*'" } */ +TESTASS(fdc, fp, void *); /* { dg-warning "warning: ISO C forbids assignment between function pointer and 'void \\*'" } */ +TESTINI(fdd, fp, void *); /* { dg-warning "warning: ISO C forbids initialization between function pointer and 'void \\*'" } */ +TESTRET(fde, fp, void *); /* { dg-warning "warning: ISO C forbids return between function pointer and 'void \\*'" } */ + +TESTARG(dfa, void *, fp); /* { dg-warning "warning: ISO C forbids passing argument 1 of 'dfaF' between function pointer and 'void \\*'" } */ +TESTARP(dfb, void *, fp); /* { dg-warning "warning: ISO C forbids passing argument 1 of 'dfbFp.x' between function pointer and 'void \\*'" } */ +TESTASS(dfc, void *, fp); /* { dg-warning "warning: ISO C forbids assignment between function pointer and 'void \\*'" } */ +TESTINI(dfd, void *, fp); /* { dg-warning "warning: ISO C forbids initialization between function pointer and 'void \\*'" } */ +TESTRET(dfe, void *, fp); /* { dg-warning "warning: ISO C forbids return between function pointer and 'void \\*'" } */ + +TESTARG(sua, int *, unsigned int *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'suaF' differ in signedness" } */ +TESTARP(sub, int *, unsigned int *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'subFp.x' differ in signedness" } */ +TESTASS(suc, int *, unsigned int *); /* { dg-warning "warning: pointer targets in assignment differ in signedness" } */ +TESTINI(sud, int *, unsigned int *); /* { dg-warning "warning: pointer targets in initialization differ in signedness" } */ +TESTRET(sue, int *, unsigned int *); /* { dg-warning "warning: pointer targets in return differ in signedness" } */ + +TESTARG(usa, unsigned int *, int *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'usaF' differ in signedness" } */ +TESTARP(usb, unsigned int *, int *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'usbFp.x' differ in signedness" } */ +TESTASS(usc, unsigned int *, int *); /* { dg-warning "warning: pointer targets in assignment differ in signedness" } */ +TESTINI(usd, unsigned int *, int *); /* { dg-warning "warning: pointer targets in initialization differ in signedness" } */ +TESTRET(use, unsigned int *, int *); /* { dg-warning "warning: pointer targets in return differ in signedness" } */ + +TESTARG(cua, char *, unsigned char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'cuaF' differ in signedness" } */ +TESTARP(cub, char *, unsigned char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'cubFp.x' differ in signedness" } */ +TESTASS(cuc, char *, unsigned char *); /* { dg-warning "warning: pointer targets in assignment differ in signedness" } */ +TESTINI(cud, char *, unsigned char *); /* { dg-warning "warning: pointer targets in initialization differ in signedness" } */ +TESTRET(cue, char *, unsigned char *); /* { dg-warning "warning: pointer targets in return differ in signedness" } */ + +TESTARG(uca, unsigned char *, char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'ucaF' differ in signedness" } */ +TESTARP(ucb, unsigned char *, char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'ucbFp.x' differ in signedness" } */ +TESTASS(ucc, unsigned char *, char *); /* { dg-warning "warning: pointer targets in assignment differ in signedness" } */ +TESTINI(ucd, unsigned char *, char *); /* { dg-warning "warning: pointer targets in initialization differ in signedness" } */ +TESTRET(uce, unsigned char *, char *); /* { dg-warning "warning: pointer targets in return differ in signedness" } */ + +TESTARG(csa, char *, signed char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'csaF' differ in signedness" } */ +TESTARP(csb, char *, signed char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'csbFp.x' differ in signedness" } */ +TESTASS(csc, char *, signed char *); /* { dg-warning "warning: pointer targets in assignment differ in signedness" } */ +TESTINI(csd, char *, signed char *); /* { dg-warning "warning: pointer targets in initialization differ in signedness" } */ +TESTRET(cse, char *, signed char *); /* { dg-warning "warning: pointer targets in return differ in signedness" } */ + +TESTARG(sca, signed char *, char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'scaF' differ in signedness" } */ +TESTARP(scb, signed char *, char *); /* { dg-warning "warning: pointer targets in passing argument 1 of 'scbFp.x' differ in signedness" } */ +TESTASS(scc, signed char *, char *); /* { dg-warning "warning: pointer targets in assignment differ in signedness" } */ +TESTINI(scd, signed char *, char *); /* { dg-warning "warning: pointer targets in initialization differ in signedness" } */ +TESTRET(sce, signed char *, char *); /* { dg-warning "warning: pointer targets in return differ in signedness" } */ + +TESTARG(cia, char *, int *); /* { dg-warning "warning: passing argument 1 of 'ciaF' from incompatible pointer type" } */ +TESTARP(cib, char *, int *); /* { dg-warning "warning: passing argument 1 of 'cibFp.x' from incompatible pointer type" } */ +TESTASS(cic, char *, int *); /* { dg-warning "warning: assignment from incompatible pointer type" } */ +TESTINI(cid, char *, int *); /* { dg-warning "warning: initialization from incompatible pointer type" } */ +TESTRET(cie, char *, int *); /* { dg-warning "warning: return from incompatible pointer type" } */ + +TESTARG(ica, int *, char *); /* { dg-warning "warning: passing argument 1 of 'icaF' from incompatible pointer type" } */ +TESTARP(icb, int *, char *); /* { dg-warning "warning: passing argument 1 of 'icbFp.x' from incompatible pointer type" } */ +TESTASS(icc, int *, char *); /* { dg-warning "warning: assignment from incompatible pointer type" } */ +TESTINI(icd, int *, char *); /* { dg-warning "warning: initialization from incompatible pointer type" } */ +TESTRET(ice, int *, char *); /* { dg-warning "warning: return from incompatible pointer type" } */ + +TESTARG(ciia, char *, int); /* { dg-warning "warning: passing argument 1 of 'ciiaF' makes pointer from integer without a cast" } */ +TESTARP(ciib, char *, int); /* { dg-warning "warning: passing argument 1 of 'ciibFp.x' makes pointer from integer without a cast" } */ +TESTASS(ciic, char *, int); /* { dg-warning "warning: assignment makes pointer from integer without a cast" } */ +TESTINI(ciid, char *, int); /* { dg-warning "warning: initialization makes pointer from integer without a cast" } */ +TESTRET(ciie, char *, int); /* { dg-warning "warning: return makes pointer from integer without a cast" } */ + +TESTARG(iica, int, char *); /* { dg-warning "warning: passing argument 1 of 'iicaF' makes integer from pointer without a cast" } */ +TESTARP(iicb, int, char *); /* { dg-warning "warning: passing argument 1 of 'iicbFp.x' makes integer from pointer without a cast" } */ +TESTASS(iicc, int, char *); /* { dg-warning "warning: assignment makes integer from pointer without a cast" } */ +TESTINI(iicd, int, char *); /* { dg-warning "warning: initialization makes integer from pointer without a cast" } */ +TESTRET(iice, int, char *); /* { dg-warning "warning: return makes integer from pointer without a cast" } */ + +struct s { int a; }; + +TESTARG(stria, struct s, int); /* { dg-error "error: incompatible type for argument 1 of 'striaF'" } */ +TESTARP(strib, struct s, int); /* { dg-error "error: incompatible type for argument 1 of 'stribFp.x'" } */ +TESTASS(stric, struct s, int); /* { dg-error "error: incompatible types in assignment" } */ +TESTINI(strid, struct s, int); /* { dg-error "error: invalid initializer" } */ +TESTRET(strie, struct s, int); /* { dg-error "error: incompatible types in return" } */ + +TESTARG(istra, int, struct s); /* { dg-error "error: incompatible type for argument 1 of 'istraF'" } */ +TESTARP(istrb, int, struct s); /* { dg-error "error: incompatible type for argument 1 of 'istrbFp.x'" } */ +TESTASS(istrc, int, struct s); /* { dg-error "error: incompatible types in assignment" } */ +TESTINI(istrd, int, struct s); /* { dg-error "error: incompatible types in initialization" } */ +TESTRET(istre, int, struct s); /* { dg-error "error: incompatible types in return" } */ diff --git a/gcc/testsuite/gcc.dg/assign-warn-2.c b/gcc/testsuite/gcc.dg/assign-warn-2.c new file mode 100644 index 00000000000..eae22d1549b --- /dev/null +++ b/gcc/testsuite/gcc.dg/assign-warn-2.c @@ -0,0 +1,124 @@ +/* Test diagnostics for bad implicit type conversions. + -pedantic-errors test. */ +/* Origin: Joseph Myers <jsm@polyomino.org.uk> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic-errors" } */ + +#define TESTARG(ID, TL, TR) void ID##F(TL); void ID##F2(TR x) { ID##F(x); } extern int dummy +#define TESTARP(ID, TL, TR) struct { void (*x)(TL); } ID##Fp; void ID##F2(TR x) { ID##Fp.x(x); } extern int dummy +#define TESTASS(ID, TL, TR) void ID##F(TR x) { TL y; y = x; } extern int dummy +#define TESTINI(ID, TL, TR) void ID##F(TR x) { TL y = x; } extern int dummy +#define TESTRET(ID, TL, TR) TR ID##V; TL ID##F(void) { return ID##V; } extern int dummy + +typedef void (*fp)(void); +typedef void (*nrfp)(void) __attribute__((noreturn)); + +TESTARG(fqa, nrfp, fp); /* { dg-error "error: passing argument 1 of 'fqaF' makes qualified function pointer from unqualified" } */ +TESTARP(fqb, nrfp, fp); /* { dg-error "error: passing argument 1 of 'fqbFp.x' makes qualified function pointer from unqualified" } */ +TESTASS(fqc, nrfp, fp); /* { dg-error "error: assignment makes qualified function pointer from unqualified" } */ +TESTINI(fqd, nrfp, fp); /* { dg-error "error: initialization makes qualified function pointer from unqualified" } */ +TESTRET(fqe, nrfp, fp); /* { dg-error "error: return makes qualified function pointer from unqualified" } */ + +TESTARG(ofqa, fp, nrfp); +TESTARP(ofqb, fp, nrfp); +TESTASS(ofqc, fp, nrfp); +TESTINI(ofqd, fp, nrfp); +TESTRET(ofqe, fp, nrfp); + +TESTARG(qa, char *, const char *); /* { dg-error "error: passing argument 1 of 'qaF' discards qualifiers from pointer target type" } */ +TESTARP(qb, char *, const char *); /* { dg-error "error: passing argument 1 of 'qbFp.x' discards qualifiers from pointer target type" } */ +TESTASS(qc, char *, const char *); /* { dg-error "error: assignment discards qualifiers from pointer target type" } */ +TESTINI(qd, char *, const char *); /* { dg-error "error: initialization discards qualifiers from pointer target type" } */ +TESTRET(qe, char *, const char *); /* { dg-error "error: return discards qualifiers from pointer target type" } */ + +TESTARG(oqa, const char *, char *); +TESTARP(oqb, const char *, char *); +TESTASS(oqc, const char *, char *); +TESTINI(oqd, const char *, char *); +TESTRET(oqe, const char *, char *); + +TESTARG(fda, fp, void *); /* { dg-error "error: ISO C forbids passing argument 1 of 'fdaF' between function pointer and 'void \\*'" } */ +TESTARP(fdb, fp, void *); /* { dg-error "error: ISO C forbids passing argument 1 of 'fdbFp.x' between function pointer and 'void \\*'" } */ +TESTASS(fdc, fp, void *); /* { dg-error "error: ISO C forbids assignment between function pointer and 'void \\*'" } */ +TESTINI(fdd, fp, void *); /* { dg-error "error: ISO C forbids initialization between function pointer and 'void \\*'" } */ +TESTRET(fde, fp, void *); /* { dg-error "error: ISO C forbids return between function pointer and 'void \\*'" } */ + +TESTARG(dfa, void *, fp); /* { dg-error "error: ISO C forbids passing argument 1 of 'dfaF' between function pointer and 'void \\*'" } */ +TESTARP(dfb, void *, fp); /* { dg-error "error: ISO C forbids passing argument 1 of 'dfbFp.x' between function pointer and 'void \\*'" } */ +TESTASS(dfc, void *, fp); /* { dg-error "error: ISO C forbids assignment between function pointer and 'void \\*'" } */ +TESTINI(dfd, void *, fp); /* { dg-error "error: ISO C forbids initialization between function pointer and 'void \\*'" } */ +TESTRET(dfe, void *, fp); /* { dg-error "error: ISO C forbids return between function pointer and 'void \\*'" } */ + +TESTARG(sua, int *, unsigned int *); /* { dg-error "error: pointer targets in passing argument 1 of 'suaF' differ in signedness" } */ +TESTARP(sub, int *, unsigned int *); /* { dg-error "error: pointer targets in passing argument 1 of 'subFp.x' differ in signedness" } */ +TESTASS(suc, int *, unsigned int *); /* { dg-error "error: pointer targets in assignment differ in signedness" } */ +TESTINI(sud, int *, unsigned int *); /* { dg-error "error: pointer targets in initialization differ in signedness" } */ +TESTRET(sue, int *, unsigned int *); /* { dg-error "error: pointer targets in return differ in signedness" } */ + +TESTARG(usa, unsigned int *, int *); /* { dg-error "error: pointer targets in passing argument 1 of 'usaF' differ in signedness" } */ +TESTARP(usb, unsigned int *, int *); /* { dg-error "error: pointer targets in passing argument 1 of 'usbFp.x' differ in signedness" } */ +TESTASS(usc, unsigned int *, int *); /* { dg-error "error: pointer targets in assignment differ in signedness" } */ +TESTINI(usd, unsigned int *, int *); /* { dg-error "error: pointer targets in initialization differ in signedness" } */ +TESTRET(use, unsigned int *, int *); /* { dg-error "error: pointer targets in return differ in signedness" } */ + +TESTARG(cua, char *, unsigned char *); /* { dg-error "error: pointer targets in passing argument 1 of 'cuaF' differ in signedness" } */ +TESTARP(cub, char *, unsigned char *); /* { dg-error "error: pointer targets in passing argument 1 of 'cubFp.x' differ in signedness" } */ +TESTASS(cuc, char *, unsigned char *); /* { dg-error "error: pointer targets in assignment differ in signedness" } */ +TESTINI(cud, char *, unsigned char *); /* { dg-error "error: pointer targets in initialization differ in signedness" } */ +TESTRET(cue, char *, unsigned char *); /* { dg-error "error: pointer targets in return differ in signedness" } */ + +TESTARG(uca, unsigned char *, char *); /* { dg-error "error: pointer targets in passing argument 1 of 'ucaF' differ in signedness" } */ +TESTARP(ucb, unsigned char *, char *); /* { dg-error "error: pointer targets in passing argument 1 of 'ucbFp.x' differ in signedness" } */ +TESTASS(ucc, unsigned char *, char *); /* { dg-error "error: pointer targets in assignment differ in signedness" } */ +TESTINI(ucd, unsigned char *, char *); /* { dg-error "error: pointer targets in initialization differ in signedness" } */ +TESTRET(uce, unsigned char *, char *); /* { dg-error "error: pointer targets in return differ in signedness" } */ + +TESTARG(csa, char *, signed char *); /* { dg-error "error: pointer targets in passing argument 1 of 'csaF' differ in signedness" } */ +TESTARP(csb, char *, signed char *); /* { dg-error "error: pointer targets in passing argument 1 of 'csbFp.x' differ in signedness" } */ +TESTASS(csc, char *, signed char *); /* { dg-error "error: pointer targets in assignment differ in signedness" } */ +TESTINI(csd, char *, signed char *); /* { dg-error "error: pointer targets in initialization differ in signedness" } */ +TESTRET(cse, char *, signed char *); /* { dg-error "error: pointer targets in return differ in signedness" } */ + +TESTARG(sca, signed char *, char *); /* { dg-error "error: pointer targets in passing argument 1 of 'scaF' differ in signedness" } */ +TESTARP(scb, signed char *, char *); /* { dg-error "error: pointer targets in passing argument 1 of 'scbFp.x' differ in signedness" } */ +TESTASS(scc, signed char *, char *); /* { dg-error "error: pointer targets in assignment differ in signedness" } */ +TESTINI(scd, signed char *, char *); /* { dg-error "error: pointer targets in initialization differ in signedness" } */ +TESTRET(sce, signed char *, char *); /* { dg-error "error: pointer targets in return differ in signedness" } */ + +TESTARG(cia, char *, int *); /* { dg-error "error: passing argument 1 of 'ciaF' from incompatible pointer type" } */ +TESTARP(cib, char *, int *); /* { dg-error "error: passing argument 1 of 'cibFp.x' from incompatible pointer type" } */ +TESTASS(cic, char *, int *); /* { dg-error "error: assignment from incompatible pointer type" } */ +TESTINI(cid, char *, int *); /* { dg-error "error: initialization from incompatible pointer type" } */ +TESTRET(cie, char *, int *); /* { dg-error "error: return from incompatible pointer type" } */ + +TESTARG(ica, int *, char *); /* { dg-error "error: passing argument 1 of 'icaF' from incompatible pointer type" } */ +TESTARP(icb, int *, char *); /* { dg-error "error: passing argument 1 of 'icbFp.x' from incompatible pointer type" } */ +TESTASS(icc, int *, char *); /* { dg-error "error: assignment from incompatible pointer type" } */ +TESTINI(icd, int *, char *); /* { dg-error "error: initialization from incompatible pointer type" } */ +TESTRET(ice, int *, char *); /* { dg-error "error: return from incompatible pointer type" } */ + +TESTARG(ciia, char *, int); /* { dg-error "error: passing argument 1 of 'ciiaF' makes pointer from integer without a cast" } */ +TESTARP(ciib, char *, int); /* { dg-error "error: passing argument 1 of 'ciibFp.x' makes pointer from integer without a cast" } */ +TESTASS(ciic, char *, int); /* { dg-error "error: assignment makes pointer from integer without a cast" } */ +TESTINI(ciid, char *, int); /* { dg-error "error: initialization makes pointer from integer without a cast" } */ +TESTRET(ciie, char *, int); /* { dg-error "error: return makes pointer from integer without a cast" } */ + +TESTARG(iica, int, char *); /* { dg-error "error: passing argument 1 of 'iicaF' makes integer from pointer without a cast" } */ +TESTARP(iicb, int, char *); /* { dg-error "error: passing argument 1 of 'iicbFp.x' makes integer from pointer without a cast" } */ +TESTASS(iicc, int, char *); /* { dg-error "error: assignment makes integer from pointer without a cast" } */ +TESTINI(iicd, int, char *); /* { dg-error "error: initialization makes integer from pointer without a cast" } */ +TESTRET(iice, int, char *); /* { dg-error "error: return makes integer from pointer without a cast" } */ + +struct s { int a; }; + +TESTARG(stria, struct s, int); /* { dg-error "error: incompatible type for argument 1 of 'striaF'" } */ +TESTARP(strib, struct s, int); /* { dg-error "error: incompatible type for argument 1 of 'stribFp.x'" } */ +TESTASS(stric, struct s, int); /* { dg-error "error: incompatible types in assignment" } */ +TESTINI(strid, struct s, int); /* { dg-error "error: invalid initializer" } */ +TESTRET(strie, struct s, int); /* { dg-error "error: incompatible types in return" } */ + +TESTARG(istra, int, struct s); /* { dg-error "error: incompatible type for argument 1 of 'istraF'" } */ +TESTARP(istrb, int, struct s); /* { dg-error "error: incompatible type for argument 1 of 'istrbFp.x'" } */ +TESTASS(istrc, int, struct s); /* { dg-error "error: incompatible types in assignment" } */ +TESTINI(istrd, int, struct s); /* { dg-error "error: incompatible types in initialization" } */ +TESTRET(istre, int, struct s); /* { dg-error "error: incompatible types in return" } */ diff --git a/gcc/testsuite/gcc.dg/noncompile/20020213-1.c b/gcc/testsuite/gcc.dg/noncompile/20020213-1.c index 77798b57c4b..c1de5663ace 100644 --- a/gcc/testsuite/gcc.dg/noncompile/20020213-1.c +++ b/gcc/testsuite/gcc.dg/noncompile/20020213-1.c @@ -24,8 +24,8 @@ int main () return 0; } -/* { dg-warning "passing arg 2 of" "2nd incompatible" { target *-*-* } 15 } */ -/* { dg-warning "passing arg 1 of" "1st incompatible" { target *-*-* } 16 } */ -/* { dg-warning "passing arg 2 of" "2nd incompatible" { target *-*-* } 16 } */ -/* { dg-warning "passing arg 1 of" "1st incompatible" { target *-*-* } 18 } */ -/* { dg-warning "passing arg 1 of" "1st incompatible" { target *-*-* } 20 } */ +/* { dg-warning "passing argument 2 of" "2nd incompatible" { target *-*-* } 15 } */ +/* { dg-warning "passing argument 1 of" "1st incompatible" { target *-*-* } 16 } */ +/* { dg-warning "passing argument 2 of" "2nd incompatible" { target *-*-* } 16 } */ +/* { dg-warning "passing argument 1 of" "1st incompatible" { target *-*-* } 18 } */ +/* { dg-warning "passing argument 1 of" "1st incompatible" { target *-*-* } 20 } */ diff --git a/gcc/testsuite/gcc.dg/warn-1.c b/gcc/testsuite/gcc.dg/warn-1.c index ce35b41e941..dc2cd0e7c71 100644 --- a/gcc/testsuite/gcc.dg/warn-1.c +++ b/gcc/testsuite/gcc.dg/warn-1.c @@ -12,5 +12,5 @@ void bar (void) { void *vp; - foo (vp); /* { dg-warning "passing arg 1 of" } */ + foo (vp); /* { dg-warning "passing argument 1 of" } */ } diff --git a/gcc/testsuite/objc.dg/method-9.m b/gcc/testsuite/objc.dg/method-9.m index ba832840062..3921663ec8f 100644 --- a/gcc/testsuite/objc.dg/method-9.m +++ b/gcc/testsuite/objc.dg/method-9.m @@ -37,7 +37,7 @@ /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 13 } */ /* The following warning is a consequence of picking the "wrong" method signature. */ - /* { dg-warning "passing arg 1 of .initWithData:. from incompatible pointer type" "" { target *-*-* } 33 } */ + /* { dg-warning "passing argument 1 of .initWithData:. from incompatible pointer type" "" { target *-*-* } 33 } */ return result; } @end |