diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index db65c14a7a5af99d3652b9fb5b2c86e9e8b53857..9cfd2a6bc4e00a590156ac28fb89256756ed2364 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -379,8 +379,8 @@ C ObjC C++ ObjC++ Warning Alias(Wbidi-chars=,any,none) ; Wbidi-chars= -C ObjC C++ ObjC++ RejectNegative Joined Warning CPP(cpp_warn_bidirectional) CppReason(CPP_W_BIDIRECTIONAL) Var(warn_bidirectional) Init(bidirectional_unpaired) Enum(cpp_bidirectional_level) --Wbidi-chars=[none|unpaired|any] Warn about UTF-8 bidirectional control characters. +C ObjC C++ ObjC++ RejectNegative Joined Warning CPP(cpp_warn_bidirectional) CppReason(CPP_W_BIDIRECTIONAL) Var(warn_bidirectional) Init(bidirectional_unpaired) Enum(cpp_bidirectional_level) EnumSet +-Wbidi-chars=[none|unpaired|any|ucn] Warn about UTF-8 bidirectional control characters. ; Required for these enum values. SourceInclude @@ -390,13 +390,16 @@ Enum Name(cpp_bidirectional_level) Type(int) UnknownError(argument %qs to %<-Wbidi-chars%> not recognized) EnumValue -Enum(cpp_bidirectional_level) String(none) Value(bidirectional_none) +Enum(cpp_bidirectional_level) String(none) Value(bidirectional_none) Set(1) EnumValue -Enum(cpp_bidirectional_level) String(unpaired) Value(bidirectional_unpaired) +Enum(cpp_bidirectional_level) String(unpaired) Value(bidirectional_unpaired) Set(1) EnumValue -Enum(cpp_bidirectional_level) String(any) Value(bidirectional_any) +Enum(cpp_bidirectional_level) String(any) Value(bidirectional_any) Set(1) + +EnumValue +Enum(cpp_bidirectional_level) String(ucn) Value(bidirectional_ucn) Set(2) Wbool-compare C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 309f5e38a8599811aa79ed88ad861d3d71230723..9e588db4fce6f7bcbfda8a98e80910b4cacabf25 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -328,7 +328,7 @@ Objective-C and Objective-C++ Dialects}. -Warray-bounds -Warray-bounds=@var{n} -Warray-compare @gol -Wno-attributes -Wattribute-alias=@var{n} -Wno-attribute-alias @gol -Wno-attribute-warning @gol --Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]} @gol +-Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{|}ucn@r{]} @gol -Wbool-compare -Wbool-operation @gol -Wno-builtin-declaration-mismatch @gol -Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol @@ -7803,7 +7803,7 @@ Attributes considered include @code{alloc_align}, @code{alloc_size}, This is the default. You can disable these warnings with either @option{-Wno-attribute-alias} or @option{-Wattribute-alias=0}. -@item -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]} +@item -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{|}ucn@r{]} @opindex Wbidi-chars= @opindex Wbidi-chars @opindex Wno-bidi-chars @@ -7820,6 +7820,10 @@ bidi contexts. @option{-Wbidi-chars=none} turns the warning off. @option{-Wbidi-chars=any} warns about any use of bidirectional control characters. +By default, this warning does not warn about UCNs. It is, however, possible +to turn on such checking by using @option{-Wbidi-chars=unpaired,ucn} or +@option{-Wbidi-chars=any,ucn}. + @item -Wbool-compare @opindex Wno-bool-compare @opindex Wbool-compare diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-10.c b/gcc/testsuite/c-c++-common/Wbidi-chars-10.c index 3f851b69e658104caddeb027b396b91d1face28c..cdcdce2be089c4c09635d4423da9b3bf3e3fe4e0 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-10.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-10.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired" } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn" } */ /* More nesting testing. */ /* RLE‫ LRI⦠PDF‬ PDIâ©*/ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-11.c b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c index 270ce2368a95f994dc5521b5f0bbf0771826e982..ea83029d6b99718c7851d4ba2cb0178ef7fb9b40 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-11.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired" } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn" } */ /* Test that we warn when mixing UCN and UTF-8. */ int LRE_‪_PDF_\u202c; diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-14.c b/gcc/testsuite/c-c++-common/Wbidi-chars-14.c index ba5f75d9553cfefdd3fc9a1d998cfc75da302b0e..cb6b05efac1bc56af66686bf9809f111ff88bf6a 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-14.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-14.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired" } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn" } */ /* Test PDI handling, which also pops any subsequent LREs, RLEs, LROs, or RLOs. */ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-16.c b/gcc/testsuite/c-c++-common/Wbidi-chars-16.c index baa0159861c099fc0dc0cac34f95f7cdd8150e28..eaf0ec9a77717632f0c8d6e2701c3fb01f0ac1a2 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-16.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-16.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=any" } */ +/* { dg-options "-Wbidi-chars=any,ucn" } */ /* Test LTR/RTL chars. */ /* LTR<‎> */ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-17.c b/gcc/testsuite/c-c++-common/Wbidi-chars-17.c index 07cb4321f964522f7ac44afec956b20e6928b149..341922146a711bdc9453f4c1af178869cd70b794 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-17.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-17.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired" } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn" } */ /* Test LTR/RTL chars. */ /* LTR<‎> */ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-18.c b/gcc/testsuite/c-c++-common/Wbidi-chars-18.c new file mode 100644 index 0000000000000000000000000000000000000000..ae586d5e08c55306d4971a79831b8fa805a3d215 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-18.c @@ -0,0 +1,11 @@ +/* PR preprocessor/104030 */ +/* { dg-do compile } */ +/* By default, don't warn about UCNs. */ + +const char * +fn () +{ + const char *aText = "\u202D" "abc"; +/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ + return aText; +} diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-19.c b/gcc/testsuite/c-c++-common/Wbidi-chars-19.c new file mode 100644 index 0000000000000000000000000000000000000000..9985c3be7a58e9998b808b900a47b37da0fa199a --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-19.c @@ -0,0 +1,11 @@ +/* PR preprocessor/104030 */ +/* { dg-do compile } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn" } */ + +const char * +fn () +{ + const char *aText = "\u202D" "abc"; +/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ + return aText; +} diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-20.c b/gcc/testsuite/c-c++-common/Wbidi-chars-20.c new file mode 100644 index 0000000000000000000000000000000000000000..859f3d53779dcc6d9c99eb6cce94432fd50fd96f --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-20.c @@ -0,0 +1,11 @@ +/* PR preprocessor/104030 */ +/* { dg-do compile } */ +/* { dg-options "-Wbidi-chars=any" } */ + +const char * +fn () +{ + const char *aText = "\u202D" "abc"; +/* { dg-bogus "U\\+202D" "" { target *-*-* } .-1 } */ + return aText; +} diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-21.c b/gcc/testsuite/c-c++-common/Wbidi-chars-21.c new file mode 100644 index 0000000000000000000000000000000000000000..2720b8a883ec35a0712f00c2b29b9b5257e00371 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-21.c @@ -0,0 +1,11 @@ +/* PR preprocessor/104030 */ +/* { dg-do compile } */ +/* { dg-options "-Wbidi-chars=ucn,any" } */ + +const char * +fn () +{ + const char *aText = "\u202D" "abc"; +/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ + return aText; +} diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-22.c b/gcc/testsuite/c-c++-common/Wbidi-chars-22.c new file mode 100644 index 0000000000000000000000000000000000000000..f960e597c5938f51e40b44c1e6d9a8cc95e11ad7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-22.c @@ -0,0 +1,11 @@ +/* PR preprocessor/104030 */ +/* { dg-do compile } */ +/* { dg-options "-Wbidi-chars=none,ucn" } */ + +const char * +fn () +{ + const char *aText = "\u202D" "abc"; +/* { dg-bogus "" "" { target *-*-* } .-1 } */ + return aText; +} diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-23.c b/gcc/testsuite/c-c++-common/Wbidi-chars-23.c new file mode 100644 index 0000000000000000000000000000000000000000..7de0a11070aaf3ba49b5ee00a279cb2f3f7d09fa --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-23.c @@ -0,0 +1,11 @@ +/* PR preprocessor/104030 */ +/* { dg-do compile } */ +/* { dg-options "-Wbidi-chars=ucn" } */ + +const char * +fn () +{ + const char *aText = "\u202D" "abc"; +/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ + return aText; +} diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-4.c b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c index 639e5c62e8886515754c2ebf00198f40e526304e..d2f0739dae06bc1a7b5168a03326021b8fe3712a 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-4.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=any -Wno-multichar -Wno-overflow" } */ +/* { dg-options "-Wbidi-chars=any,ucn -Wno-multichar -Wno-overflow" } */ /* Test all bidi chars in various contexts (identifiers, comments, string literals, character constants), both UCN and UTF-8. The bidi chars here are properly terminated, except for the character constants. */ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-5.c b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c index 68cb053144ba46a72f30a5252bf3bfdb35ab75fe..ad49498fe234e5bbb5f8e89be0aebb96e1d2eff5 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-5.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired -Wno-multichar -Wno-overflow" } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn -Wno-multichar -Wno-overflow" } */ /* Test all bidi chars in various contexts (identifiers, comments, string literals, character constants), both UCN and UTF-8. The bidi chars here are properly terminated, except for the character constants. */ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-6.c b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c index 0ce6fff2deed0643a2191bd2a1f952d38ab4d7c5..8c1c1b2a2705f222a5b1f4fc29642cdf95ef38f7 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-6.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired" } */ +/* { dg-options "-Wbidi-chars=ucn,unpaired" } */ /* Test nesting of bidi chars in various contexts. */ /* Terminated by the wrong char: */ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-7.c b/gcc/testsuite/c-c++-common/Wbidi-chars-7.c index d012d420ec04fe1755965ddd853d86da3746a84a..3270952a09a45c209834136af74634ab47792c65 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-7.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-7.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=any" } */ +/* { dg-options "-Wbidi-chars=any,ucn" } */ /* Test we ignore UCNs in comments. */ // a b c \u202a 1 2 3 diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-8.c b/gcc/testsuite/c-c++-common/Wbidi-chars-8.c index 4f54c5092eca1296f8953d44bef37f37564d6bad..3983168c9f1e3a08ba88283692b8b0c81c280b66 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-8.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-8.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=any" } */ +/* { dg-options "-Wbidi-chars=any,ucn" } */ /* Test \u vs \U. */ int a_\u202A; diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-9.c b/gcc/testsuite/c-c++-common/Wbidi-chars-9.c index e2af1b1ca97f77d6048ad044c7b5ef54450ef831..0ddb0d931088c9207e7faa2332473f7dfb157f8d 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-9.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-9.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired" } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn" } */ /* Test that we properly separate bidi contexts (comment/identifier/character constant/string literal). */ diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c b/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c index 298750a2a64c881b447552f4b2f72330a2e8dc3b..0c71f306dbc73c5911e25075295ef43c536ecc2c 100644 --- a/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c +++ b/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c @@ -1,6 +1,6 @@ /* PR preprocessor/103026 */ /* { dg-do compile } */ -/* { dg-options "-Wbidi-chars=unpaired -fdiagnostics-show-caret" } */ +/* { dg-options "-Wbidi-chars=unpaired,ucn -fdiagnostics-show-caret" } */ /* Verify that we escape and underline pertinent bidirectional control characters when quoting the source. */ diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 940c79f98c12ab233b249e3da2fe32b0b72fa137..3eba6f74b5726c13489b11db9807060f4d37daf3 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -319,15 +319,16 @@ enum cpp_main_search CMS_system, /* Search the system INCLUDE path. */ }; -/* The possible bidirectional control characters checking levels, from least - restrictive to most. */ +/* The possible bidirectional control characters checking levels. */ enum cpp_bidirectional_level { /* No checking. */ - bidirectional_none, + bidirectional_none = 0, /* Only detect unpaired uses of bidirectional control characters. */ - bidirectional_unpaired, + bidirectional_unpaired = 1, /* Detect any use of bidirectional control characters. */ - bidirectional_any + bidirectional_any = 2, + /* Also warn about UCNs. */ + bidirectional_ucn = 4 }; /* This structure is nested inside struct cpp_reader, and diff --git a/libcpp/internal.h b/libcpp/internal.h index 364c41c8149cd9c7544e2b828fcad051fcbc0325..badfd1b40daa54d791105204be5d587a493d8dba 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -605,7 +605,8 @@ struct cpp_reader characters. */ bool warn_bidi_p () const { - return CPP_OPTION (this, cpp_warn_bidirectional) != bidirectional_none; + return (CPP_OPTION (this, cpp_warn_bidirectional) + & (bidirectional_unpaired|bidirectional_any)); } }; diff --git a/libcpp/lex.cc b/libcpp/lex.cc index 4d736576cc1acf955eb057473270b851ae19c802..fb1dfabb7afef0d52fe4a42703370482e14cb037 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -1560,8 +1560,11 @@ class unpaired_bidi_rich_location : public rich_location static void maybe_warn_bidi_on_close (cpp_reader *pfile, const uchar *p) { - if (CPP_OPTION (pfile, cpp_warn_bidirectional) == bidirectional_unpaired - && bidi::vec.count () > 0) + const auto warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional); + if (bidi::vec.count () > 0 + && (warn_bidi & bidirectional_unpaired + && (!bidi::current_ctx_ucn_p () + || (warn_bidi & bidirectional_ucn)))) { const location_t loc = linemap_position_for_column (pfile->line_table, @@ -1597,7 +1600,7 @@ maybe_warn_bidi_on_char (cpp_reader *pfile, bidi::kind kind, const auto warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional); - if (warn_bidi != bidirectional_none) + if (warn_bidi & (bidirectional_unpaired|bidirectional_any)) { rich_location rich_loc (pfile->line_table, loc); rich_loc.set_escape_on_output (true); @@ -1605,10 +1608,10 @@ maybe_warn_bidi_on_char (cpp_reader *pfile, bidi::kind kind, /* It seems excessive to warn about a PDI/PDF that is closing an opened context because we've already warned about the opening character. Except warn when we have a UCN x UTF-8 - mismatch. */ + mismatch, if UCN checking is enabled. */ if (kind == bidi::current_ctx ()) { - if (warn_bidi == bidirectional_unpaired + if (warn_bidi == (bidirectional_unpaired|bidirectional_ucn) && bidi::current_ctx_ucn_p () != ucn_p) { rich_loc.add_range (bidi::current_ctx_loc ()); @@ -1617,7 +1620,8 @@ maybe_warn_bidi_on_char (cpp_reader *pfile, bidi::kind kind, "a context by \"%s\"", bidi::to_str (kind)); } } - else if (warn_bidi == bidirectional_any) + else if (warn_bidi & bidirectional_any + && (!ucn_p || (warn_bidi & bidirectional_ucn))) { if (kind == bidi::kind::PDF || kind == bidi::kind::PDI) cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc,