re PR c/25880 (improve message of warning for discarding qualifiers)

2010-06-04  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	PR c/25880
	* c-objc-common.c (c_tree_printer): Handle %V, %v and %#v.
	* c-format.c (gcc_diag_flag_specs): Add hash.
	(gcc_cxxdiag_flag_specs): Use gcc_diag_flag_specs directly.
	(gcc_tdiag_char_table,gcc_cdiag_char_table): Handle %V and %v.
	* c-pretty-print.c (pp_c_cv_qualifier): Rename as
	pp_c_cv_qualifiers. Handle qualifiers spelling here.
	(pp_c_type_qualifier_list): Call the function above.
	* c-pretty-print.h (pp_c_cv_qualifiers): Declare.
	* c-typeck.c (handle_warn_cast_qual): Print qualifiers.
	(WARN_FOR_QUALIFIERS): New macro.
	(convert_for_assignment): Use it.
testsuite/
	* gcc.dg/assign-warn-2.c: Update.
	* gcc.dg/cpp/line3.c: Update.
	* gcc.dg/c99-array-lval-8.c: Update.
	* gcc.dg/cast-qual-2.c: Update.
	* gcc.dg/c99-arraydecl-3.c:  Update.
	* gcc.dg/assign-warn-1.c:  Update.
	* gcc.dg/format/gcc_diag-1.c:  Update.

