/* Initialized in init_dynamic_diag_info. */
static GTY(()) tree local_tree_type_node;
+static GTY(()) tree local_gcall_ptr_node;
static GTY(()) tree locus;
static bool decode_format_attr (tree, function_format_info *, int);
/* Custom conversion specifiers. */
- /* These will require a "tree" at runtime. */
+ /* G requires a "gcall*" argument at runtime. */
+ { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
+ /* K requires a "tree" argument at runtime. */
{ "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
{ "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "//cR", NULL },
{ "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
{ "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
+ /* G requires a "gcall*" argument at runtime. */
+ { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
+
{ "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
{ "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "/cR", NULL },
{ "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
{ "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
+ /* G requires a "gcall*" argument at runtime. */
+ { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
+
{ "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
{ "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "/cR", NULL },
{ "K", 1, STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
{ "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
+ /* G requires a "gcall*" argument at runtime. */
+ { "G", 1, STD_C89,{ T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", 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 },
local_tree_type_node = void_type_node;
}
+ /* Similar to the above but for gcall*. */
+ if (!local_gcall_ptr_node
+ || local_gcall_ptr_node == void_type_node)
+ {
+ if ((local_gcall_ptr_node = maybe_get_identifier ("gcall")))
+ {
+ local_gcall_ptr_node
+ = identifier_global_value (local_gcall_ptr_node);
+ if (local_gcall_ptr_node)
+ {
+ if (TREE_CODE (local_gcall_ptr_node) != TYPE_DECL)
+ {
+ error ("%<gcall%> is not defined as a type");
+ local_gcall_ptr_node = 0;
+ }
+ else
+ local_gcall_ptr_node = TREE_TYPE (local_gcall_ptr_node);
+ }
+ }
+ else
+ local_gcall_ptr_node = void_type_node;
+ }
+
static tree hwi;
if (!hwi)
union tree_node;
typedef union tree_node *tree;
+/* Define gcall as a dummy type. The typedef must be provided for
+ the C test to find the symbol. */
+typedef struct gcall gcall;
#define FORMAT(kind) __attribute__ ((format (__gcc_## kind ##__, 1, 2)))
void tdiag (const char*, ...) FORMAT (tdiag);
void cxxdiag (const char*, ...) FORMAT (cxxdiag);
-void test_diag (tree t)
+void test_diag (tree t, gcall *gc)
{
diag ("%<"); /* { dg-warning "unterminated quoting directive" } */
diag ("%>"); /* { dg-warning "unmatched quoting directive " } */
diag ("%<foo%<bar%>%>"); /* { dg-warning "nested quoting directive" } */
+ diag ("%G", gc);
diag ("%K", t);
diag ("%R"); /* { dg-warning "unmatched color reset directive" } */
diag ("%r%r%R", "", "");
diag ("%r%R%r%R", "", "");
+ diag ("%<%G%>", gc); /* { dg-warning ".G. conversion used within a quoted sequence" } */
diag ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
diag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
diag ("%<%r%R%>", "");
}
-void test_cdiag (tree t)
+void test_cdiag (tree t, gcall *gc)
{
cdiag ("%<"); /* { dg-warning "unterminated quoting directive" } */
cdiag ("%>"); /* { dg-warning "unmatched quoting directive " } */
cdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
cdiag ("%E", t);
cdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */
+ cdiag ("%G", gc);
cdiag ("%K", t);
cdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
cdiag ("%<%D%>", t);
cdiag ("%<%E%>", t);
cdiag ("%<%F%>", t);
+ cdiag ("%<%G%>", gc); /* { dg-warning ".G. conversion used within a quoted sequence" } */
cdiag ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
cdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
cdiag ("%<%qT%>", t); /* { dg-warning ".q. flag used within a quoted sequence" } */
}
-void test_tdiag (tree t)
+void test_tdiag (tree t, gcall *gc)
{
tdiag ("%<"); /* { dg-warning "unterminated quoting directive" } */
tdiag ("%>"); /* { dg-warning "unmatched quoting directive " } */
tdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
tdiag ("%E", t);
+ tdiag ("%G", gc);
tdiag ("%K", t);
tdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
tdiag ("%<%D%>", t);
tdiag ("%<%E%>", t);
+ tdiag ("%<%G%>", gc); /* { dg-warning ".G. conversion used within a quoted sequence" } */
tdiag ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
tdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
tdiag ("%<%qT%>", t); /* { dg-warning ".q. flag used within a quoted sequence" } */
}
-void test_cxxdiag (tree t)
+void test_cxxdiag (tree t, gcall *gc)
{
cxxdiag ("%A", t); /* { dg-warning ".A. conversion used unquoted" } */
cxxdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
cxxdiag ("%E", t);
cxxdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */
+ cxxdiag ("%G", gc);
+ cxxdiag ("%K", t);
cxxdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
cxxdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */