I have a release on file with the FSF, but don't have SVN write access.

Problem description:
asm_fprintf allows platforms to add support for new format specifiers by using the ASM_FPRINTF_EXTENSIONS macro. ARM uses this to add support for %@ and %r specifiers.

However, it isn't enough to add these two items to the case statement in asm_fprintf (which is what ASM_FPRINTF_EXTENSIONS does). Over in c-format.c, there is compile-time checking that is done against calls to asm_fprintf to validate the format string. %@ and %r have been added to this checking (see asm_fprintf_char_table), but NOT in a platform-specific way.

This means that using %r or %@ will successfully pass the format checking on all platforms, but will ICE if used on non-ARM platforms since without ASM_FPRINTF_EXTENSIONS, there are no case statements in asm_fprintf to support them.

ChangeLog:
2014-07-23  David Wohlferd <d...@limegreensocks.com>

        * doc/c-family/c-format.c: Add support for target macro
          ASM_FPRINTF_TABLE, remove arm-specific formats.
        * gcc/config/arm/arm.h: Use ASM_FPRINTF_TABLE for %@ and %r.
        * gcc/doc/tm.texi: Document new target macro.
        * gcc/doc/tm.texi.in: Ditto.
        * gcc/testsuite/gcc.dg/format/asm_fprintf-1.c: Make tests
          for %@ and %r arm-specific.

dw
Index: gcc/c-family/c-format.c
===================================================================
--- gcc/c-family/c-format.c	(revision 212900)
+++ gcc/c-family/c-format.c	(working copy)
@@ -637,8 +637,9 @@
   { "I",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "L",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "U",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
-  { "r",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  "", NULL },
-  { "@",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
+#ifdef ASM_FPRINTF_TABLE
+  ASM_FPRINTF_TABLE
+#endif
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
 
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	(revision 212900)
+++ gcc/config/arm/arm.h	(working copy)
@@ -888,6 +888,12 @@
     fputs (reg_names [va_arg (ARGS, int)], FILE);	\
     break;
 
+/* Used in c-format.c to add entries to the table used to validate calls 
+   to asm_fprintf. */
+#define ASM_FPRINTF_TABLE \
+  { "r",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  "", NULL }, \
+  { "@",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
+
 /* Round X up to the nearest word.  */
 #define ROUND_UP_WORD(X) (((X) + 3) & ~3)
 
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 212900)
+++ gcc/doc/tm.texi	(working copy)
@@ -8611,8 +8611,39 @@
 The varargs input pointer is @var{argptr} and the rest of the format
 string, starting the character after the one that is being switched
 upon, is pointed to by @var{format}.
+See also ASM_FPRINTF_TABLE.
+
+Example:
+@smallexample
+#define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P)		\
+  case '@':						\
+    fputs (ASM_COMMENT_START, FILE);			\
+    break;						\
+							\
+  case 'r':						\
+    fputs (REGISTER_PREFIX, FILE);			\
+    fputs (reg_names [va_arg (ARGS, int)], FILE);	\
+    break;
+@end smallexample
 @end defmac
 
+@defmac ASM_FPRINTF_TABLE
+When using ASM_FPRINTF_EXTENSIONS, you must also use this macro to define
+table entries for the printf format checking performed in c-format.c. 
+This macro must contain format_char_info entries for each printf format 
+being added.
+
+Example:
+@smallexample
+#define ASM_FPRINTF_TABLE \
+  @{ "r", 0, STD_C89, \
+     @{ T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, \
+      BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN @}, \
+  "", "", NULL @}, \
+  @{ "@",   0, STD_C89, NOARGUMENTS, "",      "",   NULL @},
+@end smallexample
+@end defmac
+
 @defmac ASSEMBLER_DIALECT
 If your target supports multiple dialects of assembler language (such as
 different opcodes), define this macro as a C expression that gives the
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 212900)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -6370,8 +6370,39 @@
 The varargs input pointer is @var{argptr} and the rest of the format
 string, starting the character after the one that is being switched
 upon, is pointed to by @var{format}.
+See also ASM_FPRINTF_TABLE.
+
+Example:
+@smallexample
+#define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P)		\
+  case '@':						\
+    fputs (ASM_COMMENT_START, FILE);			\
+    break;						\
+							\
+  case 'r':						\
+    fputs (REGISTER_PREFIX, FILE);			\
+    fputs (reg_names [va_arg (ARGS, int)], FILE);	\
+    break;
+@end smallexample
 @end defmac
 
+@defmac ASM_FPRINTF_TABLE
+When using ASM_FPRINTF_EXTENSIONS, you must also use this macro to define
+table entries for the printf format checking performed in c-format.c. 
+This macro must contain format_char_info entries for each printf format 
+being added.
+
+Example:
+@smallexample
+#define ASM_FPRINTF_TABLE \
+  @{ "r", 0, STD_C89, \
+     @{ T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, \
+      BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN @}, \
+  "", "", NULL @}, \
+  @{ "@",   0, STD_C89, NOARGUMENTS, "",      "",   NULL @},
+@end smallexample
+@end defmac
+
 @defmac ASSEMBLER_DIALECT
 If your target supports multiple dialects of assembler language (such as
 different opcodes), define this macro as a C expression that gives the
Index: gcc/testsuite/gcc.dg/format/asm_fprintf-1.c
===================================================================
--- gcc/testsuite/gcc.dg/format/asm_fprintf-1.c	(revision 212900)
+++ gcc/testsuite/gcc.dg/format/asm_fprintf-1.c	(working copy)
@@ -37,10 +37,14 @@
   asm_fprintf ("%d %lu\n", i, ul);
 
   /* Extensions provided in asm_fprintf.  */
-  asm_fprintf ("%O%R%I%L%U%@");
-  asm_fprintf ("%r", i);
+  asm_fprintf ("%O%R%I%L%U");
   asm_fprintf ("%wd%wi%wo%wu%wx%wX", ll, ll, ull, ull, ull, ull);
 
+  /* These 2 format specifiers are only available on arm. */
+#ifdef __arm__
+  asm_fprintf("%@%r", i);
+#endif
+
   /* Standard specifiers not accepted in asm_fprintf.  */
   asm_fprintf ("%f\n", d); /* { dg-warning "format" "float" } */
   asm_fprintf ("%e\n", d); /* { dg-warning "format" "float" } */

Reply via email to