https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77521

            Bug ID: 77521
           Summary: %qc format directive should quote non-printable
                    characters
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The GCC-specific %qc format directive prints its character argument in quotes. 
One might expect the directive to quote non-printable characters similarly to
the %s directive but that's not what happens.  %qc prints the character as is. 
As a result, callers of the warning_at and error APIs that use the %qc
directive must be careful not to call it with non-printable characters (for
instance, by using the ISGRAPH() macro as done in c-family/c-format.c) and use
a different directive for those.  Those that don't might end up corrupting the
compiler stderr output as in the test case below.  Those that are careful end
up using a different alternate directive (e.g., %x or %o) resulting in
inconsistent diagnostics.

This bug is to change the %qc directive in the GCC pretty printer to format
non-printable characters using some other directive than the C %c (for example,
"\x%x" as done in c-family/c-format.c).

$ cat t.c && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -S -Wformat t.c
void g (int foo, int bar)
{
  asm ("combine %2, %0" : "=r" (foo) : "0" (foo), "\n" (bar));
}
t.c: In function ‘g’:
t.c:3:3: error: invalid punctuation ‘
’ in constraint
   asm ("combine %2, %0" : "=r" (foo) : "0" (foo), "\n" (bar));
   ^~~
t.c:3:3: error: invalid punctuation ‘
’ in constraint


The following is a list of GCC formatted output functions with the %qc
directive:

find gcc -name "*.c" ! -path "*/testsuite/*" | xargs grep "%qc")
gcc/fortran/io.c:  const char *unexpected_element  = _("Unexpected element %qc
in format "
gcc/fortran/matchexp.c: gfc_error ("Bad character %qc in OPERATOR name at %C",
name[i]);
gcc/fortran/symbol.c:     gfc_error ("Letter %qc already set in IMPLICIT
statement at %C",
gcc/fortran/symbol.c:         gfc_error ("Letter %qc already has an IMPLICIT
type at %C",
gcc/c-family/c-lex.c:     error_at (*loc, "stray %qc in program", (int) c);
gcc/c-family/c-format.c:                                " %qc in format",
gcc/c-family/c-format.c:                              "use of %qs length
modifier with %qc type"
grep: gcc/cp/.#decl.c: No such file or directory
gcc/stmt.c:     warning (0, "output constraint %qc for operand %d "
gcc/stmt.c:         error ("input operand constraint contains %qc",
constraint[j]);
gcc/stmt.c:         error ("invalid punctuation %qc in constraint",
constraint[j]);
gcc/config/mmix/mmix.c:      internal_error ("MMIX Internal: Missing %qc case
in mmix_print_operand", code);
gcc/config/avr/driver-avr.c:        error ("strange device name %qs after %qs:
bad character %qc",
gcc/gcc.c:          error ("spec failure: unrecognized spec option %qc", c);
gcc/gcc.c:  fatal_error (input_location, "braced spec %qs is invalid at %qc",
orig, *p);

Reply via email to