From-SVN: r160274
parent b13ea8bd
2010-06-04 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/25880
* c-objc-common.c (c_tree_printer): Handle %V, %v and %#v.
* c-format.c (gcc_diag_flag_specs): Add hash.
(gcc_cxxdiag_flag_specs): Use gcc_diag_flag_specs directly.
(gcc_tdiag_char_table,gcc_cdiag_char_table): Handle %V and %v.
* c-pretty-print.c (pp_c_cv_qualifier): Rename as
pp_c_cv_qualifiers. Handle qualifiers spelling here.
(pp_c_type_qualifier_list): Call the function above.
* c-pretty-print.h (pp_c_cv_qualifiers): Declare.
* c-typeck.c (handle_warn_cast_qual): Print qualifiers.
(WARN_FOR_QUALIFIERS): New macro.
(convert_for_assignment): Use it.
2010-06-04 Kai Tietz <kai.tietz@onevision.com> 2010-06-04 Kai Tietz <kai.tietz@onevision.com>
* config/i386/cygming.h (ASM_GENERATE_INTERNAL_LABEL): Prefix * config/i386/cygming.h (ASM_GENERATE_INTERNAL_LABEL): Prefix
......
...@@ -421,6 +421,7 @@ static const format_flag_pair gcc_gfc_flag_pairs[] = ...@@ -421,6 +421,7 @@ static const format_flag_pair gcc_gfc_flag_pairs[] =
static const format_flag_spec gcc_diag_flag_specs[] = static const format_flag_spec gcc_diag_flag_specs[] =
{ {
{ '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
{ '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
{ 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 }, { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
{ 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
...@@ -429,16 +430,7 @@ static const format_flag_spec gcc_diag_flag_specs[] = ...@@ -429,16 +430,7 @@ static const format_flag_spec gcc_diag_flag_specs[] =
#define gcc_tdiag_flag_specs gcc_diag_flag_specs #define gcc_tdiag_flag_specs gcc_diag_flag_specs
#define gcc_cdiag_flag_specs gcc_diag_flag_specs #define gcc_cdiag_flag_specs gcc_diag_flag_specs
#define gcc_cxxdiag_flag_specs gcc_diag_flag_specs
static const format_flag_spec gcc_cxxdiag_flag_specs[] =
{
{ '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
{ '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
{ 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
{ 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
{ 0, 0, 0, NULL, NULL, STD_C89 }
};
static const format_flag_spec scanf_flag_specs[] = static const format_flag_spec scanf_flag_specs[] =
{ {
...@@ -585,7 +577,9 @@ static const format_char_info gcc_tdiag_char_table[] = ...@@ -585,7 +577,9 @@ static const format_char_info gcc_tdiag_char_table[] =
/* Custom conversion specifiers. */ /* Custom conversion specifiers. */
/* These will require a "tree" at runtime. */ /* These will require a "tree" at runtime. */
{ "DFKTE", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, { "DFKTEV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
{ "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
...@@ -605,7 +599,9 @@ static const format_char_info gcc_cdiag_char_table[] = ...@@ -605,7 +599,9 @@ static const format_char_info gcc_cdiag_char_table[] =
/* Custom conversion specifiers. */ /* Custom conversion specifiers. */
/* These will require a "tree" at runtime. */ /* These will require a "tree" at runtime. */
{ "DEFKT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, { "DEFKTV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
{ "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
...@@ -627,6 +623,8 @@ static const format_char_info gcc_cxxdiag_char_table[] = ...@@ -627,6 +623,8 @@ static const format_char_info gcc_cxxdiag_char_table[] =
/* These will require a "tree" at runtime. */ /* These will require a "tree" at runtime. */
{ "ADEFKTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL }, { "ADEFKTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
{ "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
/* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */ /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
...@@ -722,19 +720,19 @@ static const format_kind_info format_types_orig[] = ...@@ -722,19 +720,19 @@ static const format_kind_info format_types_orig[] =
'w', 0, 'p', 0, 'L', 0, 'w', 0, 'p', 0, 'L', 0,
NULL, NULL NULL, NULL
}, },
{ "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL, { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+#", NULL,
gcc_diag_flag_specs, gcc_diag_flag_pairs, gcc_diag_flag_specs, gcc_diag_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0, 0, 0, 'p', 0, 'L', 0,
NULL, &integer_type_node NULL, &integer_type_node
}, },
{ "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL, { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+#", NULL,
gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs, gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0, 0, 0, 'p', 0, 'L', 0,
NULL, &integer_type_node NULL, &integer_type_node
}, },
{ "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL, { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+#", NULL,
gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs, gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
FMT_FLAG_ARG_CONVERT, FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0, 0, 0, 'p', 0, 'L', 0,
......
...@@ -79,9 +79,10 @@ c_objc_common_init (void) ...@@ -79,9 +79,10 @@ c_objc_common_init (void)
%E: an identifier or expression, %E: an identifier or expression,
%F: a function declaration, %F: a function declaration,
%T: a type. %T: a type.
%V: a list of type qualifiers from a tree.
%v: an explicit list of type qualifiers
%#v: an explicit list of type qualifiers of a function type.
These format specifiers form a subset of the format specifiers set used
by the C++ front-end.
Please notice when called, the `%' part was already skipped by the Please notice when called, the `%' part was already skipped by the
diagnostic machinery. */ diagnostic machinery. */
static bool static bool
...@@ -93,7 +94,7 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec, ...@@ -93,7 +94,7 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
c_pretty_printer *cpp = (c_pretty_printer *) pp; c_pretty_printer *cpp = (c_pretty_printer *) pp;
pp->padding = pp_none; pp->padding = pp_none;
if (precision != 0 || wide || hash) if (precision != 0 || wide)
return false; return false;
if (*spec == 'K') if (*spec == 'K')
...@@ -102,10 +103,12 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec, ...@@ -102,10 +103,12 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
return true; return true;
} }
if (*spec != 'v')
{
t = va_arg (*text->args_ptr, tree); t = va_arg (*text->args_ptr, tree);
if (set_locus && text->locus) if (set_locus && text->locus)
*text->locus = DECL_SOURCE_LOCATION (t); *text->locus = DECL_SOURCE_LOCATION (t);
}
switch (*spec) switch (*spec)
{ {
...@@ -155,6 +158,14 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec, ...@@ -155,6 +158,14 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
pp_expression (cpp, t); pp_expression (cpp, t);
return true; return true;
case 'V':
pp_c_type_qualifier_list (cpp, t);
return true;
case 'v':
pp_c_cv_qualifiers (cpp, va_arg (*text->args_ptr, int), hash);
return true;
default: default:
return false; return false;
} }
......
...@@ -170,18 +170,43 @@ pp_c_exclamation (c_pretty_printer *pp) ...@@ -170,18 +170,43 @@ pp_c_exclamation (c_pretty_printer *pp)
pp_base (pp)->padding = pp_none; pp_base (pp)->padding = pp_none;
} }
/* Print out the external representation of CV-QUALIFIER. */ /* Print out the external representation of QUALIFIERS. */
static void void
pp_c_cv_qualifier (c_pretty_printer *pp, const char *cv) pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type)
{ {
const char *p = pp_last_position_in_text (pp); const char *p = pp_last_position_in_text (pp);
bool previous = false;
if (!qualifiers)
return;
/* The C programming language does not have references, but it is much /* The C programming language does not have references, but it is much
simpler to handle those here rather than going through the same simpler to handle those here rather than going through the same
logic in the C++ pretty-printer. */ logic in the C++ pretty-printer. */
if (p != NULL && (*p == '*' || *p == '&')) if (p != NULL && (*p == '*' || *p == '&'))
pp_c_whitespace (pp); pp_c_whitespace (pp);
pp_c_ws_string (pp, cv);
if (qualifiers & TYPE_QUAL_CONST)
{
pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
previous = true;
}
if (qualifiers & TYPE_QUAL_VOLATILE)
{
if (previous)
pp_c_whitespace (pp);
pp_c_ws_string (pp, func_type ? "__attribute__((noreturn))" : "volatile");
previous = true;
}
if (qualifiers & TYPE_QUAL_RESTRICT)
{
if (previous)
pp_c_whitespace (pp);
pp_c_ws_string (pp, flag_isoc99 ? "restrict" : "__restrict__");
}
} }
/* Pretty-print T using the type-cast notation '( type-name )'. */ /* Pretty-print T using the type-cast notation '( type-name )'. */
...@@ -242,12 +267,8 @@ pp_c_type_qualifier_list (c_pretty_printer *pp, tree t) ...@@ -242,12 +267,8 @@ pp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
t = TREE_TYPE (t); t = TREE_TYPE (t);
qualifiers = TYPE_QUALS (t); qualifiers = TYPE_QUALS (t);
if (qualifiers & TYPE_QUAL_CONST) pp_c_cv_qualifiers (pp, qualifiers,
pp_c_cv_qualifier (pp, "const"); TREE_CODE (t) == FUNCTION_TYPE);
if (qualifiers & TYPE_QUAL_VOLATILE)
pp_c_cv_qualifier (pp, "volatile");
if (qualifiers & TYPE_QUAL_RESTRICT)
pp_c_cv_qualifier (pp, flag_isoc99 ? "restrict" : "__restrict__");
if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t))) if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t)))
{ {
......
...@@ -176,6 +176,7 @@ void pp_c_space_for_pointer_operator (c_pretty_printer *, tree); ...@@ -176,6 +176,7 @@ void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
void pp_c_tree_decl_identifier (c_pretty_printer *, tree); void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
void pp_c_function_definition (c_pretty_printer *, tree); void pp_c_function_definition (c_pretty_printer *, tree);
void pp_c_attributes (c_pretty_printer *, tree); void pp_c_attributes (c_pretty_printer *, tree);
void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type);
void pp_c_type_qualifier_list (c_pretty_printer *, tree); void pp_c_type_qualifier_list (c_pretty_printer *, tree);
void pp_c_parameter_type_list (c_pretty_printer *, tree); void pp_c_parameter_type_list (c_pretty_printer *, tree);
void pp_c_declaration (c_pretty_printer *, tree); void pp_c_declaration (c_pretty_printer *, tree);
......
...@@ -4440,13 +4440,15 @@ handle_warn_cast_qual (tree type, tree otype) ...@@ -4440,13 +4440,15 @@ handle_warn_cast_qual (tree type, tree otype)
&& TREE_CODE (in_otype) == POINTER_TYPE); && TREE_CODE (in_otype) == POINTER_TYPE);
if (added) if (added)
warning (OPT_Wcast_qual, "cast adds new qualifiers to function type"); warning (OPT_Wcast_qual, "cast adds %q#v qualifier to function type",
added);
if (discarded) if (discarded)
/* There are qualifiers present in IN_OTYPE that are not present /* There are qualifiers present in IN_OTYPE that are not present
in IN_TYPE. */ in IN_TYPE. */
warning (OPT_Wcast_qual, warning (OPT_Wcast_qual,
"cast discards qualifiers from pointer target type"); "cast discards %q#v qualifier from pointer target type",
discarded);
if (added || discarded) if (added || discarded)
return; return;
...@@ -4479,9 +4481,10 @@ handle_warn_cast_qual (tree type, tree otype) ...@@ -4479,9 +4481,10 @@ handle_warn_cast_qual (tree type, tree otype)
if ((TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype)) != 0 if ((TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype)) != 0
&& !is_const) && !is_const)
{ {
int added = TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype);
warning (OPT_Wcast_qual, warning (OPT_Wcast_qual,
("new qualifiers in middle of multi-level non-const cast " ("new %qv qualifier in middle of multi-level non-const cast "
"are unsafe")); "is unsafe"), added);
break; break;
} }
if (is_const) if (is_const)
...@@ -5007,6 +5010,36 @@ convert_for_assignment (location_t location, tree type, tree rhs, ...@@ -5007,6 +5010,36 @@ convert_for_assignment (location_t location, tree type, tree rhs,
} \ } \
} while (0) } while (0)
/* This macro is used to emit diagnostics to ensure that all format
strings are complete sentences, visible to gettext and checked at
compile time. It is the same as WARN_FOR_ASSIGNMENT but with an
extra parameter to enumerate qualifiers. */
#define WARN_FOR_QUALIFIERS(LOCATION, OPT, AR, AS, IN, RE, QUALS) \
do { \
switch (errtype) \
{ \
case ic_argpass: \
if (pedwarn (LOCATION, OPT, AR, parmnum, rname, QUALS)) \
inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \
? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \
"expected %qT but argument is of type %qT", \
type, rhstype); \
break; \
case ic_assign: \
pedwarn (LOCATION, OPT, AS, QUALS); \
break; \
case ic_init: \
pedwarn (LOCATION, OPT, IN, QUALS); \
break; \
case ic_return: \
pedwarn (LOCATION, OPT, RE, QUALS); \
break; \
default: \
gcc_unreachable (); \
} \
} while (0)
if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR) if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
rhs = TREE_OPERAND (rhs, 0); rhs = TREE_OPERAND (rhs, 0);
...@@ -5214,30 +5247,32 @@ convert_for_assignment (location_t location, tree type, tree rhs, ...@@ -5214,30 +5247,32 @@ convert_for_assignment (location_t location, tree type, tree rhs,
vice-versa. */ vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl) if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr)) & ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
WARN_FOR_ASSIGNMENT (location, 0, WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE " G_("passing argument %d of %qE "
"makes qualified function " "makes %q#v qualified function "
"pointer from unqualified"), "pointer from unqualified"),
G_("assignment makes qualified " G_("assignment makes %q#v qualified "
"function pointer from " "function pointer from "
"unqualified"), "unqualified"),
G_("initialization makes qualified " G_("initialization makes %q#v qualified "
"function pointer from " "function pointer from "
"unqualified"), "unqualified"),
G_("return makes qualified function " G_("return makes %q#v qualified function "
"pointer from unqualified")); "pointer from unqualified"),
TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr));
} }
else if (TYPE_QUALS_NO_ADDR_SPACE (ttr) else if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttl)) & ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
WARN_FOR_ASSIGNMENT (location, 0, WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE discards " G_("passing argument %d of %qE discards "
"qualifiers from pointer target type"), "%qv qualifier from pointer target type"),
G_("assignment discards qualifiers " G_("assignment discards %qv qualifier "
"from pointer target type"), "from pointer target type"),
G_("initialization discards qualifiers " G_("initialization discards %qv qualifier "
"from pointer target type"), "from pointer target type"),
G_("return discards qualifiers from " G_("return discards %qv qualifier from "
"pointer target type")); "pointer target type"),
TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
memb = marginal_memb; memb = marginal_memb;
} }
...@@ -5383,15 +5418,16 @@ convert_for_assignment (location_t location, tree type, tree rhs, ...@@ -5383,15 +5418,16 @@ convert_for_assignment (location_t location, tree type, tree rhs,
qualifier are acceptable if the 'volatile' has been added qualifier are acceptable if the 'volatile' has been added
in by the Objective-C EH machinery. */ in by the Objective-C EH machinery. */
if (!objc_type_quals_match (ttl, ttr)) if (!objc_type_quals_match (ttl, ttr))
WARN_FOR_ASSIGNMENT (location, 0, WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE discards " G_("passing argument %d of %qE discards "
"qualifiers from pointer target type"), "%qv qualifier from pointer target type"),
G_("assignment discards qualifiers " G_("assignment discards %qv qualifier "
"from pointer target type"), "from pointer target type"),
G_("initialization discards qualifiers " G_("initialization discards %qv qualifier "
"from pointer target type"), "from pointer target type"),
G_("return discards qualifiers from " G_("return discards %qv qualifier from "
"pointer target type")); "pointer target type"),
TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
} }
/* If this is not a case of ignoring a mismatch in signedness, /* If this is not a case of ignoring a mismatch in signedness,
no warning. */ no warning. */
...@@ -5419,16 +5455,17 @@ convert_for_assignment (location_t location, tree type, tree rhs, ...@@ -5419,16 +5455,17 @@ convert_for_assignment (location_t location, tree type, tree rhs,
where an ordinary one is wanted, but not vice-versa. */ where an ordinary one is wanted, but not vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl) if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr)) & ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
WARN_FOR_ASSIGNMENT (location, 0, WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE makes " G_("passing argument %d of %qE makes "
"qualified function pointer " "%q#v qualified function pointer "
"from unqualified"), "from unqualified"),
G_("assignment makes qualified function " G_("assignment makes %q#v qualified function "
"pointer from unqualified"), "pointer from unqualified"),
G_("initialization makes qualified " G_("initialization makes %q#v qualified "
"function pointer from unqualified"), "function pointer from unqualified"),
G_("return makes qualified function " G_("return makes %q#v qualified function "
"pointer from unqualified")); "pointer from unqualified"),
TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr));
} }
} }
else else
......
2010-06-04 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/25880
* gcc.dg/assign-warn-2.c: Update.
* gcc.dg/cpp/line3.c: Update.
* gcc.dg/c99-array-lval-8.c: Update.
* gcc.dg/cast-qual-2.c: Update.
* gcc.dg/c99-arraydecl-3.c: Update.
* gcc.dg/assign-warn-1.c: Update.
* gcc.dg/format/gcc_diag-1.c: Update.
2010-06-04 Bernd Schmidt <bernds@codesourcery.com> 2010-06-04 Bernd Schmidt <bernds@codesourcery.com>
PR rtl-optimization/39871 PR rtl-optimization/39871
......
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
typedef void (*fp)(void); typedef void (*fp)(void);
typedef void (*nrfp)(void) __attribute__((noreturn)); typedef void (*nrfp)(void) __attribute__((noreturn));
TESTARG(fqa, nrfp, fp); /* { dg-warning "passing argument 1 of 'fqaF' makes qualified function pointer from unqualified" } */ TESTARG(fqa, nrfp, fp); /* { dg-warning "passing argument 1 of 'fqaF' makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTARP(fqb, nrfp, fp); /* { dg-warning "passing argument 1 of 'fqbFp.x' makes qualified function pointer from unqualified" } */ TESTARP(fqb, nrfp, fp); /* { dg-warning "passing argument 1 of 'fqbFp.x' makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTASS(fqc, nrfp, fp); /* { dg-warning "assignment makes qualified function pointer from unqualified" } */ TESTASS(fqc, nrfp, fp); /* { dg-warning "assignment makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTINI(fqd, nrfp, fp); /* { dg-warning "initialization makes qualified function pointer from unqualified" } */ TESTINI(fqd, nrfp, fp); /* { dg-warning "initialization makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTRET(fqe, nrfp, fp); /* { dg-warning "return makes qualified function pointer from unqualified" } */ TESTRET(fqe, nrfp, fp); /* { dg-warning "return makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTARG(ofqa, fp, nrfp); TESTARG(ofqa, fp, nrfp);
TESTARP(ofqb, fp, nrfp); TESTARP(ofqb, fp, nrfp);
...@@ -24,11 +24,11 @@ TESTASS(ofqc, fp, nrfp); ...@@ -24,11 +24,11 @@ TESTASS(ofqc, fp, nrfp);
TESTINI(ofqd, fp, nrfp); TESTINI(ofqd, fp, nrfp);
TESTRET(ofqe, fp, nrfp); TESTRET(ofqe, fp, nrfp);
TESTARG(qa, char *, const char *); /* { dg-warning "passing argument 1 of 'qaF' discards qualifiers from pointer target type" } */ TESTARG(qa, char *, const char *); /* { dg-warning "passing argument 1 of 'qaF' discards 'const' qualifier from pointer target type" } */
TESTARP(qb, char *, const char *); /* { dg-warning "passing argument 1 of 'qbFp.x' discards qualifiers from pointer target type" } */ TESTARP(qb, char *, const char *); /* { dg-warning "passing argument 1 of 'qbFp.x' discards 'const' qualifier from pointer target type" } */
TESTASS(qc, char *, const char *); /* { dg-warning "assignment discards qualifiers from pointer target type" } */ TESTASS(qc, char *, const char *); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */
TESTINI(qd, char *, const char *); /* { dg-warning "initialization discards qualifiers from pointer target type" } */ TESTINI(qd, char *, const char *); /* { dg-warning "initialization discards 'const' qualifier from pointer target type" } */
TESTRET(qe, char *, const char *); /* { dg-warning "return discards qualifiers from pointer target type" } */ TESTRET(qe, char *, const char *); /* { dg-warning "return discards 'const' qualifier from pointer target type" } */
TESTARG(oqa, const char *, char *); TESTARG(oqa, const char *, char *);
TESTARP(oqb, const char *, char *); TESTARP(oqb, const char *, char *);
......
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
typedef void (*fp)(void); typedef void (*fp)(void);
typedef void (*nrfp)(void) __attribute__((noreturn)); typedef void (*nrfp)(void) __attribute__((noreturn));
TESTARG(fqa, nrfp, fp); /* { dg-error "passing argument 1 of 'fqaF' makes qualified function pointer from unqualified" } */ TESTARG(fqa, nrfp, fp); /* { dg-error "passing argument 1 of 'fqaF' makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTARP(fqb, nrfp, fp); /* { dg-error "passing argument 1 of 'fqbFp.x' makes qualified function pointer from unqualified" } */ TESTARP(fqb, nrfp, fp); /* { dg-error "passing argument 1 of 'fqbFp.x' makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTASS(fqc, nrfp, fp); /* { dg-error "assignment makes qualified function pointer from unqualified" } */ TESTASS(fqc, nrfp, fp); /* { dg-error "assignment makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTINI(fqd, nrfp, fp); /* { dg-error "initialization makes qualified function pointer from unqualified" } */ TESTINI(fqd, nrfp, fp); /* { dg-error "initialization makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTRET(fqe, nrfp, fp); /* { dg-error "return makes qualified function pointer from unqualified" } */ TESTRET(fqe, nrfp, fp); /* { dg-error "return makes '__attribute__..noreturn..' qualified function pointer from unqualified" } */
TESTARG(ofqa, fp, nrfp); TESTARG(ofqa, fp, nrfp);
TESTARP(ofqb, fp, nrfp); TESTARP(ofqb, fp, nrfp);
...@@ -25,11 +25,11 @@ TESTASS(ofqc, fp, nrfp); ...@@ -25,11 +25,11 @@ TESTASS(ofqc, fp, nrfp);
TESTINI(ofqd, fp, nrfp); TESTINI(ofqd, fp, nrfp);
TESTRET(ofqe, fp, nrfp); TESTRET(ofqe, fp, nrfp);
TESTARG(qa, char *, const char *); /* { dg-error "passing argument 1 of 'qaF' discards qualifiers from pointer target type" } */ TESTARG(qa, char *, const char *); /* { dg-error "passing argument 1 of 'qaF' discards 'const' qualifier from pointer target type" } */
TESTARP(qb, char *, const char *); /* { dg-error "passing argument 1 of 'qbFp.x' discards qualifiers from pointer target type" } */ TESTARP(qb, char *, const char *); /* { dg-error "passing argument 1 of 'qbFp.x' discards 'const' qualifier from pointer target type" } */
TESTASS(qc, char *, const char *); /* { dg-error "assignment discards qualifiers from pointer target type" } */ TESTASS(qc, char *, const char *); /* { dg-error "assignment discards 'const' qualifier from pointer target type" } */
TESTINI(qd, char *, const char *); /* { dg-error "initialization discards qualifiers from pointer target type" } */ TESTINI(qd, char *, const char *); /* { dg-error "initialization discards 'const' qualifier from pointer target type" } */
TESTRET(qe, char *, const char *); /* { dg-error "return discards qualifiers from pointer target type" } */ TESTRET(qe, char *, const char *); /* { dg-error "return discards 'const' qualifier from pointer target type" } */
TESTARG(oqa, const char *, char *); TESTARG(oqa, const char *, char *);
TESTARP(oqb, const char *, char *); TESTARP(oqb, const char *, char *);
......
...@@ -12,15 +12,15 @@ f (void) ...@@ -12,15 +12,15 @@ f (void)
const struct { const struct {
int a[1]; int a[1];
} s; } s;
int *p1 = s.a; /* { dg-error "qualifiers" } */ int *p1 = s.a; /* { dg-error "qualifier" } */
int *p2 = (a ? s : s).a; int *p2 = (a ? s : s).a;
/* In this case, the qualifier is properly on the array element type /* In this case, the qualifier is properly on the array element type
not on the rvalue structure and so is not discarded. */ not on the rvalue structure and so is not discarded. */
struct { struct {
const int a[1]; const int a[1];
} t; } t;
int *p3 = t.a; /* { dg-error "qualifiers" } */ int *p3 = t.a; /* { dg-error "qualifier" } */
int *p4 = (a ? t : t).a; /* { dg-error "qualifiers" } */ int *p4 = (a ? t : t).a; /* { dg-error "qualifier" } */
/* The issue could also lead to code being wrongly accepted. */ /* The issue could also lead to code being wrongly accepted. */
const struct { const struct {
int a[1][1]; int a[1][1];
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
void void
f0 (int a[restrict]) f0 (int a[restrict])
{ {
int **b = &a; /* { dg-error "discards qualifiers" } */ int **b = &a; /* { dg-error "discards 'restrict' qualifier" } */
int *restrict *c = &a; int *restrict *c = &a;
} }
...@@ -15,6 +15,6 @@ void ...@@ -15,6 +15,6 @@ void
f1 (a) f1 (a)
int a[restrict]; int a[restrict];
{ {
int **b = &a; /* { dg-error "discards qualifiers" } */ int **b = &a; /* { dg-error "discards 'restrict' qualifier" } */
int *restrict *c = &a; int *restrict *c = &a;
} }
...@@ -18,8 +18,8 @@ intfn_t *i2 = (intfn_t *) intfn; ...@@ -18,8 +18,8 @@ intfn_t *i2 = (intfn_t *) intfn;
intfn_t *i3 = constfn; intfn_t *i3 = constfn;
intfn_t *i4 = (intfn_t *) constfn; /* { dg-bogus "discards qualifier" } */ intfn_t *i4 = (intfn_t *) constfn; /* { dg-bogus "discards qualifier" } */
constfn_t p1 = intfn; /* { dg-warning "makes qualified function" } */ constfn_t p1 = intfn; /* { dg-warning "makes '__attribute__..const..' qualified function" } */
constfn_t p2 = (constfn_t) intfn; /* { dg-warning "new qualifier" } */ constfn_t p2 = (constfn_t) intfn; /* { dg-warning "adds '__attribute__..const..' qualifier" } */
constfn_t p3 = constfn; constfn_t p3 = constfn;
constfn_t p4 = (constfn_t) constfn; constfn_t p4 = (constfn_t) constfn;
...@@ -28,7 +28,7 @@ voidfn_t *v2 = (voidfn_t *) voidfn; ...@@ -28,7 +28,7 @@ voidfn_t *v2 = (voidfn_t *) voidfn;
voidfn_t *v3 = noreturnfn; voidfn_t *v3 = noreturnfn;
voidfn_t *v4 = (voidfn_t *) noreturnfn; /* { dg-bogus "discards qualifier" } */ voidfn_t *v4 = (voidfn_t *) noreturnfn; /* { dg-bogus "discards qualifier" } */
noreturnfn_t n1 = voidfn; /* { dg-warning "makes qualified function" } */ noreturnfn_t n1 = voidfn; /* { dg-warning "makes '__attribute__..noreturn..' qualified function" } */
noreturnfn_t n2 = (noreturnfn_t) voidfn; /* { dg-warning "new qualifier" } */ noreturnfn_t n2 = (noreturnfn_t) voidfn; /* { dg-warning "adds '__attribute__..noreturn..' qualifier" } */
noreturnfn_t n3 = noreturnfn; noreturnfn_t n3 = noreturnfn;
noreturnfn_t n4 = (noreturnfn_t) noreturnfn; noreturnfn_t n4 = (noreturnfn_t) noreturnfn;
...@@ -13,14 +13,14 @@ main(void) ...@@ -13,14 +13,14 @@ main(void)
{ {
char *A; char *A;
A = "text"; /* { dg-warning "discards qualifiers" "case zero" } */ A = "text"; /* { dg-warning "discards 'const' qualifier" "case zero" } */
A = one("text" /* { dg-warning "discards qualifiers" "case one" } */ A = one("text" /* { dg-warning "discards 'const' qualifier" "case one" } */
"text") "text")
; ;
A = two("text" /* { dg-warning "discards qualifiers" "case two" } */ A = two("text" /* { dg-warning "discards 'const' qualifier" "case two" } */
"text") "text")
; ;
A = four("text" /* { dg-warning "discards qualifiers" "case four" } */ A = four("text" /* { dg-warning "discards 'const' qualifier" "case four" } */
"text") "text")
; ;
......
...@@ -70,13 +70,13 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -70,13 +70,13 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
cdiag ("%m"); cdiag ("%m");
cxxdiag ("%m"); cxxdiag ("%m");
tdiag ("%D%F%T", t1, t1, t1); tdiag ("%D%F%T%V", t1, t1, t1, t1);
tdiag ("%+D%+F%+T", t1, t1, t1); tdiag ("%+D%+F%+T%+V", t1, t1, t1, t1);
tdiag ("%q+D%q+F%q+T", t1, t1, t1); tdiag ("%q+D%q+F%q+T%q+V", t1, t1, t1, t1);
tdiag ("%D%D%D%D", t1, t2, *t3, t4[5]); tdiag ("%D%D%D%D", t1, t2, *t3, t4[5]);
cdiag ("%D%F%T", t1, t1, t1); cdiag ("%D%F%T%V", t1, t1, t1, t1);
cdiag ("%+D%+F%+T", t1, t1, t1); cdiag ("%+D%+F%+T%+V", t1, t1, t1, t1);
cdiag ("%q+D%q+F%q+T", t1, t1, t1); cdiag ("%q+D%q+F%q+T%q+V", t1, t1, t1, t1);
cdiag ("%D%D%D%D", t1, t2, *t3, t4[5]); cdiag ("%D%D%D%D", t1, t2, *t3, t4[5]);
cdiag ("%E", t1); cdiag ("%E", t1);
cxxdiag ("%A%D%E%F%T%V", t1, t1, t1, t1, t1, t1); cxxdiag ("%A%D%E%F%T%V", t1, t1, t1, t1, t1, t1);
...@@ -86,6 +86,10 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -86,6 +86,10 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
cxxdiag ("%+#A%+#D%+#E%+#F%+#T%+#V", t1, t1, t1, t1, t1, t1); cxxdiag ("%+#A%+#D%+#E%+#F%+#T%+#V", t1, t1, t1, t1, t1, t1);
cxxdiag ("%C%L%O%P%Q", i, i, i, i, i); cxxdiag ("%C%L%O%P%Q", i, i, i, i, i);
tdiag ("%v%qv%#v", i, i, i);
cdiag ("%v%qv%#v", i, i, i);
cxxdiag ("%v%qv%#v", i, i, i);
/* Bad stuff with extensions. */ /* Bad stuff with extensions. */
diag ("%m", i); /* { dg-warning "format" "extra arg" } */ diag ("%m", i); /* { dg-warning "format" "extra arg" } */
tdiag ("%m", i); /* { dg-warning "format" "extra arg" } */ tdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
...@@ -121,6 +125,14 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -121,6 +125,14 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
cdiag ("%D", t1, t1); /* { dg-warning "format" "extra arg" } */ cdiag ("%D", t1, t1); /* { dg-warning "format" "extra arg" } */
cxxdiag ("%D", t1, t1); /* { dg-warning "format" "extra arg" } */ cxxdiag ("%D", t1, t1); /* { dg-warning "format" "extra arg" } */
tdiag ("%V", i); /* { dg-warning "format" "wrong arg" } */
cdiag ("%V", i); /* { dg-warning "format" "wrong arg" } */
cxxdiag ("%V", i); /* { dg-warning "format" "wrong arg" } */
tdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
cdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
cxxdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
/* Standard specifiers not accepted in the diagnostic framework. */ /* Standard specifiers not accepted in the diagnostic framework. */
diag ("%X\n", u); /* { dg-warning "format" "HEX" } */ diag ("%X\n", u); /* { dg-warning "format" "HEX" } */
diag ("%f\n", d); /* { dg-warning "format" "float" } */ diag ("%f\n", d); /* { dg-warning "format" "float" } */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment