Hi! The last argument to strncasecmp is incorrect, so it matched even when can%' wasn't followed by t. Also, the !ISALPHA (format_chars[1]) test looks pointless, format_chars[1] must be ' if strncasecmp succeeded and so will never be ISALPHA.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-02-10 Jakub Jelinek <ja...@redhat.com> PR other/93641 * c-format.c (check_plain): Fix up last argument of strncasecmp. Remove useless extra test. * gcc.dg/format/gcc_diag-11.c (test_cdiag_bad_words): Add two further tests. --- gcc/c-family/c-format.c.jj 2020-01-12 11:54:36.202416592 +0100 +++ gcc/c-family/c-format.c 2020-02-10 10:03:49.224547303 +0100 @@ -3270,8 +3270,7 @@ check_plain (location_t format_string_lo "quoted %qs directive in format; " "use %qs instead", "%s", "%qs"); else if (format_chars - orig_format_chars > 2 - && !strncasecmp (format_chars - 3, "can%'t", 5) - && !ISALPHA (format_chars[1])) + && !strncasecmp (format_chars - 3, "can%'t", 6)) format_warning_substr (format_string_loc, format_string_cst, fmtchrpos - 3, fmtchrpos + 3, opt, --- gcc/testsuite/gcc.dg/format/gcc_diag-11.c.jj 2020-01-12 11:54:37.423398171 +0100 +++ gcc/testsuite/gcc.dg/format/gcc_diag-11.c 2020-02-10 10:04:50.594632918 +0100 @@ -400,6 +400,8 @@ void test_cdiag_bad_words (tree t, gimpl cdiag ("you can't do that"); /* { dg-warning "contraction 'can't' in format" } */ cdiag ("you can%'t do that");/* { dg-warning "contraction 'can%'t' in format" } */ cdiag ("Can%'t touch this.");/* { dg-warning "contraction 'Can%'t' in format" } */ + cdiag ("can%'"); + cdiag ("can%' whatever"); cdiag ("on the commandline");/* { dg-warning "misspelled term 'commandline' in format; use 'command line' instead" } */ cdiag ("command line option");/* { dg-warning "misspelled term 'command line option' in format; use 'command-line option' instead" } */ cdiag ("it mustn't be"); /* { dg-warning "contraction 'mustn't' in format" } */ Jakub