aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2017-08-09 11:28:22 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2017-08-09 11:28:22 +0000
commit296c53ac8ad2a1ec7483d81f8ed9e2eee520f841 (patch)
tree55125f47ef7ad3c4c9971722231b7e845ddabe49 /gcc/c
parenta32c8316ff282ec3eb60e222e91fb19998c12f46 (diff)
downloadgcc-296c53ac8ad2a1ec7483d81f8ed9e2eee520f841.zip
gcc-296c53ac8ad2a1ec7483d81f8ed9e2eee520f841.tar.gz
gcc-296c53ac8ad2a1ec7483d81f8ed9e2eee520f841.tar.bz2
re PR c/81233 (--Wdiscarded-qualifiers and Wincompatible-pointer-types missing important detail)
PR c/81233 * c-typeck.c (pedwarn_init): Make the function take a variable list. Call emit_diagnostic_valist instead of pedwarn. (convert_for_assignment): Unroll the PEDWARN_FOR_ASSIGNMENT macro. Print the relevant types in diagnostics. * diagnostic-core.h (emit_diagnostic_valist): Add declaration. * diagnostic.c (emit_diagnostic): Add a comment. (emit_diagnostic_valist): New function. * gcc.dg/diagnostic-types-1.c: New test. * gcc.dg/assign-warn-1.c: Update warning messages. * gcc.dg/assign-warn-2.c: Likewise. * gcc.dg/c90-const-expr-5.c: Likewise. * gcc.dg/c99-const-expr-5.c: Likewise. * gcc.dg/conv-2.c: Likewise. * gcc.dg/init-bad-7.c: Likewise. * gcc.dg/overflow-warn-1.c: Likewise. * gcc.dg/overflow-warn-2.c: Likewise. * gcc.dg/overflow-warn-3.c: Likewise. * gcc.dg/overflow-warn-4.c: Likewise. * gcc.dg/pointer-array-atomic.c: Likewise. * gcc.dg/pr26865.c: Likewise. * gcc.dg/pr61162-2.c: Likewise. * gcc.dg/pr61162.c: Likewise. * gcc.dg/pr67730-2.c: Likewise. * gcc.dg/pr69156.c: Likewise. * gcc.dg/pr70174.c: Likewise. * objc.dg/proto-lossage-4.m: Likewise. From-SVN: r250985
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog8
-rw-r--r--gcc/c/c-typeck.c215
2 files changed, 164 insertions, 59 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 580cda0..98482ad 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,5 +1,13 @@
2017-08-09 Marek Polacek <polacek@redhat.com>
+ PR c/81233
+ * c-typeck.c (pedwarn_init): Make the function take a variable list.
+ Call emit_diagnostic_valist instead of pedwarn.
+ (convert_for_assignment): Unroll the PEDWARN_FOR_ASSIGNMENT macro.
+ Print the relevant types in diagnostics.
+
+2017-08-09 Marek Polacek <polacek@redhat.com>
+
PR c/81417
* c-array-notation.c (fix_builtin_array_notation_fn): Update calls to
build_conditional_expr.
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 8033a81..c5c9508 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -6065,20 +6065,19 @@ error_init (location_t loc, const char *gmsgid)
it is unconditionally given. GMSGID identifies the message. The
component name is taken from the spelling stack. */
-static void
-pedwarn_init (location_t loc, int opt, const char *gmsgid)
+static void ATTRIBUTE_GCC_DIAG (3,0)
+pedwarn_init (location_t loc, int opt, const char *gmsgid, ...)
{
- char *ofwhat;
- bool warned;
-
/* Use the location where a macro was expanded rather than where
it was defined to make sure macros defined in system headers
but used incorrectly elsewhere are diagnosed. */
source_location exploc = expansion_point_location_if_in_system_header (loc);
- /* The gmsgid may be a format string with %< and %>. */
- warned = pedwarn (exploc, opt, gmsgid);
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ va_list ap;
+ va_start (ap, gmsgid);
+ bool warned = emit_diagnostic_valist (DK_PEDWARN, exploc, opt, gmsgid, &ap);
+ va_end (ap);
+ char *ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat && warned)
inform (exploc, "(near initialization for %qs)", ofwhat);
}
@@ -6311,17 +6310,33 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
if (checktype != error_mark_node
&& TREE_CODE (type) == ENUMERAL_TYPE
&& TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (type))
- {
- PEDWARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wc___compat,
- G_("enum conversion when passing argument "
- "%d of %qE is invalid in C++"),
- G_("enum conversion in assignment is "
- "invalid in C++"),
- G_("enum conversion in initialization is "
- "invalid in C++"),
- G_("enum conversion in return is "
- "invalid in C++"));
- }
+ switch (errtype)
+ {
+ case ic_argpass:
+ if (pedwarn (expr_loc, OPT_Wc___compat, "enum conversion when "
+ "passing argument %d of %qE is invalid in C++",
+ parmnum, rname))
+ inform ((fundecl && !DECL_IS_BUILTIN (fundecl))
+ ? DECL_SOURCE_LOCATION (fundecl) : expr_loc,
+ "expected %qT but argument is of type %qT",
+ type, rhstype);
+ break;
+ case ic_assign:
+ pedwarn (location, OPT_Wc___compat, "enum conversion from %qT to "
+ "%qT in assignment is invalid in C++", rhstype, type);
+ break;
+ case ic_init:
+ pedwarn_init (location, OPT_Wc___compat, "enum conversion from "
+ "%qT to %qT in initialization is invalid in C++",
+ rhstype, type);
+ break;
+ case ic_return:
+ pedwarn (location, OPT_Wc___compat, "enum conversion from %qT to "
+ "%qT in return is invalid in C++", rhstype, type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
}
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
@@ -6727,15 +6742,36 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
;
/* If there is a mismatch, do warn. */
else if (warn_pointer_sign)
- PEDWARN_FOR_ASSIGNMENT (location, expr_loc, OPT_Wpointer_sign,
- G_("pointer targets in passing argument "
- "%d of %qE differ in signedness"),
- G_("pointer targets in assignment "
- "differ in signedness"),
- G_("pointer targets in initialization "
- "differ in signedness"),
- G_("pointer targets in return differ "
- "in signedness"));
+ switch (errtype)
+ {
+ case ic_argpass:
+ if (pedwarn (expr_loc, OPT_Wpointer_sign,
+ "pointer targets in passing argument %d of "
+ "%qE differ in signedness", parmnum, rname))
+ inform ((fundecl && !DECL_IS_BUILTIN (fundecl))
+ ? DECL_SOURCE_LOCATION (fundecl) : expr_loc,
+ "expected %qT but argument is of type %qT",
+ type, rhstype);
+ break;
+ case ic_assign:
+ pedwarn (location, OPT_Wpointer_sign,
+ "pointer targets in assignment from %qT to %qT "
+ "differ in signedness", rhstype, type);
+ break;
+ case ic_init:
+ pedwarn_init (location, OPT_Wpointer_sign,
+ "pointer targets in initialization of %qT "
+ "from %qT differ in signedness", type,
+ rhstype);
+ break;
+ case ic_return:
+ pedwarn (location, OPT_Wpointer_sign, "pointer targets in "
+ "returning %qT from a function with return type "
+ "%qT differ in signedness", rhstype, type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
}
else if (TREE_CODE (ttl) == FUNCTION_TYPE
&& TREE_CODE (ttr) == FUNCTION_TYPE)
@@ -6760,17 +6796,39 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr));
}
}
- else
- /* Avoid warning about the volatile ObjC EH puts on decls. */
- if (!objc_ok)
- PEDWARN_FOR_ASSIGNMENT (location, expr_loc,
- OPT_Wincompatible_pointer_types,
- G_("passing argument %d of %qE from "
- "incompatible pointer type"),
- G_("assignment from incompatible pointer type"),
- G_("initialization from incompatible "
- "pointer type"),
- G_("return from incompatible pointer type"));
+ /* Avoid warning about the volatile ObjC EH puts on decls. */
+ else if (!objc_ok)
+ {
+ switch (errtype)
+ {
+ case ic_argpass:
+ if (pedwarn (expr_loc, OPT_Wincompatible_pointer_types,
+ "passing argument %d of %qE from incompatible "
+ "pointer type", parmnum, rname))
+ inform ((fundecl && !DECL_IS_BUILTIN (fundecl))
+ ? DECL_SOURCE_LOCATION (fundecl) : expr_loc,
+ "expected %qT but argument is of type %qT",
+ type, rhstype);
+ break;
+ case ic_assign:
+ pedwarn (location, OPT_Wincompatible_pointer_types,
+ "assignment to %qT from incompatible pointer type %qT",
+ type, rhstype);
+ break;
+ case ic_init:
+ pedwarn_init (location, OPT_Wincompatible_pointer_types,
+ "initialization of %qT from incompatible pointer "
+ "type %qT", type, rhstype);
+ break;
+ case ic_return:
+ pedwarn (location, OPT_Wincompatible_pointer_types,
+ "returning %qT from a function with incompatible "
+ "return type %qT", rhstype, type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
return convert (type, rhs);
}
@@ -6787,31 +6845,70 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
or one that results from arithmetic, even including
a cast to integer type. */
if (!null_pointer_constant)
- PEDWARN_FOR_ASSIGNMENT (location, expr_loc,
- OPT_Wint_conversion,
- G_("passing argument %d of %qE makes "
- "pointer from integer without a cast"),
- G_("assignment makes pointer from integer "
- "without a cast"),
- G_("initialization makes pointer from "
- "integer without a cast"),
- G_("return makes pointer from integer "
- "without a cast"));
+ switch (errtype)
+ {
+ case ic_argpass:
+ if (pedwarn (expr_loc, OPT_Wint_conversion,
+ "passing argument %d of %qE makes pointer from "
+ "integer without a cast", parmnum, rname))
+ inform ((fundecl && !DECL_IS_BUILTIN (fundecl))
+ ? DECL_SOURCE_LOCATION (fundecl) : expr_loc,
+ "expected %qT but argument is of type %qT",
+ type, rhstype);
+ break;
+ case ic_assign:
+ pedwarn (location, OPT_Wint_conversion,
+ "assignment to %qT from %qT makes pointer from integer "
+ "without a cast", type, rhstype);
+ break;
+ case ic_init:
+ pedwarn_init (location, OPT_Wint_conversion,
+ "initialization of %qT from %qT makes pointer from "
+ "integer without a cast", type, rhstype);
+ break;
+ case ic_return:
+ pedwarn (location, OPT_Wint_conversion, "returning %qT from a "
+ "function with return type %qT makes pointer from "
+ "integer without a cast", rhstype, type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
return convert (type, rhs);
}
else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
{
- PEDWARN_FOR_ASSIGNMENT (location, expr_loc,
- OPT_Wint_conversion,
- G_("passing argument %d of %qE makes integer "
- "from pointer without a cast"),
- G_("assignment makes integer from pointer "
- "without a cast"),
- G_("initialization makes integer from pointer "
- "without a cast"),
- G_("return makes integer from pointer "
- "without a cast"));
+ switch (errtype)
+ {
+ case ic_argpass:
+ if (pedwarn (expr_loc, OPT_Wint_conversion,
+ "passing argument %d of %qE makes integer from "
+ "pointer without a cast", parmnum, rname))
+ inform ((fundecl && !DECL_IS_BUILTIN (fundecl))
+ ? DECL_SOURCE_LOCATION (fundecl) : expr_loc,
+ "expected %qT but argument is of type %qT",
+ type, rhstype);
+ break;
+ case ic_assign:
+ pedwarn (location, OPT_Wint_conversion,
+ "assignment to %qT from %qT makes integer from pointer "
+ "without a cast", type, rhstype);
+ break;
+ case ic_init:
+ pedwarn_init (location, OPT_Wint_conversion,
+ "initialization of %qT from %qT makes integer from "
+ "pointer without a cast", type, rhstype);
+ break;
+ case ic_return:
+ pedwarn (location, OPT_Wint_conversion, "returning %qT from a "
+ "function with return type %qT makes integer from "
+ "pointer without a cast", rhstype, type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
return convert (type, rhs);
}
else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE)