PR c/25880 improve message of warning for discarding qualifiers
Manuel López-Ibáñez
lopezibanez@gmail.com
Fri Jun 4 15:17:00 GMT 2010
This is what I committed as revision 160274.
Cheers,
Manuel.
On 24 May 2010 13:47, Joseph S. Myers <joseph@codesourcery.com> wrote:
> On Mon, 24 May 2010, Manuel López-Ibáñez wrote:
>
>> I sometimes forget that humans cannot read minds. Now with patch.
>>
>> Manuel.
>>
>> On 24 May 2010 11:38, Manuel López-Ibáñez <lopezibanez@gmail.com> wrote:
>> > Before updating testcases, I would like to know if the current patch is ok.
>> >
>> > Bootstrapped and regression tested on x86_64-linux-gnu. Failing
>> > testcases are due to the change of wording.
>
> I think you should print "const" as an attribute for functions, like
> volatile; otherwise the changes look OK. Note that you should update the
> tests of GCC format checking (gcc.dg/format/gcc_diag-1.c) to test the new
> formats, as well as updating tests that fail.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
-------------- next part --------------
Index: gcc/testsuite/gcc.dg/assign-warn-2.c
===================================================================
--- gcc/testsuite/gcc.dg/assign-warn-2.c (revision 160273)
+++ gcc/testsuite/gcc.dg/assign-warn-2.c (working copy)
@@ -11,27 +11,27 @@
#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 "passing argument 1 of 'fqaF' makes qualified function pointer from unqualified" } */
-TESTARP(fqb, nrfp, fp); /* { dg-error "passing argument 1 of 'fqbFp.x' makes qualified function pointer from unqualified" } */
-TESTASS(fqc, nrfp, fp); /* { dg-error "assignment makes qualified function pointer from unqualified" } */
-TESTINI(fqd, nrfp, fp); /* { dg-error "initialization makes qualified function pointer from unqualified" } */
-TESTRET(fqe, nrfp, fp); /* { dg-error "return 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 '__attribute__..noreturn..' 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 '__attribute__..noreturn..' qualified function pointer from unqualified" } */
+TESTRET(fqe, nrfp, fp); /* { dg-error "return makes '__attribute__..noreturn..' 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 "passing argument 1 of 'qaF' discards qualifiers from pointer target type" } */
-TESTARP(qb, char *, const char *); /* { dg-error "passing argument 1 of 'qbFp.x' discards qualifiers from pointer target type" } */
-TESTASS(qc, char *, const char *); /* { dg-error "assignment discards qualifiers from pointer target type" } */
-TESTINI(qd, char *, const char *); /* { dg-error "initialization discards qualifiers from pointer target type" } */
-TESTRET(qe, char *, const char *); /* { dg-error "return 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 'const' qualifier 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 'const' qualifier from pointer target type" } */
+TESTRET(qe, char *, const char *); /* { dg-error "return discards 'const' qualifier from pointer target type" } */
TESTARG(oqa, const char *, char *);
TESTARP(oqb, const char *, char *);
TESTASS(oqc, const char *, char *);
TESTINI(oqd, const char *, char *);
Index: gcc/testsuite/gcc.dg/cpp/line3.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/line3.c (revision 160273)
+++ gcc/testsuite/gcc.dg/cpp/line3.c (working copy)
@@ -11,18 +11,18 @@
int
main(void)
{
char *A;
- A = "text"; /* { dg-warning "discards qualifiers" "case zero" } */
- A = one("text" /* { dg-warning "discards qualifiers" "case one" } */
+ A = "text"; /* { dg-warning "discards 'const' qualifier" "case zero" } */
+ A = one("text" /* { dg-warning "discards 'const' qualifier" "case one" } */
"text")
;
- A = two("text" /* { dg-warning "discards qualifiers" "case two" } */
+ A = two("text" /* { dg-warning "discards 'const' qualifier" "case two" } */
"text")
;
- A = four("text" /* { dg-warning "discards qualifiers" "case four" } */
+ A = four("text" /* { dg-warning "discards 'const' qualifier" "case four" } */
"text")
;
return 0;
}
Index: gcc/testsuite/gcc.dg/c99-array-lval-8.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-array-lval-8.c (revision 160273)
+++ gcc/testsuite/gcc.dg/c99-array-lval-8.c (working copy)
@@ -10,19 +10,19 @@ void
f (void)
{
const struct {
int a[1];
} s;
- int *p1 = s.a; /* { dg-error "qualifiers" } */
+ int *p1 = s.a; /* { dg-error "qualifier" } */
int *p2 = (a ? s : s).a;
/* In this case, the qualifier is properly on the array element type
not on the rvalue structure and so is not discarded. */
struct {
const int a[1];
} t;
- int *p3 = t.a; /* { dg-error "qualifiers" } */
- int *p4 = (a ? t : t).a; /* { dg-error "qualifiers" } */
+ int *p3 = t.a; /* { dg-error "qualifier" } */
+ int *p4 = (a ? t : t).a; /* { dg-error "qualifier" } */
/* The issue could also lead to code being wrongly accepted. */
const struct {
int a[1][1];
} u;
const int (*p5)[1] = u.a;
Index: gcc/testsuite/gcc.dg/cast-qual-2.c
===================================================================
--- gcc/testsuite/gcc.dg/cast-qual-2.c (revision 160273)
+++ gcc/testsuite/gcc.dg/cast-qual-2.c (working copy)
@@ -16,19 +16,19 @@ volatile voidfn_t noreturnfn;
intfn_t *i1 = intfn;
intfn_t *i2 = (intfn_t *) intfn;
intfn_t *i3 = constfn;
intfn_t *i4 = (intfn_t *) constfn; /* { dg-bogus "discards qualifier" } */
-constfn_t p1 = intfn; /* { dg-warning "makes qualified function" } */
-constfn_t p2 = (constfn_t) intfn; /* { dg-warning "new qualifier" } */
+constfn_t p1 = intfn; /* { dg-warning "makes '__attribute__..const..' qualified function" } */
+constfn_t p2 = (constfn_t) intfn; /* { dg-warning "adds '__attribute__..const..' qualifier" } */
constfn_t p3 = constfn;
constfn_t p4 = (constfn_t) constfn;
voidfn_t *v1 = voidfn;
voidfn_t *v2 = (voidfn_t *) voidfn;
voidfn_t *v3 = noreturnfn;
voidfn_t *v4 = (voidfn_t *) noreturnfn; /* { dg-bogus "discards qualifier" } */
-noreturnfn_t n1 = voidfn; /* { dg-warning "makes qualified function" } */
-noreturnfn_t n2 = (noreturnfn_t) voidfn; /* { dg-warning "new qualifier" } */
+noreturnfn_t n1 = voidfn; /* { dg-warning "makes '__attribute__..noreturn..' qualified function" } */
+noreturnfn_t n2 = (noreturnfn_t) voidfn; /* { dg-warning "adds '__attribute__..noreturn..' qualifier" } */
noreturnfn_t n3 = noreturnfn;
noreturnfn_t n4 = (noreturnfn_t) noreturnfn;
Index: gcc/testsuite/gcc.dg/c99-arraydecl-3.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-arraydecl-3.c (revision 160273)
+++ gcc/testsuite/gcc.dg/c99-arraydecl-3.c (working copy)
@@ -5,16 +5,16 @@
/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
void
f0 (int a[restrict])
{
- int **b = &a; /* { dg-error "discards qualifiers" } */
+ int **b = &a; /* { dg-error "discards 'restrict' qualifier" } */
int *restrict *c = &a;
}
void
f1 (a)
int a[restrict];
{
- int **b = &a; /* { dg-error "discards qualifiers" } */
+ int **b = &a; /* { dg-error "discards 'restrict' qualifier" } */
int *restrict *c = &a;
}
Index: gcc/testsuite/gcc.dg/assign-warn-1.c
===================================================================
--- gcc/testsuite/gcc.dg/assign-warn-1.c (revision 160273)
+++ gcc/testsuite/gcc.dg/assign-warn-1.c (working copy)
@@ -10,27 +10,27 @@
#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 "passing argument 1 of 'fqaF' makes qualified function pointer from unqualified" } */
-TESTARP(fqb, nrfp, fp); /* { dg-warning "passing argument 1 of 'fqbFp.x' makes qualified function pointer from unqualified" } */
-TESTASS(fqc, nrfp, fp); /* { dg-warning "assignment makes qualified function pointer from unqualified" } */
-TESTINI(fqd, nrfp, fp); /* { dg-warning "initialization makes qualified function pointer from unqualified" } */
-TESTRET(fqe, nrfp, fp); /* { dg-warning "return 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 '__attribute__..noreturn..' 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 '__attribute__..noreturn..' qualified function pointer from unqualified" } */
+TESTRET(fqe, nrfp, fp); /* { dg-warning "return makes '__attribute__..noreturn..' 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 "passing argument 1 of 'qaF' discards qualifiers from pointer target type" } */
-TESTARP(qb, char *, const char *); /* { dg-warning "passing argument 1 of 'qbFp.x' discards qualifiers from pointer target type" } */
-TESTASS(qc, char *, const char *); /* { dg-warning "assignment discards qualifiers from pointer target type" } */
-TESTINI(qd, char *, const char *); /* { dg-warning "initialization discards qualifiers from pointer target type" } */
-TESTRET(qe, char *, const char *); /* { dg-warning "return 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 'const' qualifier 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 'const' qualifier from pointer target type" } */
+TESTRET(qe, char *, const char *); /* { dg-warning "return discards 'const' qualifier from pointer target type" } */
TESTARG(oqa, const char *, char *);
TESTARP(oqb, const char *, char *);
TESTASS(oqc, const char *, char *);
TESTINI(oqd, const char *, char *);
Index: gcc/testsuite/gcc.dg/format/gcc_diag-1.c
===================================================================
--- gcc/testsuite/gcc.dg/format/gcc_diag-1.c (revision 160273)
+++ gcc/testsuite/gcc.dg/format/gcc_diag-1.c (working copy)
@@ -68,26 +68,30 @@ foo (int i, int i1, int i2, unsigned int
diag ("%m");
tdiag ("%m");
cdiag ("%m");
cxxdiag ("%m");
- tdiag ("%D%F%T", t1, t1, t1);
- tdiag ("%+D%+F%+T", t1, t1, t1);
- tdiag ("%q+D%q+F%q+T", t1, t1, t1);
+ tdiag ("%D%F%T%V", t1, t1, t1, t1);
+ tdiag ("%+D%+F%+T%+V", t1, 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]);
- cdiag ("%D%F%T", t1, t1, t1);
- cdiag ("%+D%+F%+T", t1, t1, t1);
- cdiag ("%q+D%q+F%q+T", t1, t1, t1);
+ cdiag ("%D%F%T%V", t1, t1, t1, t1);
+ cdiag ("%+D%+F%+T%+V", t1, 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 ("%E", t1);
cxxdiag ("%A%D%E%F%T%V", t1, t1, t1, t1, t1, t1);
cxxdiag ("%D%D%D%D", t1, t2, *t3, t4[5]);
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 ("%+#A%+#D%+#E%+#F%+#T%+#V", t1, t1, t1, t1, t1, t1);
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. */
diag ("%m", i); /* { dg-warning "format" "extra arg" } */
tdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
cdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
cxxdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
@@ -119,10 +123,18 @@ foo (int i, int i1, int i2, unsigned int
cxxdiag ("%D", i); /* { dg-warning "format" "wrong arg" } */
tdiag ("%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" } */
+ 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. */
diag ("%X\n", u); /* { dg-warning "format" "HEX" } */
diag ("%f\n", d); /* { dg-warning "format" "float" } */
diag ("%e\n", d); /* { dg-warning "format" "float" } */
diag ("%E\n", d); /* { dg-warning "format" "float" } */
Index: gcc/c-objc-common.c
===================================================================
--- gcc/c-objc-common.c (revision 160273)
+++ gcc/c-objc-common.c (working copy)
@@ -77,13 +77,14 @@ c_objc_common_init (void)
is as follows:
%D: a general decl,
%E: an identifier or expression,
%F: a function declaration,
%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
diagnostic machinery. */
static bool
c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
int precision, bool wide, bool set_locus, bool hash)
@@ -91,23 +92,25 @@ c_tree_printer (pretty_printer *pp, text
tree t;
tree name;
c_pretty_printer *cpp = (c_pretty_printer *) pp;
pp->padding = pp_none;
- if (precision != 0 || wide || hash)
+ if (precision != 0 || wide)
return false;
if (*spec == 'K')
{
percent_K_format (text);
return true;
}
- t = va_arg (*text->args_ptr, tree);
-
- if (set_locus && text->locus)
- *text->locus = DECL_SOURCE_LOCATION (t);
+ if (*spec != 'v')
+ {
+ t = va_arg (*text->args_ptr, tree);
+ if (set_locus && text->locus)
+ *text->locus = DECL_SOURCE_LOCATION (t);
+ }
switch (*spec)
{
case 'D':
if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
@@ -153,10 +156,18 @@ c_tree_printer (pretty_printer *pp, text
pp_identifier (cpp, IDENTIFIER_POINTER (t));
else
pp_expression (cpp, t);
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:
return false;
}
pp_string (cpp, _("({anonymous})"));
Index: gcc/c-format.c
===================================================================
--- gcc/c-format.c (revision 160273)
+++ gcc/c-format.c (working copy)
@@ -419,28 +419,20 @@ static const format_flag_pair gcc_gfc_fl
};
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 },
{ '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 }
};
#define gcc_tdiag_flag_specs gcc_diag_flag_specs
#define gcc_cdiag_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 }
-};
+#define gcc_cxxdiag_flag_specs gcc_diag_flag_specs
static const format_flag_spec scanf_flag_specs[] =
{
{ '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
{ 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
@@ -583,11 +575,13 @@ static const format_char_info gcc_tdiag_
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
/* Custom conversion specifiers. */
/* 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 },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
{ NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
@@ -603,11 +597,13 @@ static const format_char_info gcc_cdiag_
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
/* Custom conversion specifiers. */
/* 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 },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
{ NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
@@ -625,10 +621,12 @@ static const format_char_info gcc_cxxdia
/* Custom conversion specifiers. */
/* 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 },
+ { "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'.) */
{ "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
{ "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
@@ -720,23 +718,23 @@ static const format_kind_info format_typ
asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
'w', 0, 'p', 0, 'L', 0,
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,
FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0,
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,
FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0,
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,
FMT_FLAG_ARG_CONVERT,
0, 0, 'p', 0, 'L', 0,
NULL, &integer_type_node
},
Index: gcc/c-pretty-print.c
===================================================================
--- gcc/c-pretty-print.c (revision 160273)
+++ gcc/c-pretty-print.c (working copy)
@@ -168,22 +168,47 @@ pp_c_exclamation (c_pretty_printer *pp)
{
pp_exclamation (pp);
pp_base (pp)->padding = pp_none;
}
-/* Print out the external representation of CV-QUALIFIER. */
+/* Print out the external representation of QUALIFIERS. */
-static void
-pp_c_cv_qualifier (c_pretty_printer *pp, const char *cv)
+void
+pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type)
{
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
simpler to handle those here rather than going through the same
logic in the C++ pretty-printer. */
if (p != NULL && (*p == '*' || *p == '&'))
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 )'. */
static void
@@ -240,16 +265,12 @@ pp_c_type_qualifier_list (c_pretty_print
if (!TYPE_P (t))
t = TREE_TYPE (t);
qualifiers = TYPE_QUALS (t);
- if (qualifiers & TYPE_QUAL_CONST)
- pp_c_cv_qualifier (pp, "const");
- 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__");
+ pp_c_cv_qualifiers (pp, qualifiers,
+ TREE_CODE (t) == FUNCTION_TYPE);
if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t)))
{
const char *as = c_addr_space_name (TYPE_ADDR_SPACE (t));
pp_c_identifier (pp, as);
Index: gcc/c-pretty-print.h
===================================================================
--- gcc/c-pretty-print.h (revision 160273)
+++ gcc/c-pretty-print.h (working copy)
@@ -174,10 +174,11 @@ void pp_c_space_for_pointer_operator (c_
/* Declarations. */
void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
void pp_c_function_definition (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_parameter_type_list (c_pretty_printer *, tree);
void pp_c_declaration (c_pretty_printer *, tree);
void pp_c_declaration_specifiers (c_pretty_printer *, tree);
void pp_c_declarator (c_pretty_printer *, tree);
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c (revision 160273)
+++ gcc/c-typeck.c (working copy)
@@ -4438,17 +4438,19 @@ handle_warn_cast_qual (tree type, tree o
}
while (TREE_CODE (in_type) == POINTER_TYPE
&& TREE_CODE (in_otype) == POINTER_TYPE);
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)
/* There are qualifiers present in IN_OTYPE that are not present
in IN_TYPE. */
warning (OPT_Wcast_qual,
- "cast discards qualifiers from pointer target type");
+ "cast discards %q#v qualifier from pointer target type",
+ discarded);
if (added || discarded)
return;
/* A cast from **T to const **T is unsafe, because it can cause a
@@ -4477,13 +4479,14 @@ handle_warn_cast_qual (tree type, tree o
in_type = TREE_TYPE (in_type);
in_otype = TREE_TYPE (in_otype);
if ((TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype)) != 0
&& !is_const)
{
+ int added = TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype);
warning (OPT_Wcast_qual,
- ("new qualifiers in middle of multi-level non-const cast "
- "are unsafe"));
+ ("new %qv qualifier in middle of multi-level non-const cast "
+ "is unsafe"), added);
break;
}
if (is_const)
is_const = TYPE_READONLY (in_type);
}
@@ -5005,10 +5008,40 @@ convert_for_assignment (location_t locat
default: \
gcc_unreachable (); \
} \
} 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)
rhs = TREE_OPERAND (rhs, 0);
rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype);
@@ -5212,34 +5245,36 @@ convert_for_assignment (location_t locat
certain things, it is okay to use a const or volatile
function where an ordinary one is wanted, but not
vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
- WARN_FOR_ASSIGNMENT (location, 0,
+ WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE "
- "makes qualified function "
+ "makes %q#v qualified function "
"pointer from unqualified"),
- G_("assignment makes qualified "
+ G_("assignment makes %q#v qualified "
"function pointer from "
"unqualified"),
- G_("initialization makes qualified "
+ G_("initialization makes %q#v qualified "
"function pointer from "
"unqualified"),
- G_("return makes qualified function "
- "pointer from unqualified"));
+ G_("return makes %q#v qualified function "
+ "pointer from unqualified"),
+ TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr));
}
else if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
- WARN_FOR_ASSIGNMENT (location, 0,
+ WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE discards "
- "qualifiers from pointer target type"),
- G_("assignment discards qualifiers "
+ "%qv qualifier from pointer target type"),
+ G_("assignment discards %qv qualifier "
"from pointer target type"),
- G_("initialization discards qualifiers "
+ G_("initialization discards %qv qualifier "
"from pointer target type"),
- G_("return discards qualifiers from "
- "pointer target type"));
+ G_("return discards %qv qualifier from "
+ "pointer target type"),
+ TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
memb = marginal_memb;
}
if (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl))
@@ -5381,19 +5416,20 @@ convert_for_assignment (location_t locat
{
/* Types differing only by the presence of the 'volatile'
qualifier are acceptable if the 'volatile' has been added
in by the Objective-C EH machinery. */
if (!objc_type_quals_match (ttl, ttr))
- WARN_FOR_ASSIGNMENT (location, 0,
+ WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE discards "
- "qualifiers from pointer target type"),
- G_("assignment discards qualifiers "
+ "%qv qualifier from pointer target type"),
+ G_("assignment discards %qv qualifier "
"from pointer target type"),
- G_("initialization discards qualifiers "
+ G_("initialization discards %qv qualifier "
"from pointer target type"),
- G_("return discards qualifiers from "
- "pointer target type"));
+ G_("return discards %qv qualifier from "
+ "pointer target type"),
+ TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
}
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */
else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
|| target_cmp)
@@ -5417,20 +5453,21 @@ convert_for_assignment (location_t locat
that say the function will not do certain things,
it is okay to use a const or volatile function
where an ordinary one is wanted, but not vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
- WARN_FOR_ASSIGNMENT (location, 0,
+ WARN_FOR_QUALIFIERS (location, 0,
G_("passing argument %d of %qE makes "
- "qualified function pointer "
+ "%q#v qualified function pointer "
"from unqualified"),
- G_("assignment makes qualified function "
+ G_("assignment makes %q#v qualified function "
"pointer from unqualified"),
- G_("initialization makes qualified "
+ G_("initialization makes %q#v qualified "
"function pointer from unqualified"),
- G_("return makes qualified function "
- "pointer from unqualified"));
+ G_("return makes %q#v qualified function "
+ "pointer from unqualified"),
+ TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr));
}
}
else
/* Avoid warning about the volatile ObjC EH puts on decls. */
if (!objc_ok)
More information about the Gcc-patches
mailing list