diff --git a/SOURCES/gcc8-Wbidi-chars.patch b/SOURCES/gcc8-Wbidi-chars.patch new file mode 100644 index 0000000..988defe --- /dev/null +++ b/SOURCES/gcc8-Wbidi-chars.patch @@ -0,0 +1,1644 @@ +commit 51c500269bf53749b107807d84271385fad35628 +Author: Marek Polacek +Date: Wed Oct 6 14:33:59 2021 -0400 + + libcpp: Implement -Wbidi-chars for CVE-2021-42574 [PR103026] + + From a link below: + "An issue was discovered in the Bidirectional Algorithm in the Unicode + Specification through 14.0. It permits the visual reordering of + characters via control sequences, which can be used to craft source code + that renders different logic than the logical ordering of tokens + ingested by compilers and interpreters. Adversaries can leverage this to + encode source code for compilers accepting Unicode such that targeted + vulnerabilities are introduced invisibly to human reviewers." + + More info: + https://nvd.nist.gov/vuln/detail/CVE-2021-42574 + https://trojansource.codes/ + + This is not a compiler bug. However, to mitigate the problem, this patch + implements -Wbidi-chars=[none|unpaired|any] to warn about possibly + misleading Unicode bidirectional control characters the preprocessor may + encounter. + + The default is =unpaired, which warns about improperly terminated + bidirectional control characters; e.g. a LRE without its corresponding PDF. + The level =any warns about any use of bidirectional control characters. + + This patch handles both UCNs and UTF-8 characters. UCNs designating + bidi characters in identifiers are accepted since r204886. Then r217144 + enabled -fextended-identifiers by default. Extended characters in C/C++ + identifiers have been accepted since r275979. However, this patch still + warns about mixing UTF-8 and UCN bidi characters; there seems to be no + good reason to allow mixing them. + + We warn in different contexts: comments (both C and C++-style), string + literals, character constants, and identifiers. Expectedly, UCNs are ignored + in comments and raw string literals. The bidirectional control characters + can nest so this patch handles that as well. + + I have not included nor tested this at all with Fortran (which also has + string literals and line comments). + + Dave M. posted patches improving diagnostic involving Unicode characters. + This patch does not make use of this new infrastructure yet. + + PR preprocessor/103026 + + gcc/c-family/ChangeLog: + + * c.opt (Wbidi-chars, Wbidi-chars=): New option. + + gcc/ChangeLog: + + * doc/invoke.texi: Document -Wbidi-chars. + + libcpp/ChangeLog: + + * include/cpplib.h (enum cpp_bidirectional_level): New. + (struct cpp_options): Add cpp_warn_bidirectional. + (enum cpp_warning_reason): Add CPP_W_BIDIRECTIONAL. + * internal.h (struct cpp_reader): Add warn_bidi_p member + function. + * init.c (cpp_create_reader): Set cpp_warn_bidirectional. + * lex.c (bidi): New namespace. + (get_bidi_utf8): New function. + (get_bidi_ucn): Likewise. + (maybe_warn_bidi_on_close): Likewise. + (maybe_warn_bidi_on_char): Likewise. + (_cpp_skip_block_comment): Implement warning about bidirectional + control characters. + (skip_line_comment): Likewise. + (forms_identifier_p): Likewise. + (lex_identifier): Likewise. + (lex_string): Likewise. + (lex_raw_string): Likewise. + + gcc/testsuite/ChangeLog: + + * c-c++-common/Wbidi-chars-1.c: New test. + * c-c++-common/Wbidi-chars-2.c: New test. + * c-c++-common/Wbidi-chars-3.c: New test. + * c-c++-common/Wbidi-chars-4.c: New test. + * c-c++-common/Wbidi-chars-5.c: New test. + * c-c++-common/Wbidi-chars-6.c: New test. + * c-c++-common/Wbidi-chars-7.c: New test. + * c-c++-common/Wbidi-chars-8.c: New test. + * c-c++-common/Wbidi-chars-9.c: New test. + * c-c++-common/Wbidi-chars-10.c: New test. + * c-c++-common/Wbidi-chars-11.c: New test. + * c-c++-common/Wbidi-chars-12.c: New test. + * c-c++-common/Wbidi-chars-13.c: New test. + * c-c++-common/Wbidi-chars-14.c: New test. + * c-c++-common/Wbidi-chars-15.c: New test. + * c-c++-common/Wbidi-chars-16.c: New test. + * c-c++-common/Wbidi-chars-17.c: New test. + +diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt +index f591b39be5a..cf922812198 100644 +--- a/gcc/c-family/c.opt ++++ b/gcc/c-family/c.opt +@@ -334,6 +334,30 @@ Wbad-function-cast + C ObjC Var(warn_bad_function_cast) Warning + Warn about casting functions to incompatible types. + ++Wbidi-chars ++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. ++ ++; Required for these enum values. ++SourceInclude ++cpplib.h ++ ++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) ++ ++EnumValue ++Enum(cpp_bidirectional_level) String(unpaired) Value(bidirectional_unpaired) ++ ++EnumValue ++Enum(cpp_bidirectional_level) String(any) Value(bidirectional_any) ++ + Wbool-compare + C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) + Warn about boolean expression compared with an integer value different from true/false. +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 78ca7738df2..cc85c53aede 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -264,7 +264,8 @@ Objective-C and Objective-C++ Dialects}. + -Walloc-zero -Walloc-size-larger-than=@var{n} + -Walloca -Walloca-larger-than=@var{n} @gol + -Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol +--Wno-attributes -Wbool-compare -Wbool-operation @gol ++-Wno-attributes -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]} @gol ++-Wbool-compare -Wbool-operation @gol + -Wno-builtin-declaration-mismatch @gol + -Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol + -Wc++-compat -Wc++11-compat -Wc++14-compat @gol +@@ -5606,6 +5607,23 @@ Warn about declarations using the @code{alias} and similar attributes whose + target is incompatible with the type of the alias. @xref{Function Attributes, + ,Declaring Attributes of Functions}. + ++@item -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]} ++@opindex Wbidi-chars= ++@opindex Wbidi-chars ++@opindex Wno-bidi-chars ++Warn about possibly misleading UTF-8 bidirectional control characters in ++comments, string literals, character constants, and identifiers. Such ++characters can change left-to-right writing direction into right-to-left ++(and vice versa), which can cause confusion between the logical order and ++visual order. This may be dangerous; for instance, it may seem that a piece ++of code is not commented out, whereas it in fact is. ++ ++There are three levels of warning supported by GCC@. The default is ++@option{-Wbidi-chars=unpaired}, which warns about improperly terminated ++bidi contexts. @option{-Wbidi-chars=none} turns the warning off. ++@option{-Wbidi-chars=any} warns about any use of bidirectional control ++characters. ++ + @item -Wbool-compare + @opindex Wno-bool-compare + @opindex Wbool-compare +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-1.c b/gcc/testsuite/c-c++-common/Wbidi-chars-1.c +new file mode 100644 +index 00000000000..34f5ac19271 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-1.c +@@ -0,0 +1,12 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++ ++int main() { ++ int isAdmin = 0; ++ /*‮ } ⁦if (isAdmin)⁩ ⁦ begin admins only */ ++/* { dg-warning "bidirectional" "" { target *-*-* } .-1 } */ ++ __builtin_printf("You are an admin.\n"); ++ /* end admins only ‮ { ⁦*/ ++/* { dg-warning "bidirectional" "" { target *-*-* } .-1 } */ ++ return 0; ++} +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-10.c b/gcc/testsuite/c-c++-common/Wbidi-chars-10.c +new file mode 100644 +index 00000000000..3f851b69e65 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-10.c +@@ -0,0 +1,27 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* More nesting testing. */ ++ ++/* RLE‫ LRI⁦ PDF‬ PDI⁩*/ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int LRE_\u202a_PDF_\u202c; ++int LRE_\u202a_PDF_\u202c_LRE_\u202a_PDF_\u202c; ++int LRE_\u202a_LRI_\u2066_PDF_\u202c_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int RLE_\u202b_RLI_\u2067_PDF_\u202c_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int RLE_\u202b_RLI_\u2067_PDI_\u2069_PDF_\u202c; ++int FSI_\u2068_LRO_\u202d_PDI_\u2069_PDF_\u202c; ++int FSI_\u2068; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int FSI_\u2068_PDI_\u2069; ++int FSI_\u2068_FSI_\u2068_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069; ++int RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDF_\u202c; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int RLI_\u2067_RLI_\u2067_RLI_\u2067_RLI_\u2067_FSI_\u2068_PDI_\u2069_PDI_\u2069_PDI_\u2069_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-11.c b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c +new file mode 100644 +index 00000000000..44d044d82de +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c +@@ -0,0 +1,9 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* Test that we warn when mixing UCN and UTF-8. */ ++ ++const char *s1 = "LRE_‪_PDF_\u202c"; ++/* { dg-warning "mismatch" "" { target *-*-* } .-1 } */ ++const char *s2 = "LRE_\u202a_PDF_‬"; ++/* { dg-warning "mismatch" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-12.c b/gcc/testsuite/c-c++-common/Wbidi-chars-12.c +new file mode 100644 +index 00000000000..b07eec1da91 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-12.c +@@ -0,0 +1,19 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile { target { c || c++11 } } } */ ++/* { dg-options "-Wbidi-chars=any" } */ ++/* Test raw strings. */ ++ ++const char *s1 = R"(a b c LRE‪ 1 2 3 PDF‬ x y z)"; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++const char *s2 = R"(a b c RLE‫ 1 2 3 PDF‬ x y z)"; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++const char *s3 = R"(a b c LRO‭ 1 2 3 PDF‬ x y z)"; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++const char *s4 = R"(a b c RLO‮ 1 2 3 PDF‬ x y z)"; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++const char *s7 = R"(a b c FSI⁨ 1 2 3 PDI⁩ x y) z"; ++/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */ ++const char *s8 = R"(a b c PDI⁩ x y )z"; ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-1 } */ ++const char *s9 = R"(a b c PDF‬ x y z)"; ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-13.c b/gcc/testsuite/c-c++-common/Wbidi-chars-13.c +new file mode 100644 +index 00000000000..b2dd9fde752 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-13.c +@@ -0,0 +1,17 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile { target { c || c++11 } } } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* Test raw strings. */ ++ ++const char *s1 = R"(a b c LRE‪ 1 2 3)"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++const char *s2 = R"(a b c RLE‫ 1 2 3)"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++const char *s3 = R"(a b c LRO‭ 1 2 3)"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++const char *s4 = R"(a b c FSI⁨ 1 2 3)"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++const char *s5 = R"(a b c LRI⁦ 1 2 3)"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++const char *s6 = R"(a b c RLI⁧ 1 2 3)"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-14.c b/gcc/testsuite/c-c++-common/Wbidi-chars-14.c +new file mode 100644 +index 00000000000..ba5f75d9553 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-14.c +@@ -0,0 +1,38 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* Test PDI handling, which also pops any subsequent LREs, RLEs, LROs, ++ or RLOs. */ ++ ++/* LRI_⁦_LRI_⁦_RLE_‫_RLE_‫_RLE_‫_PDI_⁩*/ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// LRI_⁦_RLE_‫_RLE_‫_RLE_‫_PDI_⁩ ++// LRI_⁦_RLO_‮_RLE_‫_RLE_‫_PDI_⁩ ++// LRI_⁦_RLO_‮_RLE_‫_PDI_⁩ ++// FSI_⁨_RLO_‮_PDI_⁩ ++// FSI_⁨_FSI_⁨_RLO_‮_PDI_⁩ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ ++int LRI_\u2066_LRI_\u2066_LRE_\u202a_LRE_\u202a_LRE_\u202a_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int LRI_\u2066_LRI_\u2066_LRE_\u202a_LRE_\u202a_LRE_\u202a_PDI_\u2069_PDI_\u2069; ++int LRI_\u2066_LRI_\u2066_LRI_\u2066_LRE_\u202a_LRE_\u202a_LRE_\u202a_PDI_\u2069_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int PDI_\u2069; ++int LRI_\u2066_PDI_\u2069; ++int RLI_\u2067_PDI_\u2069; ++int LRE_\u202a_LRI_\u2066_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int LRI_\u2066_LRE_\u202a_PDF_\u202c_PDI_\u2069; ++int LRI_\u2066_LRE_\u202a_LRE_\u202a_PDF_\u202c_PDI_\u2069; ++int RLI_\u2067_LRI_\u2066_LRE_\u202a_LRE_\u202a_PDF_\u202c_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int FSI_\u2068_LRI_\u2066_LRE_\u202a_LRE_\u202a_PDF_\u202c_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int RLO_\u202e_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int RLI_\u2067_PDI_\u2069_RLI_\u2067; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int FSI_\u2068_PDF_\u202c_PDI_\u2069; ++int FSI_\u2068_FSI_\u2068_PDF_\u202c_PDI_\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-15.c b/gcc/testsuite/c-c++-common/Wbidi-chars-15.c +new file mode 100644 +index 00000000000..a0ce8ff5e2c +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-15.c +@@ -0,0 +1,59 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* Test unpaired bidi control chars in multiline comments. */ ++ ++/* ++ * LRE‪ end ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* ++ * RLE‫ end ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* ++ * LRO‭ end ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* ++ * RLO‮ end ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* ++ * LRI⁦ end ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* ++ * RLI⁧ end ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* ++ * FSI⁨ end ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* LRE‪ ++ PDF‬ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++/* FSI⁨ ++ PDI⁩ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++ ++/* LRE<‪> ++ * ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-3 } */ ++ ++/* ++ * LRE<‪> ++ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++ ++/* ++ * ++ * LRE<‪> */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ ++/* RLI<⁧> */ /* PDI<⁩> */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* LRE<‪> */ /* PDF<‬> */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-16.c b/gcc/testsuite/c-c++-common/Wbidi-chars-16.c +new file mode 100644 +index 00000000000..baa0159861c +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-16.c +@@ -0,0 +1,26 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=any" } */ ++/* Test LTR/RTL chars. */ ++ ++/* LTR<‎> */ ++/* { dg-warning "U\\+200E" "" { target *-*-* } .-1 } */ ++// LTR<‎> ++/* { dg-warning "U\\+200E" "" { target *-*-* } .-1 } */ ++/* RTL<‏> */ ++/* { dg-warning "U\\+200F" "" { target *-*-* } .-1 } */ ++// RTL<‏> ++/* { dg-warning "U\\+200F" "" { target *-*-* } .-1 } */ ++ ++const char *s1 = "LTR<‎>"; ++/* { dg-warning "U\\+200E" "" { target *-*-* } .-1 } */ ++const char *s2 = "LTR\u200e"; ++/* { dg-warning "U\\+200E" "" { target *-*-* } .-1 } */ ++const char *s3 = "LTR\u200E"; ++/* { dg-warning "U\\+200E" "" { target *-*-* } .-1 } */ ++const char *s4 = "RTL<‏>"; ++/* { dg-warning "U\\+200F" "" { target *-*-* } .-1 } */ ++const char *s5 = "RTL\u200f"; ++/* { dg-warning "U\\+200F" "" { target *-*-* } .-1 } */ ++const char *s6 = "RTL\u200F"; ++/* { dg-warning "U\\+200F" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-17.c b/gcc/testsuite/c-c++-common/Wbidi-chars-17.c +new file mode 100644 +index 00000000000..07cb4321f96 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-17.c +@@ -0,0 +1,30 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* Test LTR/RTL chars. */ ++ ++/* LTR<‎> */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// LTR<‎> ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* RTL<‏> */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// RTL<‏> ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int ltr_\u200e; ++/* { dg-error "universal character " "" { target *-*-* } .-1 } */ ++int rtl_\u200f; ++/* { dg-error "universal character " "" { target *-*-* } .-1 } */ ++ ++const char *s1 = "LTR<‎>"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++const char *s2 = "LTR\u200e"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++const char *s3 = "LTR\u200E"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++const char *s4 = "RTL<‏>"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++const char *s5 = "RTL\u200f"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++const char *s6 = "RTL\u200F"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-2.c b/gcc/testsuite/c-c++-common/Wbidi-chars-2.c +new file mode 100644 +index 00000000000..2340374f276 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-2.c +@@ -0,0 +1,9 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++ ++int main() { ++ /* Say hello; newline⁧/*/ return 0 ; ++/* { dg-warning "bidirectional" "" { target *-*-* } .-1 } */ ++ __builtin_printf("Hello world.\n"); ++ return 0; ++} +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-3.c b/gcc/testsuite/c-c++-common/Wbidi-chars-3.c +new file mode 100644 +index 00000000000..9dc7edb6e64 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-3.c +@@ -0,0 +1,11 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++ ++int main() { ++ const char* access_level = "user"; ++ if (__builtin_strcmp(access_level, "user‮ ⁦// Check if admin⁩ ⁦")) { ++/* { dg-warning "bidirectional" "" { target *-*-* } .-1 } */ ++ __builtin_printf("You are an admin.\n"); ++ } ++ return 0; ++} +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-4.c b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c +new file mode 100644 +index 00000000000..49f856b9bfe +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c +@@ -0,0 +1,172 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=any -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. */ ++ ++/* a b c LRE‪ 1 2 3 PDF‬ x y z */ ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++/* a b c RLE‫ 1 2 3 PDF‬ x y z */ ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++/* a b c LRO‭ 1 2 3 PDF‬ x y z */ ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++/* a b c RLO‮ 1 2 3 PDF‬ x y z */ ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++/* a b c LRI⁦ 1 2 3 PDI⁩ x y z */ ++/* { dg-warning "U\\+2066" "" { target *-*-* } .-1 } */ ++/* a b c RLI⁧ 1 2 3 PDI⁩ x y */ ++/* { dg-warning "U\\+2067" "" { target *-*-* } .-1 } */ ++/* a b c FSI⁨ 1 2 3 PDI⁩ x y z */ ++/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */ ++ ++/* Same but C++ comments instead. */ ++// a b c LRE‪ 1 2 3 PDF‬ x y z ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++// a b c RLE‫ 1 2 3 PDF‬ x y z ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++// a b c LRO‭ 1 2 3 PDF‬ x y z ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++// a b c RLO‮ 1 2 3 PDF‬ x y z ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++// a b c LRI⁦ 1 2 3 PDI⁩ x y z ++/* { dg-warning "U\\+2066" "" { target *-*-* } .-1 } */ ++// a b c RLI⁧ 1 2 3 PDI⁩ x y ++/* { dg-warning "U\\+2067" "" { target *-*-* } .-1 } */ ++// a b c FSI⁨ 1 2 3 PDI⁩ x y z ++/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */ ++ ++/* Here we're closing an unopened context, warn when =any. */ ++/* a b c PDI⁩ x y z */ ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-1 } */ ++/* a b c PDF‬ x y z */ ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */ ++// a b c PDI⁩ x y z ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-1 } */ ++// a b c PDF‬ x y z ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */ ++ ++/* Multiline comments. */ ++/* a b c PDI⁩ x y z ++ */ ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-2 } */ ++/* a b c PDF‬ x y z ++ */ ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-2 } */ ++/* first ++ a b c PDI⁩ x y z ++ */ ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-2 } */ ++/* first ++ a b c PDF‬ x y z ++ */ ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-2 } */ ++/* first ++ a b c PDI⁩ x y z */ ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-1 } */ ++/* first ++ a b c PDF‬ x y z */ ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */ ++ ++void ++g1 () ++{ ++ const char *s1 = "a b c LRE‪ 1 2 3 PDF‬ x y z"; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++ const char *s2 = "a b c RLE‫ 1 2 3 PDF‬ x y z"; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++ const char *s3 = "a b c LRO‭ 1 2 3 PDF‬ x y z"; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++ const char *s4 = "a b c RLO‮ 1 2 3 PDF‬ x y z"; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++ const char *s5 = "a b c LRI⁦ 1 2 3 PDI⁩ x y z"; ++/* { dg-warning "U\\+2066" "" { target *-*-* } .-1 } */ ++ const char *s6 = "a b c RLI⁧ 1 2 3 PDI⁩ x y z"; ++/* { dg-warning "U\\+2067" "" { target *-*-* } .-1 } */ ++ const char *s7 = "a b c FSI⁨ 1 2 3 PDI⁩ x y z"; ++/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */ ++ const char *s8 = "a b c PDI⁩ x y z"; ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-1 } */ ++ const char *s9 = "a b c PDF‬ x y z"; ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */ ++ ++ const char *s10 = "a b c LRE\u202a 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++ const char *s11 = "a b c LRE\u202A 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++ const char *s12 = "a b c RLE\u202b 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++ const char *s13 = "a b c RLE\u202B 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++ const char *s14 = "a b c LRO\u202d 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++ const char *s15 = "a b c LRO\u202D 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++ const char *s16 = "a b c RLO\u202e 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++ const char *s17 = "a b c RLO\u202E 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++ const char *s18 = "a b c LRI\u2066 1 2 3 PDI\u2069 x y z"; ++/* { dg-warning "U\\+2066" "" { target *-*-* } .-1 } */ ++ const char *s19 = "a b c RLI\u2067 1 2 3 PDI\u2069 x y z"; ++/* { dg-warning "U\\+2067" "" { target *-*-* } .-1 } */ ++ const char *s20 = "a b c FSI\u2068 1 2 3 PDI\u2069 x y z"; ++/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */ ++} ++ ++void ++g2 () ++{ ++ const char c1 = '\u202a'; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++ const char c2 = '\u202A'; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++ const char c3 = '\u202b'; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++ const char c4 = '\u202B'; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++ const char c5 = '\u202d'; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++ const char c6 = '\u202D'; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++ const char c7 = '\u202e'; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++ const char c8 = '\u202E'; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++ const char c9 = '\u2066'; ++/* { dg-warning "U\\+2066" "" { target *-*-* } .-1 } */ ++ const char c10 = '\u2067'; ++/* { dg-warning "U\\+2067" "" { target *-*-* } .-1 } */ ++ const char c11 = '\u2068'; ++/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */ ++} ++ ++int A\u202cY; ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */ ++int A\u202CY2; ++/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */ ++ ++int d\u202ae\u202cf; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++int d\u202Ae\u202cf2; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++int d\u202be\u202cf; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++int d\u202Be\u202cf2; ++/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */ ++int d\u202de\u202cf; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++int d\u202De\u202cf2; ++/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */ ++int d\u202ee\u202cf; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++int d\u202Ee\u202cf2; ++/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */ ++int d\u2066e\u2069f; ++/* { dg-warning "U\\+2066" "" { target *-*-* } .-1 } */ ++int d\u2067e\u2069f; ++/* { dg-warning "U\\+2067" "" { target *-*-* } .-1 } */ ++int d\u2068e\u2069f; ++/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */ ++int X\u2069; ++/* { dg-warning "U\\+2069" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-5.c b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c +new file mode 100644 +index 00000000000..f5776806c79 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c +@@ -0,0 +1,172 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired -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. */ ++ ++/* a b c LRE‪ 1 2 3 PDF‬ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c RLE‫ 1 2 3 PDF‬ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c LRO‭ 1 2 3 PDF‬ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c RLO‮ 1 2 3 PDF‬ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c LRI⁦ 1 2 3 PDI⁩ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c RLI⁧ 1 2 3 PDI⁩ x y */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c FSI⁨ 1 2 3 PDI⁩ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ ++/* Same but C++ comments instead. */ ++// a b c LRE‪ 1 2 3 PDF‬ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c RLE‫ 1 2 3 PDF‬ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c LRO‭ 1 2 3 PDF‬ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c RLO‮ 1 2 3 PDF‬ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c LRI⁦ 1 2 3 PDI⁩ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c RLI⁧ 1 2 3 PDI⁩ x y ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c FSI⁨ 1 2 3 PDI⁩ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ ++/* Here we're closing an unopened context, warn when =any. */ ++/* a b c PDI⁩ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c PDF‬ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c PDI⁩ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++// a b c PDF‬ x y z ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ ++/* Multiline comments. */ ++/* a b c PDI⁩ x y z ++ */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-2 } */ ++/* a b c PDF‬ x y z ++ */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-2 } */ ++/* first ++ a b c PDI⁩ x y z ++ */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-2 } */ ++/* first ++ a b c PDF‬ x y z ++ */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-2 } */ ++/* first ++ a b c PDI⁩ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++/* first ++ a b c PDF‬ x y z */ ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ ++void ++g1 () ++{ ++ const char *s1 = "a b c LRE‪ 1 2 3 PDF‬ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s2 = "a b c RLE‫ 1 2 3 PDF‬ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s3 = "a b c LRO‭ 1 2 3 PDF‬ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s4 = "a b c RLO‮ 1 2 3 PDF‬ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s5 = "a b c LRI⁦ 1 2 3 PDI⁩ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s6 = "a b c RLI⁧ 1 2 3 PDI⁩ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s7 = "a b c FSI⁨ 1 2 3 PDI⁩ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s8 = "a b c PDI⁩ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s9 = "a b c PDF‬ x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ ++ const char *s10 = "a b c LRE\u202a 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s11 = "a b c LRE\u202A 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s12 = "a b c RLE\u202b 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s13 = "a b c RLE\u202B 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s14 = "a b c LRO\u202d 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s15 = "a b c LRO\u202D 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s16 = "a b c RLO\u202e 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s17 = "a b c RLO\u202E 1 2 3 PDF\u202c x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s18 = "a b c LRI\u2066 1 2 3 PDI\u2069 x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s19 = "a b c RLI\u2067 1 2 3 PDI\u2069 x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s20 = "a b c FSI\u2068 1 2 3 PDI\u2069 x y z"; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++} ++ ++void ++g2 () ++{ ++ const char c1 = '\u202a'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c2 = '\u202A'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c3 = '\u202b'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c4 = '\u202B'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c5 = '\u202d'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c6 = '\u202D'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c7 = '\u202e'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c8 = '\u202E'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c9 = '\u2066'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c10 = '\u2067'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char c11 = '\u2068'; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++} ++ ++int A\u202cY; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int A\u202CY2; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++ ++int d\u202ae\u202cf; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u202Ae\u202cf2; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u202be\u202cf; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u202Be\u202cf2; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u202de\u202cf; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u202De\u202cf2; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u202ee\u202cf; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u202Ee\u202cf2; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u2066e\u2069f; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u2067e\u2069f; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int d\u2068e\u2069f; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ ++int X\u2069; ++/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-6.c b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c +new file mode 100644 +index 00000000000..a65d6faf60e +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c +@@ -0,0 +1,130 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* Test nesting of bidi chars in various contexts. */ ++ ++/* Terminated by the wrong char: */ ++/* a b c LRE‪ 1 2 3 PDI⁩ x y z */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c RLE‫ 1 2 3 PDI⁩ x y z*/ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c LRO‭ 1 2 3 PDI⁩ x y z */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c RLO‮ 1 2 3 PDI⁩ x y z */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c LRI⁦ 1 2 3 PDF‬ x y z */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c RLI⁧ 1 2 3 PDF‬ x y z */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* a b c FSI⁨ 1 2 3 PDF‬ x y z*/ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ ++/* LRE‪ PDF‬ */ ++/* LRE‪ LRE‪ PDF‬ PDF‬ */ ++/* PDF‬ LRE‪ PDF‬ */ ++/* LRE‪ PDF‬ LRE‪ PDF‬ */ ++/* LRE‪ LRE‪ PDF‬ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* PDF‬ LRE‪ */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ ++// a b c LRE‪ 1 2 3 PDI⁩ x y z ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// a b c RLE‫ 1 2 3 PDI⁩ x y z*/ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// a b c LRO‭ 1 2 3 PDI⁩ x y z ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// a b c RLO‮ 1 2 3 PDI⁩ x y z ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// a b c LRI⁦ 1 2 3 PDF‬ x y z ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// a b c RLI⁧ 1 2 3 PDF‬ x y z ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// a b c FSI⁨ 1 2 3 PDF‬ x y z ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ ++// LRE‪ PDF‬ ++// LRE‪ LRE‪ PDF‬ PDF‬ ++// PDF‬ LRE‪ PDF‬ ++// LRE‪ PDF‬ LRE‪ PDF‬ ++// LRE‪ LRE‪ PDF‬ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++// PDF‬ LRE‪ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ ++void ++g1 () ++{ ++ const char *s1 = "a b c LRE‪ 1 2 3 PDI⁩ x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s2 = "a b c LRE\u202a 1 2 3 PDI\u2069 x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s3 = "a b c RLE‫ 1 2 3 PDI⁩ x y "; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s4 = "a b c RLE\u202b 1 2 3 PDI\u2069 x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s5 = "a b c LRO‭ 1 2 3 PDI⁩ x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s6 = "a b c LRO\u202d 1 2 3 PDI\u2069 x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s7 = "a b c RLO‮ 1 2 3 PDI⁩ x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s8 = "a b c RLO\u202e 1 2 3 PDI\u2069 x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s9 = "a b c LRI⁦ 1 2 3 PDF‬ x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s10 = "a b c LRI\u2066 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s11 = "a b c RLI⁧ 1 2 3 PDF‬ x y z\ ++ "; ++/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */ ++ const char *s12 = "a b c RLI\u2067 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s13 = "a b c FSI⁨ 1 2 3 PDF‬ x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s14 = "a b c FSI\u2068 1 2 3 PDF\u202c x y z"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s15 = "PDF‬ LRE‪"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s16 = "PDF\u202c LRE\u202a"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s17 = "LRE‪ PDF‬"; ++ const char *s18 = "LRE\u202a PDF\u202c"; ++ const char *s19 = "LRE‪ LRE‪ PDF‬ PDF‬"; ++ const char *s20 = "LRE\u202a LRE\u202a PDF\u202c PDF\u202c"; ++ const char *s21 = "PDF‬ LRE‪ PDF‬"; ++ const char *s22 = "PDF\u202c LRE\u202a PDF\u202c"; ++ const char *s23 = "LRE‪ LRE‪ PDF‬"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s24 = "LRE\u202a LRE\u202a PDF\u202c"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s25 = "PDF‬ LRE‪"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s26 = "PDF\u202c LRE\u202a"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s27 = "PDF‬ LRE\u202a"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ const char *s28 = "PDF\u202c LRE‪"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++} ++ ++int A\u202aB\u2069C; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int a\u202bB\u2069c; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int a\u202db\u2069c2; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int a\u202eb\u2069; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int a\u2066b\u202c; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int a\u2067b\u202c; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int a\u2068b\u202c; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int A\u202aB\u202c; ++int A\u202aA\u202aB\u202cB\u202c; ++int a_\u202C_\u202a_\u202c; ++int a_\u202a_\u202c_\u202a_\u202c_; ++int a_\u202a_\u202c_\u202a_; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-7.c b/gcc/testsuite/c-c++-common/Wbidi-chars-7.c +new file mode 100644 +index 00000000000..d012d420ec0 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-7.c +@@ -0,0 +1,9 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=any" } */ ++/* Test we ignore UCNs in comments. */ ++ ++// a b c \u202a 1 2 3 ++// a b c \u202A 1 2 3 ++/* a b c \u202a 1 2 3 */ ++/* 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 +new file mode 100644 +index 00000000000..4f54c5092ec +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-8.c +@@ -0,0 +1,13 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=any" } */ ++/* Test \u vs \U. */ ++ ++int a_\u202A; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++int a_\u202a_2; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++int a_\U0000202A_3; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ ++int a_\U0000202a_4; ++/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */ +diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-9.c b/gcc/testsuite/c-c++-common/Wbidi-chars-9.c +new file mode 100644 +index 00000000000..e2af1b1ca97 +--- /dev/null ++++ b/gcc/testsuite/c-c++-common/Wbidi-chars-9.c +@@ -0,0 +1,29 @@ ++/* PR preprocessor/103026 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wbidi-chars=unpaired" } */ ++/* Test that we properly separate bidi contexts (comment/identifier/character ++ constant/string literal). */ ++ ++/* LRE ->‪<- */ int pdf_\u202c_1; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* RLE ->‫<- */ int pdf_\u202c_2; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* LRO ->‭<- */ int pdf_\u202c_3; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* RLO ->‮<- */ int pdf_\u202c_4; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* LRI ->⁦<-*/ int pdi_\u2069_1; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* RLI ->⁧<- */ int pdi_\u2069_12; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* FSI ->⁨<- */ int pdi_\u2069_3; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++ ++const char *s1 = "LRE\u202a"; /* PDF ->‬<- */ ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++/* LRE ->‪<- */ const char *s2 = "PDF\u202c"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++const char *s3 = "LRE\u202a"; int pdf_\u202c_5; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ ++int lre_\u202a; const char *s4 = "PDF\u202c"; ++/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */ +diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h +index 3ad52d5e01e..e0dcb7f0529 100644 +--- a/libcpp/include/cpplib.h ++++ b/libcpp/include/cpplib.h +@@ -305,6 +305,17 @@ enum cpp_normalize_level { + normalized_none + }; + ++/* The possible bidirectional control characters checking levels, from least ++ restrictive to most. */ ++enum cpp_bidirectional_level { ++ /* No checking. */ ++ bidirectional_none, ++ /* Only detect unpaired uses of bidirectional control characters. */ ++ bidirectional_unpaired, ++ /* Detect any use of bidirectional control characters. */ ++ bidirectional_any ++}; ++ + /* This structure is nested inside struct cpp_reader, and + carries all the options visible to the command line. */ + struct cpp_options +@@ -506,6 +517,10 @@ struct cpp_options + /* True if warn about differences between C++98 and C++11. */ + bool cpp_warn_cxx11_compat; + ++ /* Nonzero if bidirectional control characters checking is on. See enum ++ cpp_bidirectional_level. */ ++ unsigned char cpp_warn_bidirectional; ++ + /* Dependency generation. */ + struct + { +@@ -1063,7 +1078,8 @@ enum { + CPP_W_PEDANTIC, + CPP_W_C90_C99_COMPAT, + CPP_W_CXX11_COMPAT, +- CPP_W_EXPANSION_TO_DEFINED ++ CPP_W_EXPANSION_TO_DEFINED, ++ CPP_W_BIDIRECTIONAL + }; + + /* Output a diagnostic of some kind. */ +diff --git a/libcpp/init.c b/libcpp/init.c +index ca3fbaa5c05..5c15da82ff8 100644 +--- a/libcpp/init.c ++++ b/libcpp/init.c +@@ -208,6 +208,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, + = ENABLE_CANONICAL_SYSTEM_HEADERS; + CPP_OPTION (pfile, ext_numeric_literals) = 1; + CPP_OPTION (pfile, warn_date_time) = 0; ++ CPP_OPTION (pfile, cpp_warn_bidirectional) = bidirectional_unpaired; + + /* Default CPP arithmetic to something sensible for the host for the + benefit of dumb users like fix-header. */ +diff --git a/libcpp/internal.h b/libcpp/internal.h +index 4f74f995cec..53b4c0f4af7 100644 +--- a/libcpp/internal.h ++++ b/libcpp/internal.h +@@ -576,6 +576,13 @@ struct cpp_reader + /* If non-null, the lexer will use this location for the next token + instead of getting a location from the linemap. */ + source_location *forced_token_location_p; ++ ++ /* Returns true iff we should warn about UTF-8 bidirectional control ++ characters. */ ++ bool warn_bidi_p () const ++ { ++ return CPP_OPTION (this, cpp_warn_bidirectional) != bidirectional_none; ++ } + }; + + /* Character classes. Based on the more primitive macros in safe-ctype.h. +diff --git a/libcpp/lex.c b/libcpp/lex.c +index a408f912c5c..ea7f75e842e 100644 +--- a/libcpp/lex.c ++++ b/libcpp/lex.c +@@ -1164,6 +1164,324 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment) + } + } + ++namespace bidi { ++ enum kind { ++ NONE, LRE, RLE, LRO, RLO, LRI, RLI, FSI, PDF, PDI, LTR, RTL ++ }; ++ ++ /* All the UTF-8 encodings of bidi characters start with E2. */ ++ const uchar utf8_start = 0xe2; ++ ++ /* A vector holding currently open bidi contexts. We use a char for ++ each context, its LSB is 1 if it represents a PDF context, 0 if it ++ represents a PDI context. The next bit is 1 if this context was open ++ by a bidi character written as a UCN, and 0 when it was UTF-8. */ ++ semi_embedded_vec vec; ++ ++ /* Close the whole comment/identifier/string literal/character constant ++ context. */ ++ void on_close () ++ { ++ vec.truncate (0); ++ } ++ ++ /* Pop the last element in the vector. */ ++ void pop () ++ { ++ unsigned int len = vec.count (); ++ gcc_checking_assert (len > 0); ++ vec.truncate (len - 1); ++ } ++ ++ /* Return the context of the Ith element. */ ++ kind ctx_at (unsigned int i) ++ { ++ return (vec[i] & 1) ? PDF : PDI; ++ } ++ ++ /* Return which context is currently opened. */ ++ kind current_ctx () ++ { ++ unsigned int len = vec.count (); ++ if (len == 0) ++ return NONE; ++ return ctx_at (len - 1); ++ } ++ ++ /* Return true if the current context comes from a UCN origin, that is, ++ the bidi char which started this bidi context was written as a UCN. */ ++ bool current_ctx_ucn_p () ++ { ++ unsigned int len = vec.count (); ++ gcc_checking_assert (len > 0); ++ return (vec[len - 1] >> 1) & 1; ++ } ++ ++ /* We've read a bidi char, update the current vector as necessary. */ ++ void on_char (kind k, bool ucn_p) ++ { ++ switch (k) ++ { ++ case LRE: ++ case RLE: ++ case LRO: ++ case RLO: ++ vec.push (ucn_p ? 3u : 1u); ++ break; ++ case LRI: ++ case RLI: ++ case FSI: ++ vec.push (ucn_p ? 2u : 0u); ++ break; ++ /* PDF terminates the scope of the last LRE, RLE, LRO, or RLO ++ whose scope has not yet been terminated. */ ++ case PDF: ++ if (current_ctx () == PDF) ++ pop (); ++ break; ++ /* PDI terminates the scope of the last LRI, RLI, or FSI whose ++ scope has not yet been terminated, as well as the scopes of ++ any subsequent LREs, RLEs, LROs, or RLOs whose scopes have not ++ yet been terminated. */ ++ case PDI: ++ for (int i = vec.count () - 1; i >= 0; --i) ++ if (ctx_at (i) == PDI) ++ { ++ vec.truncate (i); ++ break; ++ } ++ break; ++ case LTR: ++ case RTL: ++ /* These aren't popped by a PDF/PDI. */ ++ break; ++ [[likely]] case NONE: ++ break; ++ default: ++ abort (); ++ } ++ } ++ ++ /* Return a descriptive string for K. */ ++ const char *to_str (kind k) ++ { ++ switch (k) ++ { ++ case LRE: ++ return "U+202A (LEFT-TO-RIGHT EMBEDDING)"; ++ case RLE: ++ return "U+202B (RIGHT-TO-LEFT EMBEDDING)"; ++ case LRO: ++ return "U+202D (LEFT-TO-RIGHT OVERRIDE)"; ++ case RLO: ++ return "U+202E (RIGHT-TO-LEFT OVERRIDE)"; ++ case LRI: ++ return "U+2066 (LEFT-TO-RIGHT ISOLATE)"; ++ case RLI: ++ return "U+2067 (RIGHT-TO-LEFT ISOLATE)"; ++ case FSI: ++ return "U+2068 (FIRST STRONG ISOLATE)"; ++ case PDF: ++ return "U+202C (POP DIRECTIONAL FORMATTING)"; ++ case PDI: ++ return "U+2069 (POP DIRECTIONAL ISOLATE)"; ++ case LTR: ++ return "U+200E (LEFT-TO-RIGHT MARK)"; ++ case RTL: ++ return "U+200F (RIGHT-TO-LEFT MARK)"; ++ default: ++ abort (); ++ } ++ } ++} ++ ++/* Parse a sequence of 3 bytes starting with P and return its bidi code. */ ++ ++static bidi::kind ++get_bidi_utf8 (const unsigned char *const p) ++{ ++ gcc_checking_assert (p[0] == bidi::utf8_start); ++ ++ if (p[1] == 0x80) ++ switch (p[2]) ++ { ++ case 0xaa: ++ return bidi::LRE; ++ case 0xab: ++ return bidi::RLE; ++ case 0xac: ++ return bidi::PDF; ++ case 0xad: ++ return bidi::LRO; ++ case 0xae: ++ return bidi::RLO; ++ case 0x8e: ++ return bidi::LTR; ++ case 0x8f: ++ return bidi::RTL; ++ default: ++ break; ++ } ++ else if (p[1] == 0x81) ++ switch (p[2]) ++ { ++ case 0xa6: ++ return bidi::LRI; ++ case 0xa7: ++ return bidi::RLI; ++ case 0xa8: ++ return bidi::FSI; ++ case 0xa9: ++ return bidi::PDI; ++ default: ++ break; ++ } ++ ++ return bidi::NONE; ++} ++ ++/* Parse a UCN where P points just past \u or \U and return its bidi code. */ ++ ++static bidi::kind ++get_bidi_ucn (const unsigned char *p, bool is_U) ++{ ++ /* 6.4.3 Universal Character Names ++ \u hex-quad ++ \U hex-quad hex-quad ++ where \unnnn means \U0000nnnn. */ ++ ++ if (is_U) ++ { ++ if (p[0] != '0' || p[1] != '0' || p[2] != '0' || p[3] != '0') ++ return bidi::NONE; ++ /* Skip 4B so we can treat \u and \U the same below. */ ++ p += 4; ++ } ++ ++ /* All code points we are looking for start with 20xx. */ ++ if (p[0] != '2' || p[1] != '0') ++ return bidi::NONE; ++ else if (p[2] == '2') ++ switch (p[3]) ++ { ++ case 'a': ++ case 'A': ++ return bidi::LRE; ++ case 'b': ++ case 'B': ++ return bidi::RLE; ++ case 'c': ++ case 'C': ++ return bidi::PDF; ++ case 'd': ++ case 'D': ++ return bidi::LRO; ++ case 'e': ++ case 'E': ++ return bidi::RLO; ++ default: ++ break; ++ } ++ else if (p[2] == '6') ++ switch (p[3]) ++ { ++ case '6': ++ return bidi::LRI; ++ case '7': ++ return bidi::RLI; ++ case '8': ++ return bidi::FSI; ++ case '9': ++ return bidi::PDI; ++ default: ++ break; ++ } ++ else if (p[2] == '0') ++ switch (p[3]) ++ { ++ case 'e': ++ case 'E': ++ return bidi::LTR; ++ case 'f': ++ case 'F': ++ return bidi::RTL; ++ default: ++ break; ++ } ++ ++ return bidi::NONE; ++} ++ ++/* We're closing a bidi context, that is, we've encountered a newline, ++ are closing a C-style comment, or are at the end of a string literal, ++ character constant, or identifier. Warn if this context was not ++ properly terminated by a PDI or PDF. P points to the last character ++ in this context. */ ++ ++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 source_location loc ++ = linemap_position_for_column (pfile->line_table, ++ CPP_BUF_COLUMN (pfile->buffer, p)); ++ cpp_warning_with_line (pfile, CPP_W_BIDIRECTIONAL, loc, 0, ++ "unpaired UTF-8 bidirectional control character " ++ "detected"); ++ } ++ /* We're done with this context. */ ++ bidi::on_close (); ++} ++ ++/* We're at the beginning or in the middle of an identifier/comment/string ++ literal/character constant. Warn if we've encountered a bidi character. ++ KIND says which bidi character it was; P points to it in the character ++ stream. UCN_P is true iff this bidi character was written as a UCN. */ ++ ++static void ++maybe_warn_bidi_on_char (cpp_reader *pfile, const uchar *p, bidi::kind kind, ++ bool ucn_p) ++{ ++ if (__builtin_expect (kind == bidi::NONE, 1)) ++ return; ++ ++ const unsigned char warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional); ++ ++ if (warn_bidi != bidirectional_none) ++ { ++ const source_location loc ++ = linemap_position_for_column (pfile->line_table, ++ CPP_BUF_COLUMN (pfile->buffer, p)); ++ /* 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. */ ++ if (kind == bidi::current_ctx ()) ++ { ++ if (warn_bidi == bidirectional_unpaired ++ && bidi::current_ctx_ucn_p () != ucn_p) ++ cpp_warning_with_line (pfile, CPP_W_BIDIRECTIONAL, loc, 0, ++ "UTF-8 vs UCN mismatch when closing " ++ "a context by \"%s\"", bidi::to_str (kind)); ++ } ++ else if (warn_bidi == bidirectional_any) ++ { ++ if (kind == bidi::PDF || kind == bidi::PDI) ++ cpp_warning_with_line (pfile, CPP_W_BIDIRECTIONAL, loc, 0, ++ "\"%s\" is closing an unopened context", ++ bidi::to_str (kind)); ++ else ++ cpp_warning_with_line (pfile, CPP_W_BIDIRECTIONAL, loc, 0, ++ "found problematic Unicode character \"%s\"", ++ bidi::to_str (kind)); ++ } ++ } ++ /* We're done with this context. */ ++ bidi::on_char (kind, ucn_p); ++} ++ + /* Skip a C-style block comment. We find the end of the comment by + seeing if an asterisk is before every '/' we encounter. Returns + nonzero if comment terminated by EOF, zero otherwise. +@@ -1175,6 +1493,7 @@ _cpp_skip_block_comment (cpp_reader *pfile) + cpp_buffer *buffer = pfile->buffer; + const uchar *cur = buffer->cur; + uchar c; ++ const bool warn_bidi_p = pfile->warn_bidi_p (); + + cur++; + if (*cur == '/') +@@ -1189,7 +1508,11 @@ _cpp_skip_block_comment (cpp_reader *pfile) + if (c == '/') + { + if (cur[-2] == '*') +- break; ++ { ++ if (warn_bidi_p) ++ maybe_warn_bidi_on_close (pfile, cur); ++ break; ++ } + + /* Warn about potential nested comments, but not if the '/' + comes immediately before the true comment delimiter. +@@ -1208,6 +1531,8 @@ _cpp_skip_block_comment (cpp_reader *pfile) + { + unsigned int cols; + buffer->cur = cur - 1; ++ if (warn_bidi_p) ++ maybe_warn_bidi_on_close (pfile, cur); + _cpp_process_line_notes (pfile, true); + if (buffer->next_line >= buffer->rlimit) + return true; +@@ -1218,6 +1543,13 @@ _cpp_skip_block_comment (cpp_reader *pfile) + + cur = buffer->cur; + } ++ /* If this is a beginning of a UTF-8 encoding, it might be ++ a bidirectional control character. */ ++ else if (__builtin_expect (c == bidi::utf8_start, 0) && warn_bidi_p) ++ { ++ bidi::kind kind = get_bidi_utf8 (cur - 1); ++ maybe_warn_bidi_on_char (pfile, cur, kind, /*ucn_p=*/false); ++ } + } + + buffer->cur = cur; +@@ -1233,9 +1565,31 @@ skip_line_comment (cpp_reader *pfile) + { + cpp_buffer *buffer = pfile->buffer; + source_location orig_line = pfile->line_table->highest_line; ++ const bool warn_bidi_p = pfile->warn_bidi_p (); + +- while (*buffer->cur != '\n') +- buffer->cur++; ++ if (!warn_bidi_p) ++ while (*buffer->cur != '\n') ++ buffer->cur++; ++ else ++ { ++ while (*buffer->cur != '\n' ++ && *buffer->cur != bidi::utf8_start) ++ buffer->cur++; ++ if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0)) ++ { ++ while (*buffer->cur != '\n') ++ { ++ if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0)) ++ { ++ bidi::kind kind = get_bidi_utf8 (buffer->cur); ++ maybe_warn_bidi_on_char (pfile, buffer->cur, kind, ++ /*ucn_p=*/false); ++ } ++ buffer->cur++; ++ } ++ maybe_warn_bidi_on_close (pfile, buffer->cur); ++ } ++ } + + _cpp_process_line_notes (pfile, true); + return orig_line != pfile->line_table->highest_line; +@@ -1315,11 +1669,13 @@ warn_about_normalization (cpp_reader *pfile, + + /* Returns TRUE if the sequence starting at buffer->cur is invalid in + an identifier. FIRST is TRUE if this starts an identifier. */ ++ + static bool + forms_identifier_p (cpp_reader *pfile, int first, + struct normalize_state *state) + { + cpp_buffer *buffer = pfile->buffer; ++ const bool warn_bidi_p = pfile->warn_bidi_p (); + + if (*buffer->cur == '$') + { +@@ -1343,6 +1699,12 @@ forms_identifier_p (cpp_reader *pfile, int first, + { + cppchar_t s; + buffer->cur += 2; ++ if (warn_bidi_p) ++ { ++ bidi::kind kind = get_bidi_ucn (buffer->cur, ++ buffer->cur[-1] == 'U'); ++ maybe_warn_bidi_on_char (pfile, buffer->cur, kind, /*ucn_p=*/true); ++ } + if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first, + state, &s, NULL, NULL)) + return true; +@@ -1450,6 +1812,7 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, + const uchar *cur; + unsigned int len; + unsigned int hash = HT_HASHSTEP (0, *base); ++ const bool warn_bidi_p = pfile->warn_bidi_p (); + + cur = pfile->buffer->cur; + if (! starts_ucn) +@@ -1472,6 +1835,8 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, + pfile->buffer->cur++; + } + } while (forms_identifier_p (pfile, false, nst)); ++ if (warn_bidi_p) ++ maybe_warn_bidi_on_close (pfile, pfile->buffer->cur); + result = _cpp_interpret_identifier (pfile, base, + pfile->buffer->cur - base); + *spelling = cpp_lookup (pfile, base, pfile->buffer->cur - base); +@@ -1673,6 +2038,7 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base, + _cpp_buff *first_buff = NULL, *last_buff = NULL; + size_t raw_prefix_start; + _cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note]; ++ const bool warn_bidi_p = pfile->warn_bidi_p (); + + type = (*base == 'L' ? CPP_WSTRING : + *base == 'U' ? CPP_STRING32 : +@@ -1909,8 +2275,15 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base, + cur = base = pfile->buffer->cur; + note = &pfile->buffer->notes[pfile->buffer->cur_note]; + } ++ else if (__builtin_expect ((unsigned char) c == bidi::utf8_start, 0) ++ && warn_bidi_p) ++ maybe_warn_bidi_on_char (pfile, cur - 1, get_bidi_utf8 (cur - 1), ++ /*ucn_p=*/false); + } + ++ if (warn_bidi_p) ++ maybe_warn_bidi_on_close (pfile, cur); ++ + if (CPP_OPTION (pfile, user_literals)) + { + /* If a string format macro, say from inttypes.h, is placed touching +@@ -2005,15 +2378,27 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) + else + terminator = '>', type = CPP_HEADER_NAME; + ++ const bool warn_bidi_p = pfile->warn_bidi_p (); + for (;;) + { + cppchar_t c = *cur++; + + /* In #include-style directives, terminators are not escapable. */ + if (c == '\\' && !pfile->state.angled_headers && *cur != '\n') +- cur++; ++ { ++ if ((cur[0] == 'u' || cur[0] == 'U') && warn_bidi_p) ++ { ++ bidi::kind kind = get_bidi_ucn (cur + 1, cur[0] == 'U'); ++ maybe_warn_bidi_on_char (pfile, cur, kind, /*ucn_p=*/true); ++ } ++ cur++; ++ } + else if (c == terminator) +- break; ++ { ++ if (warn_bidi_p) ++ maybe_warn_bidi_on_close (pfile, cur - 1); ++ break; ++ } + else if (c == '\n') + { + cur--; +@@ -2030,6 +2415,11 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) + } + else if (c == '\0') + saw_NUL = true; ++ else if (__builtin_expect (c == bidi::utf8_start, 0) && warn_bidi_p) ++ { ++ bidi::kind kind = get_bidi_utf8 (cur - 1); ++ maybe_warn_bidi_on_char (pfile, cur - 1, kind, /*ucn_p=*/false); ++ } + } + + if (saw_NUL && !pfile->state.skipping) diff --git a/SOURCES/gcc8-Wno-format-security.patch b/SOURCES/gcc8-Wno-format-security.patch new file mode 100644 index 0000000..cb21e5d --- /dev/null +++ b/SOURCES/gcc8-Wno-format-security.patch @@ -0,0 +1,27 @@ +2017-02-25 Jakub Jelinek + + * configure.ac: When adding -Wno-format, also add -Wno-format-security. + * configure: Regenerated. + +--- gcc/configure.ac.jj 2017-02-13 12:20:53.000000000 +0100 ++++ gcc/configure.ac 2017-02-25 12:42:32.859175403 +0100 +@@ -481,7 +481,7 @@ AC_ARG_ENABLE(build-format-warnings, + AS_HELP_STRING([--disable-build-format-warnings],[don't use -Wformat while building GCC]), + [],[enable_build_format_warnings=yes]) + AS_IF([test $enable_build_format_warnings = no], +- [wf_opt=-Wno-format],[wf_opt=]) ++ [wf_opt="-Wno-format -Wno-format-security"],[wf_opt=]) + ACX_PROG_CXX_WARNING_OPTS( + m4_quote(m4_do([-W -Wall -Wno-narrowing -Wwrite-strings ], + [-Wcast-qual $wf_opt])), [loose_warn]) +--- gcc/configure.jj 2017-02-13 12:20:52.000000000 +0100 ++++ gcc/configure 2017-02-25 12:42:50.041946391 +0100 +@@ -6647,7 +6647,7 @@ else + fi + + if test $enable_build_format_warnings = no; then : +- wf_opt=-Wno-format ++ wf_opt="-Wno-format -Wno-format-security" + else + wf_opt= + fi diff --git a/SOURCES/gcc8-foffload-default.patch b/SOURCES/gcc8-foffload-default.patch new file mode 100644 index 0000000..771e1e0 --- /dev/null +++ b/SOURCES/gcc8-foffload-default.patch @@ -0,0 +1,117 @@ +2017-01-20 Jakub Jelinek + + * gcc.c (offload_targets_default): New variable. + (process_command): Set it if -foffload is defaulted. + (driver::maybe_putenv_OFFLOAD_TARGETS): Add OFFLOAD_TARGET_DEFAULT=1 + into environment if -foffload has been defaulted. + * lto-wrapper.c (OFFLOAD_TARGET_DEFAULT_ENV): Define. + (compile_images_for_offload_targets): If OFFLOAD_TARGET_DEFAULT + is in the environment, don't fail if corresponding mkoffload + can't be found. Free and clear offload_names if no valid offload + is found. +libgomp/ + * target.c (gomp_load_plugin_for_device): If a plugin can't be + dlopened, assume it has no devices silently. + +--- gcc/gcc.c.jj 2017-01-17 10:28:40.000000000 +0100 ++++ gcc/gcc.c 2017-01-20 16:26:29.649962902 +0100 +@@ -290,6 +290,10 @@ static const char *spec_host_machine = D + + static char *offload_targets = NULL; + ++/* Set to true if -foffload has not been used and offload_targets ++ is set to the configured in default. */ ++static bool offload_targets_default; ++ + /* Nonzero if cross-compiling. + When -b is used, the value comes from the `specs' file. */ + +@@ -4457,7 +4461,10 @@ process_command (unsigned int decoded_op + /* If the user didn't specify any, default to all configured offload + targets. */ + if (ENABLE_OFFLOADING && offload_targets == NULL) +- handle_foffload_option (OFFLOAD_TARGETS); ++ { ++ handle_foffload_option (OFFLOAD_TARGETS); ++ offload_targets_default = true; ++ } + + if (output_file + && strcmp (output_file, "-") != 0 +@@ -7693,6 +7700,8 @@ driver::maybe_putenv_OFFLOAD_TARGETS () + obstack_grow (&collect_obstack, offload_targets, + strlen (offload_targets) + 1); + xputenv (XOBFINISH (&collect_obstack, char *)); ++ if (offload_targets_default) ++ xputenv ("OFFLOAD_TARGET_DEFAULT=1"); + } + + free (offload_targets); +--- gcc/lto-wrapper.c.jj 2017-01-01 12:45:34.000000000 +0100 ++++ gcc/lto-wrapper.c 2017-01-20 16:34:18.294016997 +0100 +@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. + /* Environment variable, used for passing the names of offload targets from GCC + driver to lto-wrapper. */ + #define OFFLOAD_TARGET_NAMES_ENV "OFFLOAD_TARGET_NAMES" ++#define OFFLOAD_TARGET_DEFAULT_ENV "OFFLOAD_TARGET_DEFAULT" + + enum lto_mode_d { + LTO_MODE_NONE, /* Not doing LTO. */ +@@ -790,8 +791,10 @@ compile_images_for_offload_targets (unsi + if (!target_names) + return; + unsigned num_targets = parse_env_var (target_names, &names, NULL); ++ const char *target_names_default = getenv (OFFLOAD_TARGET_DEFAULT_ENV); + + int next_name_entry = 0; ++ bool hsa_seen = false; + const char *compiler_path = getenv ("COMPILER_PATH"); + if (!compiler_path) + goto out; +@@ -804,18 +807,32 @@ compile_images_for_offload_targets (unsi + /* HSA does not use LTO-like streaming and a different compiler, skip + it. */ + if (strcmp (names[i], "hsa") == 0) +- continue; ++ { ++ hsa_seen = true; ++ continue; ++ } + + offload_names[next_name_entry] + = compile_offload_image (names[i], compiler_path, in_argc, in_argv, + compiler_opts, compiler_opt_count, + linker_opts, linker_opt_count); + if (!offload_names[next_name_entry]) +- fatal_error (input_location, +- "problem with building target image for %s\n", names[i]); ++ { ++ if (target_names_default != NULL) ++ continue; ++ fatal_error (input_location, ++ "problem with building target image for %s\n", ++ names[i]); ++ } + next_name_entry++; + } + ++ if (next_name_entry == 0 && !hsa_seen) ++ { ++ free (offload_names); ++ offload_names = NULL; ++ } ++ + out: + free_array_of_ptrs ((void **) names, num_targets); + } +--- libgomp/target.c.jj 2017-01-01 12:45:52.000000000 +0100 ++++ libgomp/target.c 2017-01-20 20:12:13.756710875 +0100 +@@ -2356,7 +2356,7 @@ gomp_load_plugin_for_device (struct gomp + + void *plugin_handle = dlopen (plugin_name, RTLD_LAZY); + if (!plugin_handle) +- goto dl_fail; ++ return 0; + + /* Check if all required functions are available in the plugin and store + their handlers. None of the symbols can legitimately be NULL, diff --git a/SOURCES/gcc8-hack.patch b/SOURCES/gcc8-hack.patch new file mode 100644 index 0000000..515173f --- /dev/null +++ b/SOURCES/gcc8-hack.patch @@ -0,0 +1,124 @@ +--- libada/Makefile.in.jj 2009-01-14 12:07:35.000000000 +0100 ++++ libada/Makefile.in 2009-01-15 14:25:33.000000000 +0100 +@@ -66,18 +66,40 @@ libsubdir := $(libdir)/gcc/$(target_nonc + ADA_RTS_DIR=$(GCC_DIR)/ada/rts$(subst /,_,$(MULTISUBDIR)) + ADA_RTS_SUBDIR=./rts$(subst /,_,$(MULTISUBDIR)) + ++DEFAULTMULTIFLAGS := ++ifeq ($(MULTISUBDIR),) ++targ:=$(subst -, ,$(target)) ++arch:=$(word 1,$(targ)) ++ifeq ($(words $(targ)),2) ++osys:=$(word 2,$(targ)) ++else ++osys:=$(word 3,$(targ)) ++endif ++ifeq ($(strip $(filter-out i%86 x86_64 powerpc% ppc% s390% sparc% linux%, $(arch) $(osys))),) ++ifeq ($(shell $(CC) $(CFLAGS) -print-multi-os-directory),../lib64) ++DEFAULTMULTIFLAGS := -m64 ++else ++ifeq ($(strip $(filter-out s390%, $(arch))),) ++DEFAULTMULTIFLAGS := -m31 ++else ++DEFAULTMULTIFLAGS := -m32 ++endif ++endif ++endif ++endif ++ + # exeext should not be used because it's the *host* exeext. We're building + # a *target* library, aren't we?!? Likewise for CC. Still, provide bogus + # definitions just in case something slips through the safety net provided + # by recursive make invocations in gcc/ada/Makefile.in + LIBADA_FLAGS_TO_PASS = \ + "MAKEOVERRIDES=" \ +- "LDFLAGS=$(LDFLAGS)" \ ++ "LDFLAGS=$(LDFLAGS) $(DEFAULTMULTIFLAGS)" \ + "LN_S=$(LN_S)" \ + "SHELL=$(SHELL)" \ +- "GNATLIBFLAGS=$(GNATLIBFLAGS) $(MULTIFLAGS)" \ +- "GNATLIBCFLAGS=$(GNATLIBCFLAGS) $(MULTIFLAGS)" \ +- "GNATLIBCFLAGS_FOR_C=$(GNATLIBCFLAGS_FOR_C) $(MULTIFLAGS)" \ ++ "GNATLIBFLAGS=$(GNATLIBFLAGS) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \ ++ "GNATLIBCFLAGS=$(GNATLIBCFLAGS) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \ ++ "GNATLIBCFLAGS_FOR_C=$(GNATLIBCFLAGS_FOR_C) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \ + "PICFLAG_FOR_TARGET=$(PICFLAG)" \ + "THREAD_KIND=$(THREAD_KIND)" \ + "TRACE=$(TRACE)" \ +@@ -88,7 +110,7 @@ LIBADA_FLAGS_TO_PASS = \ + "exeext=.exeext.should.not.be.used " \ + 'CC=the.host.compiler.should.not.be.needed' \ + "GCC_FOR_TARGET=$(CC)" \ +- "CFLAGS=$(CFLAGS)" ++ "CFLAGS=$(CFLAGS) $(DEFAULTMULTIFLAGS)" + + # Rules to build gnatlib. + .PHONY: gnatlib gnatlib-plain gnatlib-sjlj gnatlib-zcx gnatlib-shared osconstool +--- config-ml.in.jj 2010-06-30 09:50:44.000000000 +0200 ++++ config-ml.in 2010-07-02 21:24:17.994211151 +0200 +@@ -511,6 +511,8 @@ multi-do: + ADAFLAGS="$(ADAFLAGS) $${flags}" \ + prefix="$(prefix)" \ + exec_prefix="$(exec_prefix)" \ ++ mandir="$(mandir)" \ ++ infodir="$(infodir)" \ + GOCFLAGS="$(GOCFLAGS) $${flags}" \ + CXXFLAGS="$(CXXFLAGS) $${flags}" \ + LIBCFLAGS="$(LIBCFLAGS) $${flags}" \ +--- libcpp/macro.c.jj 2015-01-14 11:01:34.000000000 +0100 ++++ libcpp/macro.c 2015-01-14 14:22:19.286949884 +0100 +@@ -2947,8 +2947,6 @@ create_iso_definition (cpp_reader *pfile + cpp_token *token; + const cpp_token *ctoken; + bool following_paste_op = false; +- const char *paste_op_error_msg = +- N_("'##' cannot appear at either end of a macro expansion"); + unsigned int num_extra_tokens = 0; + + /* Get the first token of the expansion (or the '(' of a +@@ -3059,7 +3057,8 @@ create_iso_definition (cpp_reader *pfile + function-like macros, but not at the end. */ + if (following_paste_op) + { +- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); ++ cpp_error (pfile, CPP_DL_ERROR, ++ "'##' cannot appear at either end of a macro expansion"); + return false; + } + break; +@@ -3072,7 +3071,8 @@ create_iso_definition (cpp_reader *pfile + function-like macros, but not at the beginning. */ + if (macro->count == 1) + { +- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); ++ cpp_error (pfile, CPP_DL_ERROR, ++ "'##' cannot appear at either end of a macro expansion"); + return false; + } + +--- libcpp/expr.c.jj 2015-01-14 11:01:34.000000000 +0100 ++++ libcpp/expr.c 2015-01-14 14:35:52.851002344 +0100 +@@ -672,16 +672,17 @@ cpp_classify_number (cpp_reader *pfile, + if ((result & CPP_N_WIDTH) == CPP_N_LARGE + && CPP_OPTION (pfile, cpp_warn_long_long)) + { +- const char *message = CPP_OPTION (pfile, cplusplus) +- ? N_("use of C++11 long long integer constant") +- : N_("use of C99 long long integer constant"); +- + if (CPP_OPTION (pfile, c99)) + cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location, +- 0, message); ++ 0, CPP_OPTION (pfile, cplusplus) ++ ? N_("use of C++11 long long integer constant") ++ : N_("use of C99 long long integer constant")); + else + cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG, +- virtual_location, 0, message); ++ virtual_location, 0, ++ CPP_OPTION (pfile, cplusplus) ++ ? N_("use of C++11 long long integer constant") ++ : N_("use of C99 long long integer constant")); + } + + result |= CPP_N_INTEGER; diff --git a/SOURCES/gcc8-i386-libgomp.patch b/SOURCES/gcc8-i386-libgomp.patch new file mode 100644 index 0000000..520561e --- /dev/null +++ b/SOURCES/gcc8-i386-libgomp.patch @@ -0,0 +1,11 @@ +--- libgomp/configure.tgt.jj 2008-01-10 20:53:48.000000000 +0100 ++++ libgomp/configure.tgt 2008-03-27 12:44:51.000000000 +0100 +@@ -67,7 +67,7 @@ if test $enable_linux_futex = yes; then + ;; + *) + if test -z "$with_arch"; then +- XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}" ++ XCFLAGS="${XCFLAGS} -march=i486 -mtune=generic" + fi + esac + ;; diff --git a/SOURCES/gcc8-isl-dl.patch b/SOURCES/gcc8-isl-dl.patch new file mode 100644 index 0000000..46d3b0d --- /dev/null +++ b/SOURCES/gcc8-isl-dl.patch @@ -0,0 +1,715 @@ +--- gcc/Makefile.in.jj 2015-06-06 10:00:25.000000000 +0200 ++++ gcc/Makefile.in 2015-11-04 14:56:02.643536437 +0100 +@@ -1046,7 +1046,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY) + # and the system's installed libraries. + LIBS = @LIBS@ libcommon.a $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBBACKTRACE) \ + $(LIBIBERTY) $(LIBDECNUMBER) $(HOST_LIBS) +-BACKENDLIBS = $(ISLLIBS) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \ ++BACKENDLIBS = $(if $(ISLLIBS),-ldl) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \ + $(ZLIB) + # Any system libraries needed just for GNAT. + SYSLIBS = @GNAT_LIBEXC@ +@@ -2196,6 +2196,15 @@ $(out_object_file): $(out_file) + $(common_out_object_file): $(common_out_file) + $(COMPILE) $< + $(POSTCOMPILE) ++ ++graphite%.o : \ ++ ALL_CFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CFLAGS)) ++graphite.o : \ ++ ALL_CFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CFLAGS)) ++graphite%.o : \ ++ ALL_CXXFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CXXFLAGS)) ++graphite.o : \ ++ ALL_CXXFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CXXFLAGS)) + # + # Generate header and source files from the machine description, + # and compile them. +--- gcc/graphite.h.jj 2016-01-27 12:44:06.000000000 +0100 ++++ gcc/graphite.h 2016-01-27 13:26:38.309876856 +0100 +@@ -39,6 +39,590 @@ along with GCC; see the file COPYING3. + #include + #include + #include ++#include ++#include ++ ++#define DYNSYMS \ ++ DYNSYM (isl_aff_add_coefficient_si); \ ++ DYNSYM (isl_aff_free); \ ++ DYNSYM (isl_aff_get_space); \ ++ DYNSYM (isl_aff_set_coefficient_si); \ ++ DYNSYM (isl_aff_set_constant_si); \ ++ DYNSYM (isl_aff_zero_on_domain); \ ++ DYNSYM (isl_band_free); \ ++ DYNSYM (isl_band_get_children); \ ++ DYNSYM (isl_band_get_partial_schedule); \ ++ DYNSYM (isl_band_has_children); \ ++ DYNSYM (isl_band_list_free); \ ++ DYNSYM (isl_band_list_get_band); \ ++ DYNSYM (isl_band_list_get_ctx); \ ++ DYNSYM (isl_band_list_n_band); \ ++ DYNSYM (isl_band_n_member); \ ++ DYNSYM (isl_basic_map_add_constraint); \ ++ DYNSYM (isl_basic_map_project_out); \ ++ DYNSYM (isl_basic_map_universe); \ ++ DYNSYM (isl_constraint_set_coefficient_si); \ ++ DYNSYM (isl_constraint_set_constant_si); \ ++ DYNSYM (isl_ctx_alloc); \ ++ DYNSYM (isl_ctx_free); \ ++ DYNSYM (isl_equality_alloc); \ ++ DYNSYM (isl_id_alloc); \ ++ DYNSYM (isl_id_copy); \ ++ DYNSYM (isl_id_free); \ ++ DYNSYM (isl_inequality_alloc); \ ++ DYNSYM (isl_local_space_copy); \ ++ DYNSYM (isl_local_space_free); \ ++ DYNSYM (isl_local_space_from_space); \ ++ DYNSYM (isl_local_space_range); \ ++ DYNSYM (isl_map_add_constraint); \ ++ DYNSYM (isl_map_add_dims); \ ++ DYNSYM (isl_map_align_params); \ ++ DYNSYM (isl_map_apply_range); \ ++ DYNSYM (isl_map_copy); \ ++ DYNSYM (isl_map_dim); \ ++ DYNSYM (isl_map_dump); \ ++ DYNSYM (isl_map_equate); \ ++ DYNSYM (isl_map_fix_si); \ ++ DYNSYM (isl_map_flat_product); \ ++ DYNSYM (isl_map_flat_range_product); \ ++ DYNSYM (isl_map_free); \ ++ DYNSYM (isl_map_from_basic_map); \ ++ DYNSYM (isl_map_from_pw_aff); \ ++ DYNSYM (isl_map_from_union_map); \ ++ DYNSYM (isl_map_get_ctx); \ ++ DYNSYM (isl_map_get_space); \ ++ DYNSYM (isl_map_get_tuple_id); \ ++ DYNSYM (isl_map_insert_dims); \ ++ DYNSYM (isl_map_intersect); \ ++ DYNSYM (isl_map_intersect_domain); \ ++ DYNSYM (isl_map_intersect_range); \ ++ DYNSYM (isl_map_is_empty); \ ++ DYNSYM (isl_map_lex_ge); \ ++ DYNSYM (isl_map_lex_le); \ ++ DYNSYM (isl_map_n_out); \ ++ DYNSYM (isl_map_range); \ ++ DYNSYM (isl_map_set_tuple_id); \ ++ DYNSYM (isl_map_universe); \ ++ DYNSYM (isl_options_set_on_error); \ ++ DYNSYM (isl_options_set_schedule_serialize_sccs); \ ++ DYNSYM (isl_printer_set_yaml_style); \ ++ DYNSYM (isl_options_set_schedule_max_constant_term); \ ++ DYNSYM (isl_options_set_schedule_maximize_band_depth); \ ++ DYNSYM (isl_printer_free); \ ++ DYNSYM (isl_printer_print_aff); \ ++ DYNSYM (isl_printer_print_constraint); \ ++ DYNSYM (isl_printer_print_map); \ ++ DYNSYM (isl_printer_print_set); \ ++ DYNSYM (isl_printer_to_file); \ ++ DYNSYM (isl_pw_aff_add); \ ++ DYNSYM (isl_pw_aff_alloc); \ ++ DYNSYM (isl_pw_aff_copy); \ ++ DYNSYM (isl_pw_aff_eq_set); \ ++ DYNSYM (isl_pw_aff_free); \ ++ DYNSYM (isl_pw_aff_from_aff); \ ++ DYNSYM (isl_pw_aff_ge_set); \ ++ DYNSYM (isl_pw_aff_gt_set); \ ++ DYNSYM (isl_pw_aff_is_cst); \ ++ DYNSYM (isl_pw_aff_le_set); \ ++ DYNSYM (isl_pw_aff_lt_set); \ ++ DYNSYM (isl_pw_aff_mul); \ ++ DYNSYM (isl_pw_aff_ne_set); \ ++ DYNSYM (isl_pw_aff_nonneg_set); \ ++ DYNSYM (isl_pw_aff_set_tuple_id); \ ++ DYNSYM (isl_pw_aff_sub); \ ++ DYNSYM (isl_pw_aff_zero_set); \ ++ DYNSYM (isl_schedule_free); \ ++ DYNSYM (isl_schedule_get_band_forest); \ ++ DYNSYM (isl_set_add_constraint); \ ++ DYNSYM (isl_set_add_dims); \ ++ DYNSYM (isl_set_apply); \ ++ DYNSYM (isl_set_coalesce); \ ++ DYNSYM (isl_set_copy); \ ++ DYNSYM (isl_set_dim); \ ++ DYNSYM (isl_set_fix_si); \ ++ DYNSYM (isl_set_free); \ ++ DYNSYM (isl_set_get_space); \ ++ DYNSYM (isl_set_get_tuple_id); \ ++ DYNSYM (isl_set_intersect); \ ++ DYNSYM (isl_set_is_empty); \ ++ DYNSYM (isl_set_n_dim); \ ++ DYNSYM (isl_set_nat_universe); \ ++ DYNSYM (isl_set_project_out); \ ++ DYNSYM (isl_set_set_tuple_id); \ ++ DYNSYM (isl_set_universe); \ ++ DYNSYM (isl_space_add_dims); \ ++ DYNSYM (isl_space_alloc); \ ++ DYNSYM (isl_space_copy); \ ++ DYNSYM (isl_space_dim); \ ++ DYNSYM (isl_space_domain); \ ++ DYNSYM (isl_space_find_dim_by_id); \ ++ DYNSYM (isl_space_free); \ ++ DYNSYM (isl_space_from_domain); \ ++ DYNSYM (isl_space_get_tuple_id); \ ++ DYNSYM (isl_space_params_alloc); \ ++ DYNSYM (isl_space_range); \ ++ DYNSYM (isl_space_set_alloc); \ ++ DYNSYM (isl_space_set_dim_id); \ ++ DYNSYM (isl_space_set_tuple_id); \ ++ DYNSYM (isl_union_map_add_map); \ ++ DYNSYM (isl_union_map_align_params); \ ++ DYNSYM (isl_union_map_apply_domain); \ ++ DYNSYM (isl_union_map_apply_range); \ ++ DYNSYM (isl_union_map_compute_flow); \ ++ DYNSYM (isl_union_map_copy); \ ++ DYNSYM (isl_union_map_empty); \ ++ DYNSYM (isl_union_map_flat_range_product); \ ++ DYNSYM (isl_union_map_foreach_map); \ ++ DYNSYM (isl_union_map_free); \ ++ DYNSYM (isl_union_map_from_map); \ ++ DYNSYM (isl_union_map_get_ctx); \ ++ DYNSYM (isl_union_map_get_space); \ ++ DYNSYM (isl_union_map_gist_domain); \ ++ DYNSYM (isl_union_map_gist_range); \ ++ DYNSYM (isl_union_map_intersect_domain); \ ++ DYNSYM (isl_union_map_is_empty); \ ++ DYNSYM (isl_union_map_subtract); \ ++ DYNSYM (isl_union_map_union); \ ++ DYNSYM (isl_union_set_add_set); \ ++ DYNSYM (isl_union_set_compute_schedule); \ ++ DYNSYM (isl_union_set_copy); \ ++ DYNSYM (isl_union_set_empty); \ ++ DYNSYM (isl_union_set_from_set); \ ++ DYNSYM (isl_aff_add_constant_val); \ ++ DYNSYM (isl_aff_get_coefficient_val); \ ++ DYNSYM (isl_aff_get_ctx); \ ++ DYNSYM (isl_aff_mod_val); \ ++ DYNSYM (isl_ast_build_ast_from_schedule); \ ++ DYNSYM (isl_ast_build_free); \ ++ DYNSYM (isl_ast_build_from_context); \ ++ DYNSYM (isl_ast_build_get_ctx); \ ++ DYNSYM (isl_ast_build_get_schedule); \ ++ DYNSYM (isl_ast_build_get_schedule_space); \ ++ DYNSYM (isl_ast_build_set_before_each_for); \ ++ DYNSYM (isl_ast_build_set_options); \ ++ DYNSYM (isl_ast_expr_free); \ ++ DYNSYM (isl_ast_expr_from_val); \ ++ DYNSYM (isl_ast_expr_get_ctx); \ ++ DYNSYM (isl_ast_expr_get_id); \ ++ DYNSYM (isl_ast_expr_get_op_arg); \ ++ DYNSYM (isl_ast_expr_get_op_n_arg); \ ++ DYNSYM (isl_ast_expr_get_op_type); \ ++ DYNSYM (isl_ast_expr_get_type); \ ++ DYNSYM (isl_ast_expr_get_val); \ ++ DYNSYM (isl_ast_expr_sub); \ ++ DYNSYM (isl_ast_node_block_get_children); \ ++ DYNSYM (isl_ast_node_for_get_body); \ ++ DYNSYM (isl_ast_node_for_get_cond); \ ++ DYNSYM (isl_ast_node_for_get_inc); \ ++ DYNSYM (isl_ast_node_for_get_init); \ ++ DYNSYM (isl_ast_node_for_get_iterator); \ ++ DYNSYM (isl_ast_node_free); \ ++ DYNSYM (isl_ast_node_get_annotation); \ ++ DYNSYM (isl_ast_node_get_type); \ ++ DYNSYM (isl_ast_node_if_get_cond); \ ++ DYNSYM (isl_ast_node_if_get_else); \ ++ DYNSYM (isl_ast_node_if_get_then); \ ++ DYNSYM (isl_ast_node_list_free); \ ++ DYNSYM (isl_ast_node_list_get_ast_node); \ ++ DYNSYM (isl_ast_node_list_n_ast_node); \ ++ DYNSYM (isl_ast_node_user_get_expr); \ ++ DYNSYM (isl_constraint_set_coefficient_val); \ ++ DYNSYM (isl_constraint_set_constant_val); \ ++ DYNSYM (isl_id_get_user); \ ++ DYNSYM (isl_local_space_get_ctx); \ ++ DYNSYM (isl_map_fix_val); \ ++ DYNSYM (isl_options_set_ast_build_atomic_upper_bound); \ ++ DYNSYM (isl_printer_print_ast_node); \ ++ DYNSYM (isl_printer_print_str); \ ++ DYNSYM (isl_printer_set_output_format); \ ++ DYNSYM (isl_pw_aff_mod_val); \ ++ DYNSYM (isl_schedule_constraints_compute_schedule); \ ++ DYNSYM (isl_schedule_constraints_on_domain); \ ++ DYNSYM (isl_schedule_constraints_set_coincidence); \ ++ DYNSYM (isl_schedule_constraints_set_proximity); \ ++ DYNSYM (isl_schedule_constraints_set_validity); \ ++ DYNSYM (isl_set_get_dim_id); \ ++ DYNSYM (isl_set_max_val); \ ++ DYNSYM (isl_set_min_val); \ ++ DYNSYM (isl_set_params); \ ++ DYNSYM (isl_space_align_params); \ ++ DYNSYM (isl_space_map_from_domain_and_range); \ ++ DYNSYM (isl_space_set_tuple_name); \ ++ DYNSYM (isl_space_wrap); \ ++ DYNSYM (isl_union_map_from_domain_and_range); \ ++ DYNSYM (isl_union_map_range); \ ++ DYNSYM (isl_union_set_union); \ ++ DYNSYM (isl_union_set_universe); \ ++ DYNSYM (isl_val_2exp); \ ++ DYNSYM (isl_val_add_ui); \ ++ DYNSYM (isl_val_copy); \ ++ DYNSYM (isl_val_free); \ ++ DYNSYM (isl_val_int_from_si); \ ++ DYNSYM (isl_val_int_from_ui); \ ++ DYNSYM (isl_val_mul); \ ++ DYNSYM (isl_val_neg); \ ++ DYNSYM (isl_val_sub); \ ++ DYNSYM (isl_printer_print_union_map); \ ++ DYNSYM (isl_pw_aff_get_ctx); \ ++ DYNSYM (isl_val_is_int); \ ++ DYNSYM (isl_ctx_get_max_operations); \ ++ DYNSYM (isl_ctx_set_max_operations); \ ++ DYNSYM (isl_ctx_last_error); \ ++ DYNSYM (isl_ctx_reset_operations); \ ++ DYNSYM (isl_map_coalesce); \ ++ DYNSYM (isl_printer_print_schedule); \ ++ DYNSYM (isl_set_set_dim_id); \ ++ DYNSYM (isl_union_map_coalesce); \ ++ DYNSYM (isl_multi_val_set_val); \ ++ DYNSYM (isl_multi_val_zero); \ ++ DYNSYM (isl_options_set_schedule_max_coefficient); \ ++ DYNSYM (isl_options_set_tile_scale_tile_loops); \ ++ DYNSYM (isl_schedule_copy); \ ++ DYNSYM (isl_schedule_get_map); \ ++ DYNSYM (isl_schedule_map_schedule_node_bottom_up); \ ++ DYNSYM (isl_schedule_node_band_get_permutable); \ ++ DYNSYM (isl_schedule_node_band_get_space); \ ++ DYNSYM (isl_schedule_node_band_tile); \ ++ DYNSYM (isl_schedule_node_child); \ ++ DYNSYM (isl_schedule_node_free); \ ++ DYNSYM (isl_schedule_node_get_child); \ ++ DYNSYM (isl_schedule_node_get_ctx); \ ++ DYNSYM (isl_schedule_node_get_type); \ ++ DYNSYM (isl_schedule_node_n_children); \ ++ DYNSYM (isl_union_map_is_equal); \ ++ DYNSYM (isl_union_access_info_compute_flow); \ ++ DYNSYM (isl_union_access_info_from_sink); \ ++ DYNSYM (isl_union_access_info_set_may_source); \ ++ DYNSYM (isl_union_access_info_set_must_source); \ ++ DYNSYM (isl_union_access_info_set_schedule); \ ++ DYNSYM (isl_union_flow_free); \ ++ DYNSYM (isl_union_flow_get_may_dependence); \ ++ DYNSYM (isl_union_flow_get_must_dependence); \ ++ DYNSYM (isl_aff_var_on_domain); \ ++ DYNSYM (isl_multi_aff_from_aff); \ ++ DYNSYM (isl_schedule_get_ctx); \ ++ DYNSYM (isl_multi_aff_set_tuple_id); \ ++ DYNSYM (isl_multi_aff_dim); \ ++ DYNSYM (isl_schedule_get_domain); \ ++ DYNSYM (isl_union_set_is_empty); \ ++ DYNSYM (isl_union_set_get_space); \ ++ DYNSYM (isl_union_pw_multi_aff_empty); \ ++ DYNSYM (isl_union_set_foreach_set); \ ++ DYNSYM (isl_union_set_free); \ ++ DYNSYM (isl_multi_union_pw_aff_from_union_pw_multi_aff); \ ++ DYNSYM (isl_multi_union_pw_aff_apply_multi_aff); \ ++ DYNSYM (isl_schedule_insert_partial_schedule); \ ++ DYNSYM (isl_union_pw_multi_aff_free); \ ++ DYNSYM (isl_pw_multi_aff_project_out_map); \ ++ DYNSYM (isl_union_pw_multi_aff_add_pw_multi_aff); \ ++ DYNSYM (isl_schedule_from_domain); \ ++ DYNSYM (isl_schedule_sequence); \ ++ DYNSYM (isl_ast_build_node_from_schedule); \ ++ DYNSYM (isl_ast_node_mark_get_node); \ ++ DYNSYM (isl_schedule_node_band_member_get_ast_loop_type); \ ++ DYNSYM (isl_schedule_node_band_member_set_ast_loop_type); \ ++ DYNSYM (isl_val_n_abs_num_chunks); \ ++ DYNSYM (isl_val_get_abs_num_chunks); \ ++ DYNSYM (isl_val_int_from_chunks); \ ++ DYNSYM (isl_val_is_neg); \ ++ DYNSYM (isl_version); \ ++ DYNSYM (isl_options_get_on_error); \ ++ DYNSYM (isl_ctx_reset_error); ++ ++extern struct isl_pointers_s__ ++{ ++ bool inited; ++ void *h; ++#define DYNSYM(x) __typeof (x) *p_##x ++ DYNSYMS ++#undef DYNSYM ++} isl_pointers__; ++ ++#define isl_aff_add_coefficient_si (*isl_pointers__.p_isl_aff_add_coefficient_si) ++#define isl_aff_free (*isl_pointers__.p_isl_aff_free) ++#define isl_aff_get_space (*isl_pointers__.p_isl_aff_get_space) ++#define isl_aff_set_coefficient_si (*isl_pointers__.p_isl_aff_set_coefficient_si) ++#define isl_aff_set_constant_si (*isl_pointers__.p_isl_aff_set_constant_si) ++#define isl_aff_zero_on_domain (*isl_pointers__.p_isl_aff_zero_on_domain) ++#define isl_band_free (*isl_pointers__.p_isl_band_free) ++#define isl_band_get_children (*isl_pointers__.p_isl_band_get_children) ++#define isl_band_get_partial_schedule (*isl_pointers__.p_isl_band_get_partial_schedule) ++#define isl_band_has_children (*isl_pointers__.p_isl_band_has_children) ++#define isl_band_list_free (*isl_pointers__.p_isl_band_list_free) ++#define isl_band_list_get_band (*isl_pointers__.p_isl_band_list_get_band) ++#define isl_band_list_get_ctx (*isl_pointers__.p_isl_band_list_get_ctx) ++#define isl_band_list_n_band (*isl_pointers__.p_isl_band_list_n_band) ++#define isl_band_n_member (*isl_pointers__.p_isl_band_n_member) ++#define isl_basic_map_add_constraint (*isl_pointers__.p_isl_basic_map_add_constraint) ++#define isl_basic_map_project_out (*isl_pointers__.p_isl_basic_map_project_out) ++#define isl_basic_map_universe (*isl_pointers__.p_isl_basic_map_universe) ++#define isl_constraint_set_coefficient_si (*isl_pointers__.p_isl_constraint_set_coefficient_si) ++#define isl_constraint_set_constant_si (*isl_pointers__.p_isl_constraint_set_constant_si) ++#define isl_ctx_alloc (*isl_pointers__.p_isl_ctx_alloc) ++#define isl_ctx_free (*isl_pointers__.p_isl_ctx_free) ++#define isl_equality_alloc (*isl_pointers__.p_isl_equality_alloc) ++#define isl_id_alloc (*isl_pointers__.p_isl_id_alloc) ++#define isl_id_copy (*isl_pointers__.p_isl_id_copy) ++#define isl_id_free (*isl_pointers__.p_isl_id_free) ++#define isl_inequality_alloc (*isl_pointers__.p_isl_inequality_alloc) ++#define isl_local_space_copy (*isl_pointers__.p_isl_local_space_copy) ++#define isl_local_space_free (*isl_pointers__.p_isl_local_space_free) ++#define isl_local_space_from_space (*isl_pointers__.p_isl_local_space_from_space) ++#define isl_local_space_range (*isl_pointers__.p_isl_local_space_range) ++#define isl_map_add_constraint (*isl_pointers__.p_isl_map_add_constraint) ++#define isl_map_add_dims (*isl_pointers__.p_isl_map_add_dims) ++#define isl_map_align_params (*isl_pointers__.p_isl_map_align_params) ++#define isl_map_apply_range (*isl_pointers__.p_isl_map_apply_range) ++#define isl_map_copy (*isl_pointers__.p_isl_map_copy) ++#define isl_map_dim (*isl_pointers__.p_isl_map_dim) ++#define isl_map_dump (*isl_pointers__.p_isl_map_dump) ++#define isl_map_equate (*isl_pointers__.p_isl_map_equate) ++#define isl_map_fix_si (*isl_pointers__.p_isl_map_fix_si) ++#define isl_map_flat_product (*isl_pointers__.p_isl_map_flat_product) ++#define isl_map_flat_range_product (*isl_pointers__.p_isl_map_flat_range_product) ++#define isl_map_free (*isl_pointers__.p_isl_map_free) ++#define isl_map_from_basic_map (*isl_pointers__.p_isl_map_from_basic_map) ++#define isl_map_from_pw_aff (*isl_pointers__.p_isl_map_from_pw_aff) ++#define isl_map_from_union_map (*isl_pointers__.p_isl_map_from_union_map) ++#define isl_map_get_ctx (*isl_pointers__.p_isl_map_get_ctx) ++#define isl_map_get_space (*isl_pointers__.p_isl_map_get_space) ++#define isl_map_get_tuple_id (*isl_pointers__.p_isl_map_get_tuple_id) ++#define isl_map_insert_dims (*isl_pointers__.p_isl_map_insert_dims) ++#define isl_map_intersect (*isl_pointers__.p_isl_map_intersect) ++#define isl_map_intersect_domain (*isl_pointers__.p_isl_map_intersect_domain) ++#define isl_map_intersect_range (*isl_pointers__.p_isl_map_intersect_range) ++#define isl_map_is_empty (*isl_pointers__.p_isl_map_is_empty) ++#define isl_map_lex_ge (*isl_pointers__.p_isl_map_lex_ge) ++#define isl_map_lex_le (*isl_pointers__.p_isl_map_lex_le) ++#define isl_map_n_out (*isl_pointers__.p_isl_map_n_out) ++#define isl_map_range (*isl_pointers__.p_isl_map_range) ++#define isl_map_set_tuple_id (*isl_pointers__.p_isl_map_set_tuple_id) ++#define isl_map_universe (*isl_pointers__.p_isl_map_universe) ++#define isl_options_set_on_error (*isl_pointers__.p_isl_options_set_on_error) ++#define isl_options_set_schedule_serialize_sccs (*isl_pointers__.p_isl_options_set_schedule_serialize_sccs) ++#define isl_printer_set_yaml_style (*isl_pointers__.p_isl_printer_set_yaml_style) ++#define isl_options_set_schedule_max_constant_term (*isl_pointers__.p_isl_options_set_schedule_max_constant_term) ++#define isl_options_set_schedule_maximize_band_depth (*isl_pointers__.p_isl_options_set_schedule_maximize_band_depth) ++#define isl_printer_free (*isl_pointers__.p_isl_printer_free) ++#define isl_printer_print_aff (*isl_pointers__.p_isl_printer_print_aff) ++#define isl_printer_print_constraint (*isl_pointers__.p_isl_printer_print_constraint) ++#define isl_printer_print_map (*isl_pointers__.p_isl_printer_print_map) ++#define isl_printer_print_set (*isl_pointers__.p_isl_printer_print_set) ++#define isl_printer_to_file (*isl_pointers__.p_isl_printer_to_file) ++#define isl_pw_aff_add (*isl_pointers__.p_isl_pw_aff_add) ++#define isl_pw_aff_alloc (*isl_pointers__.p_isl_pw_aff_alloc) ++#define isl_pw_aff_copy (*isl_pointers__.p_isl_pw_aff_copy) ++#define isl_pw_aff_eq_set (*isl_pointers__.p_isl_pw_aff_eq_set) ++#define isl_pw_aff_free (*isl_pointers__.p_isl_pw_aff_free) ++#define isl_pw_aff_from_aff (*isl_pointers__.p_isl_pw_aff_from_aff) ++#define isl_pw_aff_ge_set (*isl_pointers__.p_isl_pw_aff_ge_set) ++#define isl_pw_aff_gt_set (*isl_pointers__.p_isl_pw_aff_gt_set) ++#define isl_pw_aff_is_cst (*isl_pointers__.p_isl_pw_aff_is_cst) ++#define isl_pw_aff_le_set (*isl_pointers__.p_isl_pw_aff_le_set) ++#define isl_pw_aff_lt_set (*isl_pointers__.p_isl_pw_aff_lt_set) ++#define isl_pw_aff_mul (*isl_pointers__.p_isl_pw_aff_mul) ++#define isl_pw_aff_ne_set (*isl_pointers__.p_isl_pw_aff_ne_set) ++#define isl_pw_aff_nonneg_set (*isl_pointers__.p_isl_pw_aff_nonneg_set) ++#define isl_pw_aff_set_tuple_id (*isl_pointers__.p_isl_pw_aff_set_tuple_id) ++#define isl_pw_aff_sub (*isl_pointers__.p_isl_pw_aff_sub) ++#define isl_pw_aff_zero_set (*isl_pointers__.p_isl_pw_aff_zero_set) ++#define isl_schedule_free (*isl_pointers__.p_isl_schedule_free) ++#define isl_schedule_get_band_forest (*isl_pointers__.p_isl_schedule_get_band_forest) ++#define isl_set_add_constraint (*isl_pointers__.p_isl_set_add_constraint) ++#define isl_set_add_dims (*isl_pointers__.p_isl_set_add_dims) ++#define isl_set_apply (*isl_pointers__.p_isl_set_apply) ++#define isl_set_coalesce (*isl_pointers__.p_isl_set_coalesce) ++#define isl_set_copy (*isl_pointers__.p_isl_set_copy) ++#define isl_set_dim (*isl_pointers__.p_isl_set_dim) ++#define isl_set_fix_si (*isl_pointers__.p_isl_set_fix_si) ++#define isl_set_free (*isl_pointers__.p_isl_set_free) ++#define isl_set_get_space (*isl_pointers__.p_isl_set_get_space) ++#define isl_set_get_tuple_id (*isl_pointers__.p_isl_set_get_tuple_id) ++#define isl_set_intersect (*isl_pointers__.p_isl_set_intersect) ++#define isl_set_is_empty (*isl_pointers__.p_isl_set_is_empty) ++#define isl_set_n_dim (*isl_pointers__.p_isl_set_n_dim) ++#define isl_set_nat_universe (*isl_pointers__.p_isl_set_nat_universe) ++#define isl_set_project_out (*isl_pointers__.p_isl_set_project_out) ++#define isl_set_set_tuple_id (*isl_pointers__.p_isl_set_set_tuple_id) ++#define isl_set_universe (*isl_pointers__.p_isl_set_universe) ++#define isl_space_add_dims (*isl_pointers__.p_isl_space_add_dims) ++#define isl_space_alloc (*isl_pointers__.p_isl_space_alloc) ++#define isl_space_copy (*isl_pointers__.p_isl_space_copy) ++#define isl_space_dim (*isl_pointers__.p_isl_space_dim) ++#define isl_space_domain (*isl_pointers__.p_isl_space_domain) ++#define isl_space_find_dim_by_id (*isl_pointers__.p_isl_space_find_dim_by_id) ++#define isl_space_free (*isl_pointers__.p_isl_space_free) ++#define isl_space_from_domain (*isl_pointers__.p_isl_space_from_domain) ++#define isl_space_get_tuple_id (*isl_pointers__.p_isl_space_get_tuple_id) ++#define isl_space_params_alloc (*isl_pointers__.p_isl_space_params_alloc) ++#define isl_space_range (*isl_pointers__.p_isl_space_range) ++#define isl_space_set_alloc (*isl_pointers__.p_isl_space_set_alloc) ++#define isl_space_set_dim_id (*isl_pointers__.p_isl_space_set_dim_id) ++#define isl_space_set_tuple_id (*isl_pointers__.p_isl_space_set_tuple_id) ++#define isl_union_map_add_map (*isl_pointers__.p_isl_union_map_add_map) ++#define isl_union_map_align_params (*isl_pointers__.p_isl_union_map_align_params) ++#define isl_union_map_apply_domain (*isl_pointers__.p_isl_union_map_apply_domain) ++#define isl_union_map_apply_range (*isl_pointers__.p_isl_union_map_apply_range) ++#define isl_union_map_compute_flow (*isl_pointers__.p_isl_union_map_compute_flow) ++#define isl_union_map_copy (*isl_pointers__.p_isl_union_map_copy) ++#define isl_union_map_empty (*isl_pointers__.p_isl_union_map_empty) ++#define isl_union_map_flat_range_product (*isl_pointers__.p_isl_union_map_flat_range_product) ++#define isl_union_map_foreach_map (*isl_pointers__.p_isl_union_map_foreach_map) ++#define isl_union_map_free (*isl_pointers__.p_isl_union_map_free) ++#define isl_union_map_from_map (*isl_pointers__.p_isl_union_map_from_map) ++#define isl_union_map_get_ctx (*isl_pointers__.p_isl_union_map_get_ctx) ++#define isl_union_map_get_space (*isl_pointers__.p_isl_union_map_get_space) ++#define isl_union_map_gist_domain (*isl_pointers__.p_isl_union_map_gist_domain) ++#define isl_union_map_gist_range (*isl_pointers__.p_isl_union_map_gist_range) ++#define isl_union_map_intersect_domain (*isl_pointers__.p_isl_union_map_intersect_domain) ++#define isl_union_map_is_empty (*isl_pointers__.p_isl_union_map_is_empty) ++#define isl_union_map_subtract (*isl_pointers__.p_isl_union_map_subtract) ++#define isl_union_map_union (*isl_pointers__.p_isl_union_map_union) ++#define isl_union_set_add_set (*isl_pointers__.p_isl_union_set_add_set) ++#define isl_union_set_compute_schedule (*isl_pointers__.p_isl_union_set_compute_schedule) ++#define isl_union_set_copy (*isl_pointers__.p_isl_union_set_copy) ++#define isl_union_set_empty (*isl_pointers__.p_isl_union_set_empty) ++#define isl_union_set_from_set (*isl_pointers__.p_isl_union_set_from_set) ++#define isl_aff_add_constant_val (*isl_pointers__.p_isl_aff_add_constant_val) ++#define isl_aff_get_coefficient_val (*isl_pointers__.p_isl_aff_get_coefficient_val) ++#define isl_aff_get_ctx (*isl_pointers__.p_isl_aff_get_ctx) ++#define isl_aff_mod_val (*isl_pointers__.p_isl_aff_mod_val) ++#define isl_ast_build_ast_from_schedule (*isl_pointers__.p_isl_ast_build_ast_from_schedule) ++#define isl_ast_build_free (*isl_pointers__.p_isl_ast_build_free) ++#define isl_ast_build_from_context (*isl_pointers__.p_isl_ast_build_from_context) ++#define isl_ast_build_get_ctx (*isl_pointers__.p_isl_ast_build_get_ctx) ++#define isl_ast_build_get_schedule (*isl_pointers__.p_isl_ast_build_get_schedule) ++#define isl_ast_build_get_schedule_space (*isl_pointers__.p_isl_ast_build_get_schedule_space) ++#define isl_ast_build_set_before_each_for (*isl_pointers__.p_isl_ast_build_set_before_each_for) ++#define isl_ast_build_set_options (*isl_pointers__.p_isl_ast_build_set_options) ++#define isl_ast_expr_free (*isl_pointers__.p_isl_ast_expr_free) ++#define isl_ast_expr_from_val (*isl_pointers__.p_isl_ast_expr_from_val) ++#define isl_ast_expr_get_ctx (*isl_pointers__.p_isl_ast_expr_get_ctx) ++#define isl_ast_expr_get_id (*isl_pointers__.p_isl_ast_expr_get_id) ++#define isl_ast_expr_get_op_arg (*isl_pointers__.p_isl_ast_expr_get_op_arg) ++#define isl_ast_expr_get_op_n_arg (*isl_pointers__.p_isl_ast_expr_get_op_n_arg) ++#define isl_ast_expr_get_op_type (*isl_pointers__.p_isl_ast_expr_get_op_type) ++#define isl_ast_expr_get_type (*isl_pointers__.p_isl_ast_expr_get_type) ++#define isl_ast_expr_get_val (*isl_pointers__.p_isl_ast_expr_get_val) ++#define isl_ast_expr_sub (*isl_pointers__.p_isl_ast_expr_sub) ++#define isl_ast_node_block_get_children (*isl_pointers__.p_isl_ast_node_block_get_children) ++#define isl_ast_node_for_get_body (*isl_pointers__.p_isl_ast_node_for_get_body) ++#define isl_ast_node_for_get_cond (*isl_pointers__.p_isl_ast_node_for_get_cond) ++#define isl_ast_node_for_get_inc (*isl_pointers__.p_isl_ast_node_for_get_inc) ++#define isl_ast_node_for_get_init (*isl_pointers__.p_isl_ast_node_for_get_init) ++#define isl_ast_node_for_get_iterator (*isl_pointers__.p_isl_ast_node_for_get_iterator) ++#define isl_ast_node_free (*isl_pointers__.p_isl_ast_node_free) ++#define isl_ast_node_get_annotation (*isl_pointers__.p_isl_ast_node_get_annotation) ++#define isl_ast_node_get_type (*isl_pointers__.p_isl_ast_node_get_type) ++#define isl_ast_node_if_get_cond (*isl_pointers__.p_isl_ast_node_if_get_cond) ++#define isl_ast_node_if_get_else (*isl_pointers__.p_isl_ast_node_if_get_else) ++#define isl_ast_node_if_get_then (*isl_pointers__.p_isl_ast_node_if_get_then) ++#define isl_ast_node_list_free (*isl_pointers__.p_isl_ast_node_list_free) ++#define isl_ast_node_list_get_ast_node (*isl_pointers__.p_isl_ast_node_list_get_ast_node) ++#define isl_ast_node_list_n_ast_node (*isl_pointers__.p_isl_ast_node_list_n_ast_node) ++#define isl_ast_node_user_get_expr (*isl_pointers__.p_isl_ast_node_user_get_expr) ++#define isl_constraint_set_coefficient_val (*isl_pointers__.p_isl_constraint_set_coefficient_val) ++#define isl_constraint_set_constant_val (*isl_pointers__.p_isl_constraint_set_constant_val) ++#define isl_id_get_user (*isl_pointers__.p_isl_id_get_user) ++#define isl_local_space_get_ctx (*isl_pointers__.p_isl_local_space_get_ctx) ++#define isl_map_fix_val (*isl_pointers__.p_isl_map_fix_val) ++#define isl_options_set_ast_build_atomic_upper_bound (*isl_pointers__.p_isl_options_set_ast_build_atomic_upper_bound) ++#define isl_printer_print_ast_node (*isl_pointers__.p_isl_printer_print_ast_node) ++#define isl_printer_print_str (*isl_pointers__.p_isl_printer_print_str) ++#define isl_printer_set_output_format (*isl_pointers__.p_isl_printer_set_output_format) ++#define isl_pw_aff_mod_val (*isl_pointers__.p_isl_pw_aff_mod_val) ++#define isl_schedule_constraints_compute_schedule (*isl_pointers__.p_isl_schedule_constraints_compute_schedule) ++#define isl_schedule_constraints_on_domain (*isl_pointers__.p_isl_schedule_constraints_on_domain) ++#define isl_schedule_constraints_set_coincidence (*isl_pointers__.p_isl_schedule_constraints_set_coincidence) ++#define isl_schedule_constraints_set_proximity (*isl_pointers__.p_isl_schedule_constraints_set_proximity) ++#define isl_schedule_constraints_set_validity (*isl_pointers__.p_isl_schedule_constraints_set_validity) ++#define isl_set_get_dim_id (*isl_pointers__.p_isl_set_get_dim_id) ++#define isl_set_max_val (*isl_pointers__.p_isl_set_max_val) ++#define isl_set_min_val (*isl_pointers__.p_isl_set_min_val) ++#define isl_set_params (*isl_pointers__.p_isl_set_params) ++#define isl_space_align_params (*isl_pointers__.p_isl_space_align_params) ++#define isl_space_map_from_domain_and_range (*isl_pointers__.p_isl_space_map_from_domain_and_range) ++#define isl_space_set_tuple_name (*isl_pointers__.p_isl_space_set_tuple_name) ++#define isl_space_wrap (*isl_pointers__.p_isl_space_wrap) ++#define isl_union_map_from_domain_and_range (*isl_pointers__.p_isl_union_map_from_domain_and_range) ++#define isl_union_map_range (*isl_pointers__.p_isl_union_map_range) ++#define isl_union_set_union (*isl_pointers__.p_isl_union_set_union) ++#define isl_union_set_universe (*isl_pointers__.p_isl_union_set_universe) ++#define isl_val_2exp (*isl_pointers__.p_isl_val_2exp) ++#define isl_val_add_ui (*isl_pointers__.p_isl_val_add_ui) ++#define isl_val_copy (*isl_pointers__.p_isl_val_copy) ++#define isl_val_free (*isl_pointers__.p_isl_val_free) ++#define isl_val_int_from_si (*isl_pointers__.p_isl_val_int_from_si) ++#define isl_val_int_from_ui (*isl_pointers__.p_isl_val_int_from_ui) ++#define isl_val_mul (*isl_pointers__.p_isl_val_mul) ++#define isl_val_neg (*isl_pointers__.p_isl_val_neg) ++#define isl_val_sub (*isl_pointers__.p_isl_val_sub) ++#define isl_printer_print_union_map (*isl_pointers__.p_isl_printer_print_union_map) ++#define isl_pw_aff_get_ctx (*isl_pointers__.p_isl_pw_aff_get_ctx) ++#define isl_val_is_int (*isl_pointers__.p_isl_val_is_int) ++#define isl_ctx_get_max_operations (*isl_pointers__.p_isl_ctx_get_max_operations) ++#define isl_ctx_set_max_operations (*isl_pointers__.p_isl_ctx_set_max_operations) ++#define isl_ctx_last_error (*isl_pointers__.p_isl_ctx_last_error) ++#define isl_ctx_reset_operations (*isl_pointers__.p_isl_ctx_reset_operations) ++#define isl_map_coalesce (*isl_pointers__.p_isl_map_coalesce) ++#define isl_printer_print_schedule (*isl_pointers__.p_isl_printer_print_schedule) ++#define isl_set_set_dim_id (*isl_pointers__.p_isl_set_set_dim_id) ++#define isl_union_map_coalesce (*isl_pointers__.p_isl_union_map_coalesce) ++#define isl_multi_val_set_val (*isl_pointers__.p_isl_multi_val_set_val) ++#define isl_multi_val_zero (*isl_pointers__.p_isl_multi_val_zero) ++#define isl_options_set_schedule_max_coefficient (*isl_pointers__.p_isl_options_set_schedule_max_coefficient) ++#define isl_options_set_tile_scale_tile_loops (*isl_pointers__.p_isl_options_set_tile_scale_tile_loops) ++#define isl_schedule_copy (*isl_pointers__.p_isl_schedule_copy) ++#define isl_schedule_get_map (*isl_pointers__.p_isl_schedule_get_map) ++#define isl_schedule_map_schedule_node_bottom_up (*isl_pointers__.p_isl_schedule_map_schedule_node_bottom_up) ++#define isl_schedule_node_band_get_permutable (*isl_pointers__.p_isl_schedule_node_band_get_permutable) ++#define isl_schedule_node_band_get_space (*isl_pointers__.p_isl_schedule_node_band_get_space) ++#define isl_schedule_node_band_tile (*isl_pointers__.p_isl_schedule_node_band_tile) ++#define isl_schedule_node_child (*isl_pointers__.p_isl_schedule_node_child) ++#define isl_schedule_node_free (*isl_pointers__.p_isl_schedule_node_free) ++#define isl_schedule_node_get_child (*isl_pointers__.p_isl_schedule_node_get_child) ++#define isl_schedule_node_get_ctx (*isl_pointers__.p_isl_schedule_node_get_ctx) ++#define isl_schedule_node_get_type (*isl_pointers__.p_isl_schedule_node_get_type) ++#define isl_schedule_node_n_children (*isl_pointers__.p_isl_schedule_node_n_children) ++#define isl_union_map_is_equal (*isl_pointers__.p_isl_union_map_is_equal) ++#define isl_union_access_info_compute_flow (*isl_pointers__.p_isl_union_access_info_compute_flow) ++#define isl_union_access_info_from_sink (*isl_pointers__.p_isl_union_access_info_from_sink) ++#define isl_union_access_info_set_may_source (*isl_pointers__.p_isl_union_access_info_set_may_source) ++#define isl_union_access_info_set_must_source (*isl_pointers__.p_isl_union_access_info_set_must_source) ++#define isl_union_access_info_set_schedule (*isl_pointers__.p_isl_union_access_info_set_schedule) ++#define isl_union_flow_free (*isl_pointers__.p_isl_union_flow_free) ++#define isl_union_flow_get_may_dependence (*isl_pointers__.p_isl_union_flow_get_may_dependence) ++#define isl_union_flow_get_must_dependence (*isl_pointers__.p_isl_union_flow_get_must_dependence) ++#define isl_aff_var_on_domain (*isl_pointers__.p_isl_aff_var_on_domain) ++#define isl_multi_aff_from_aff (*isl_pointers__.p_isl_multi_aff_from_aff) ++#define isl_schedule_get_ctx (*isl_pointers__.p_isl_schedule_get_ctx) ++#define isl_multi_aff_set_tuple_id (*isl_pointers__.p_isl_multi_aff_set_tuple_id) ++#define isl_multi_aff_dim (*isl_pointers__.p_isl_multi_aff_dim) ++#define isl_schedule_get_domain (*isl_pointers__.p_isl_schedule_get_domain) ++#define isl_union_set_is_empty (*isl_pointers__.p_isl_union_set_is_empty) ++#define isl_union_set_get_space (*isl_pointers__.p_isl_union_set_get_space) ++#define isl_union_pw_multi_aff_empty (*isl_pointers__.p_isl_union_pw_multi_aff_empty) ++#define isl_union_set_foreach_set (*isl_pointers__.p_isl_union_set_foreach_set) ++#define isl_union_set_free (*isl_pointers__.p_isl_union_set_free) ++#define isl_multi_union_pw_aff_from_union_pw_multi_aff (*isl_pointers__.p_isl_multi_union_pw_aff_from_union_pw_multi_aff) ++#define isl_multi_union_pw_aff_apply_multi_aff (*isl_pointers__.p_isl_multi_union_pw_aff_apply_multi_aff) ++#define isl_schedule_insert_partial_schedule (*isl_pointers__.p_isl_schedule_insert_partial_schedule) ++#define isl_union_pw_multi_aff_free (*isl_pointers__.p_isl_union_pw_multi_aff_free) ++#define isl_pw_multi_aff_project_out_map (*isl_pointers__.p_isl_pw_multi_aff_project_out_map) ++#define isl_union_pw_multi_aff_add_pw_multi_aff (*isl_pointers__.p_isl_union_pw_multi_aff_add_pw_multi_aff) ++#define isl_schedule_from_domain (*isl_pointers__.p_isl_schedule_from_domain) ++#define isl_schedule_sequence (*isl_pointers__.p_isl_schedule_sequence) ++#define isl_ast_build_node_from_schedule (*isl_pointers__.p_isl_ast_build_node_from_schedule) ++#define isl_ast_node_mark_get_node (*isl_pointers__.p_isl_ast_node_mark_get_node) ++#define isl_schedule_node_band_member_get_ast_loop_type (*isl_pointers__.p_isl_schedule_node_band_member_get_ast_loop_type) ++#define isl_schedule_node_band_member_set_ast_loop_type (*isl_pointers__.p_isl_schedule_node_band_member_set_ast_loop_type) ++#define isl_val_n_abs_num_chunks (*isl_pointers__.p_isl_val_n_abs_num_chunks) ++#define isl_val_get_abs_num_chunks (*isl_pointers__.p_isl_val_get_abs_num_chunks) ++#define isl_val_int_from_chunks (*isl_pointers__.p_isl_val_int_from_chunks) ++#define isl_val_is_neg (*isl_pointers__.p_isl_val_is_neg) ++#define isl_version (*isl_pointers__.p_isl_version) ++#define isl_options_get_on_error (*isl_pointers__.p_isl_options_get_on_error) ++#define isl_ctx_reset_error (*isl_pointers__.p_isl_ctx_reset_error) + + typedef struct poly_dr *poly_dr_p; + +@@ -461,5 +1045,6 @@ extern void build_scops (vec *); + extern void dot_all_sese (FILE *, vec &); + extern void dot_sese (sese_l &); + extern void dot_cfg (); ++extern const char *get_isl_version (bool); + + #endif +--- gcc/graphite.c.jj 2015-11-04 14:15:32.000000000 +0100 ++++ gcc/graphite.c 2015-11-04 14:56:02.645536409 +0100 +@@ -60,6 +60,35 @@ along with GCC; see the file COPYING3. + #include "tree-into-ssa.h" + #include "graphite.h" + ++__typeof (isl_pointers__) isl_pointers__; ++ ++static bool ++init_isl_pointers (void) ++{ ++ void *h; ++ ++ if (isl_pointers__.inited) ++ return isl_pointers__.h != NULL; ++ h = dlopen ("libisl.so.15", RTLD_LAZY); ++ isl_pointers__.h = h; ++ if (h == NULL) ++ return false; ++#define DYNSYM(x) \ ++ do \ ++ { \ ++ union { __typeof (isl_pointers__.p_##x) p; void *q; } u; \ ++ u.q = dlsym (h, #x); \ ++ if (u.q == NULL) \ ++ return false; \ ++ isl_pointers__.p_##x = u.p; \ ++ } \ ++ while (0) ++ DYNSYMS ++#undef DYNSYM ++ isl_pointers__.inited = true; ++ return true; ++} ++ + /* Print global statistics to FILE. */ + + static void +@@ -365,6 +394,15 @@ graphite_transform_loops (void) + if (parallelized_function_p (cfun->decl)) + return; + ++ if (number_of_loops (cfun) <= 1) ++ return; ++ ++ if (!init_isl_pointers ()) ++ { ++ sorry ("Graphite loop optimizations cannot be used"); ++ return; ++ } ++ + calculate_dominance_info (CDI_DOMINATORS); + + /* We rely on post-dominators during merging of SESE regions so those +@@ -455,6 +493,14 @@ graphite_transform_loops (void) + } + } + ++const char * ++get_isl_version (bool force) ++{ ++ if (force) ++ init_isl_pointers (); ++ return (isl_pointers__.inited && isl_version) ? isl_version () : "none"; ++} ++ + #else /* If isl is not available: #ifndef HAVE_isl. */ + + static void +--- gcc/toplev.c.jj 2017-02-19 13:02:31.000000000 +0100 ++++ gcc/toplev.c 2017-02-19 16:50:25.536301350 +0100 +@@ -94,6 +94,7 @@ along with GCC; see the file COPYING3. + + #ifdef HAVE_isl + #include ++extern const char *get_isl_version (bool); + #endif + + static void general_init (const char *, bool); +@@ -683,7 +684,7 @@ print_version (FILE *file, const char *i + #ifndef HAVE_isl + "none" + #else +- isl_version () ++ get_isl_version (*indent == 0) + #endif + ); + if (strcmp (GCC_GMP_STRINGIFY_VERSION, gmp_version)) diff --git a/SOURCES/gcc8-libgcc-hardened.patch b/SOURCES/gcc8-libgcc-hardened.patch new file mode 100644 index 0000000..51f6c39 --- /dev/null +++ b/SOURCES/gcc8-libgcc-hardened.patch @@ -0,0 +1,14 @@ +--- libgcc/config/t-slibgcc.mp 2018-10-03 16:07:00.336990246 -0400 ++++ libgcc/config/t-slibgcc 2018-10-03 16:06:26.719946740 -0400 +@@ -30,9 +30,10 @@ SHLIB_LC = -lc + SHLIB_MAKE_SOLINK = $(LN_S) $(SHLIB_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK) + SHLIB_INSTALL_SOLINK = $(LN_S) $(SHLIB_SONAME) \ + $(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK) ++SHLIB_EXTRA_LDFLAGS = -Wl,-z,relro -Wl,-z,now + + SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \ +- $(SHLIB_LDFLAGS) \ ++ $(SHLIB_LDFLAGS) $(SHLIB_EXTRA_LDFLAGS) \ + -o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \ + $(SHLIB_OBJS) $(SHLIB_LC) && \ + rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \ diff --git a/SOURCES/gcc8-libgomp-omp_h-multilib.patch b/SOURCES/gcc8-libgomp-omp_h-multilib.patch new file mode 100644 index 0000000..d0e98d1 --- /dev/null +++ b/SOURCES/gcc8-libgomp-omp_h-multilib.patch @@ -0,0 +1,17 @@ +2008-06-09 Jakub Jelinek + + * omp.h.in (omp_nest_lock_t): Fix up for Linux multilibs. + +--- libgomp/omp.h.in.jj 2008-06-09 13:34:05.000000000 +0200 ++++ libgomp/omp.h.in 2008-06-09 13:34:48.000000000 +0200 +@@ -42,8 +42,8 @@ typedef struct + + typedef struct + { +- unsigned char _x[@OMP_NEST_LOCK_SIZE@] +- __attribute__((__aligned__(@OMP_NEST_LOCK_ALIGN@))); ++ unsigned char _x[8 + sizeof (void *)] ++ __attribute__((__aligned__(sizeof (void *)))); + } omp_nest_lock_t; + #endif + diff --git a/SOURCES/gcc8-libgomp-testsuite.patch b/SOURCES/gcc8-libgomp-testsuite.patch new file mode 100644 index 0000000..502ee22 --- /dev/null +++ b/SOURCES/gcc8-libgomp-testsuite.patch @@ -0,0 +1,41 @@ +--- libgomp/testsuite/libgomp-test-support.exp.in.jj 2018-04-25 09:40:31.323655308 +0200 ++++ libgomp/testsuite/libgomp-test-support.exp.in 2019-04-25 20:01:50.028243827 +0200 +@@ -2,4 +2,5 @@ set cuda_driver_include "@CUDA_DRIVER_IN + set cuda_driver_lib "@CUDA_DRIVER_LIB@" + set hsa_runtime_lib "@HSA_RUNTIME_LIB@" + ++set offload_plugins "@offload_plugins@" + set offload_targets "@offload_targets@" +--- libgomp/testsuite/lib/libgomp.exp.jj 2018-04-25 09:40:31.584655429 +0200 ++++ libgomp/testsuite/lib/libgomp.exp 2019-05-24 11:41:51.015822702 +0200 +@@ -40,7 +40,7 @@ load_file libgomp-test-support.exp + # Populate offload_targets_s (offloading targets separated by a space), and + # offload_targets_s_openacc (the same, but with OpenACC names; OpenACC spells + # some of them a little differently). +-set offload_targets_s [split $offload_targets ","] ++set offload_targets_s [split $offload_plugins ","] + set offload_targets_s_openacc {} + foreach offload_target_openacc $offload_targets_s { + # Translate to OpenACC names, or skip if not yet supported. +@@ -137,8 +137,8 @@ proc libgomp_init { args } { + + # Add liboffloadmic build directory in LD_LIBRARY_PATH to support + # non-fallback testing for Intel MIC targets +- global offload_targets +- if { [string match "*,intelmic,*" ",$offload_targets,"] } { ++ global offload_plugins ++ if { [string match "*,intelmic,*" ",$offload_plugins,"] } { + append always_ld_library_path ":${blddir}/../liboffloadmic/.libs" + append always_ld_library_path ":${blddir}/../liboffloadmic/plugin/.libs" + # libstdc++ is required by liboffloadmic +@@ -362,8 +362,8 @@ proc check_effective_target_offload_devi + # Return 1 if configured for nvptx offloading. + + proc check_effective_target_openacc_nvidia_accel_configured { } { +- global offload_targets +- if { ![string match "*,nvptx,*" ",$offload_targets,"] } { ++ global offload_plugins ++ if { ![string match "*,nvptx,*" ",$offload_plugins,"] } { + return 0 + } + # PR libgomp/65099: Currently, we only support offloading in 64-bit diff --git a/SOURCES/gcc8-libtool-no-rpath.patch b/SOURCES/gcc8-libtool-no-rpath.patch new file mode 100644 index 0000000..466c661 --- /dev/null +++ b/SOURCES/gcc8-libtool-no-rpath.patch @@ -0,0 +1,27 @@ +libtool sucks. +--- ltmain.sh.jj 2007-12-07 14:53:21.000000000 +0100 ++++ ltmain.sh 2008-09-05 21:51:48.000000000 +0200 +@@ -5394,6 +5394,7 @@ EOF + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do ++ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then +@@ -6071,6 +6072,7 @@ EOF + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do ++ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then +@@ -6120,6 +6122,7 @@ EOF + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do ++ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then diff --git a/SOURCES/gcc8-mcet.patch b/SOURCES/gcc8-mcet.patch new file mode 100644 index 0000000..6fb78ca --- /dev/null +++ b/SOURCES/gcc8-mcet.patch @@ -0,0 +1,17 @@ +2018-04-24 Jakub Jelinek + + * config/i386/i386.opt (mcet): Remporarily re-add as alias to -mshstk. + +--- gcc/config/i386/i386.opt (revision 259613) ++++ gcc/config/i386/i386.opt (revision 259612) +@@ -1006,6 +1006,10 @@ mgeneral-regs-only + Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save + Generate code which uses only the general registers. + ++mcet ++Target Undocumented Alias(mshstk) ++;; Deprecated ++ + mshstk + Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save + Enable shadow stack built-in functions from Control-flow Enforcement diff --git a/SOURCES/gcc8-no-add-needed.patch b/SOURCES/gcc8-no-add-needed.patch new file mode 100644 index 0000000..aa2f52d --- /dev/null +++ b/SOURCES/gcc8-no-add-needed.patch @@ -0,0 +1,50 @@ +2010-02-08 Roland McGrath + + * config/rs6000/sysv4.h (LINK_EH_SPEC): Pass --no-add-needed to the + linker. + * config/gnu-user.h (LINK_EH_SPEC): Likewise. + * config/alpha/elf.h (LINK_EH_SPEC): Likewise. + * config/ia64/linux.h (LINK_EH_SPEC): Likewise. + +--- gcc/config/alpha/elf.h.jj 2011-01-03 12:52:31.118056764 +0100 ++++ gcc/config/alpha/elf.h 2011-01-04 18:14:10.931874160 +0100 +@@ -168,5 +168,5 @@ extern int alpha_this_gpdisp_sequence_nu + I imagine that other systems will catch up. In the meantime, it + doesn't harm to make sure that the data exists to be used later. */ + #if defined(HAVE_LD_EH_FRAME_HDR) +-#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} " ++#define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} " + #endif +--- gcc/config/ia64/linux.h.jj 2011-01-03 13:02:11.462994522 +0100 ++++ gcc/config/ia64/linux.h 2011-01-04 18:14:10.931874160 +0100 +@@ -76,7 +76,7 @@ do { \ + Signalize that because we have fde-glibc, we don't need all C shared libs + linked against -lgcc_s. */ + #undef LINK_EH_SPEC +-#define LINK_EH_SPEC "" ++#define LINK_EH_SPEC "--no-add-needed " + + #undef TARGET_INIT_LIBFUNCS + #define TARGET_INIT_LIBFUNCS ia64_soft_fp_init_libfuncs +--- gcc/config/gnu-user.h.jj 2011-01-03 12:53:03.739057299 +0100 ++++ gcc/config/gnu-user.h 2011-01-04 18:14:10.932814884 +0100 +@@ -133,7 +133,7 @@ see the files COPYING3 and COPYING.RUNTI + #define LIB_SPEC GNU_USER_TARGET_LIB_SPEC + + #if defined(HAVE_LD_EH_FRAME_HDR) +-#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} " ++#define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} " + #endif + + #undef LINK_GCC_C_SEQUENCE_SPEC +--- gcc/config/rs6000/sysv4.h.jj 2011-01-03 13:02:18.255994215 +0100 ++++ gcc/config/rs6000/sysv4.h 2011-01-04 18:14:10.933888871 +0100 +@@ -816,7 +816,7 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEF + -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}" + + #if defined(HAVE_LD_EH_FRAME_HDR) +-# define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} " ++# define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} " + #endif + + #define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \ diff --git a/SOURCES/gcc8-rh1512529-aarch64.patch b/SOURCES/gcc8-rh1512529-aarch64.patch new file mode 100644 index 0000000..4030027 --- /dev/null +++ b/SOURCES/gcc8-rh1512529-aarch64.patch @@ -0,0 +1,445 @@ +--- gcc/config/aarch64/aarch64.c ++++ gcc/config/aarch64/aarch64.c +@@ -3799,7 +3799,14 @@ aarch64_output_probe_stack_range (rtx reg1, rtx reg2) + output_asm_insn ("sub\t%0, %0, %1", xops); + + /* Probe at TEST_ADDR. */ +- output_asm_insn ("str\txzr, [%0]", xops); ++ if (flag_stack_clash_protection) ++ { ++ gcc_assert (xops[0] == stack_pointer_rtx); ++ xops[1] = GEN_INT (PROBE_INTERVAL - 8); ++ output_asm_insn ("str\txzr, [%0, %1]", xops); ++ } ++ else ++ output_asm_insn ("str\txzr, [%0]", xops); + + /* Test if TEST_ADDR == LAST_ADDR. */ + xops[1] = reg2; +@@ -4589,6 +4596,133 @@ aarch64_set_handled_components (sbitmap components) + cfun->machine->reg_is_wrapped_separately[regno] = true; + } + ++/* Allocate POLY_SIZE bytes of stack space using TEMP1 and TEMP2 as scratch ++ registers. */ ++ ++static void ++aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, ++ poly_int64 poly_size) ++{ ++ HOST_WIDE_INT size; ++ if (!poly_size.is_constant (&size)) ++ { ++ sorry ("stack probes for SVE frames"); ++ return; ++ } ++ ++ HOST_WIDE_INT probe_interval ++ = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL); ++ HOST_WIDE_INT guard_size ++ = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE); ++ HOST_WIDE_INT guard_used_by_caller = 1024; ++ ++ /* SIZE should be large enough to require probing here. ie, it ++ must be larger than GUARD_SIZE - GUARD_USED_BY_CALLER. ++ ++ We can allocate GUARD_SIZE - GUARD_USED_BY_CALLER as a single chunk ++ without any probing. */ ++ gcc_assert (size >= guard_size - guard_used_by_caller); ++ aarch64_sub_sp (temp1, temp2, guard_size - guard_used_by_caller, true); ++ HOST_WIDE_INT orig_size = size; ++ size -= (guard_size - guard_used_by_caller); ++ ++ HOST_WIDE_INT rounded_size = size & -probe_interval; ++ HOST_WIDE_INT residual = size - rounded_size; ++ ++ /* We can handle a small number of allocations/probes inline. Otherwise ++ punt to a loop. */ ++ if (rounded_size && rounded_size <= 4 * probe_interval) ++ { ++ /* We don't use aarch64_sub_sp here because we don't want to ++ repeatedly load TEMP1. */ ++ rtx step = GEN_INT (-probe_interval); ++ if (probe_interval > ARITH_FACTOR) ++ { ++ emit_move_insn (temp1, step); ++ step = temp1; ++ } ++ ++ for (HOST_WIDE_INT i = 0; i < rounded_size; i += probe_interval) ++ { ++ rtx_insn *insn = emit_insn (gen_add2_insn (stack_pointer_rtx, step)); ++ add_reg_note (insn, REG_STACK_CHECK, const0_rtx); ++ ++ if (probe_interval > ARITH_FACTOR) ++ { ++ RTX_FRAME_RELATED_P (insn) = 1; ++ rtx adj = plus_constant (Pmode, stack_pointer_rtx, -probe_interval); ++ add_reg_note (insn, REG_CFA_ADJUST_CFA, ++ gen_rtx_SET (stack_pointer_rtx, adj)); ++ } ++ ++ emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, ++ (probe_interval ++ - GET_MODE_SIZE (word_mode)))); ++ emit_insn (gen_blockage ()); ++ } ++ dump_stack_clash_frame_info (PROBE_INLINE, size != rounded_size); ++ } ++ else if (rounded_size) ++ { ++ /* Compute the ending address. */ ++ unsigned int scratchreg = REGNO (temp1); ++ emit_move_insn (temp1, GEN_INT (-rounded_size)); ++ rtx_insn *insn ++ = emit_insn (gen_add3_insn (temp1, stack_pointer_rtx, temp1)); ++ ++ /* For the initial allocation, we don't have a frame pointer ++ set up, so we always need CFI notes. If we're doing the ++ final allocation, then we may have a frame pointer, in which ++ case it is the CFA, otherwise we need CFI notes. ++ ++ We can determine which allocation we are doing by looking at ++ the temporary register. IP0 is the initial allocation, IP1 ++ is the final allocation. */ ++ if (scratchreg == IP0_REGNUM || !frame_pointer_needed) ++ { ++ /* We want the CFA independent of the stack pointer for the ++ duration of the loop. */ ++ add_reg_note (insn, REG_CFA_DEF_CFA, ++ plus_constant (Pmode, temp1, ++ (rounded_size + (orig_size - size)))); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ } ++ ++ /* This allocates and probes the stack. ++ ++ It also probes at a 4k interval regardless of the value of ++ PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL. */ ++ insn = emit_insn (gen_probe_stack_range (stack_pointer_rtx, ++ stack_pointer_rtx, temp1)); ++ ++ /* Now reset the CFA register if needed. */ ++ if (scratchreg == IP0_REGNUM || !frame_pointer_needed) ++ { ++ add_reg_note (insn, REG_CFA_DEF_CFA, ++ plus_constant (Pmode, stack_pointer_rtx, ++ (rounded_size + (orig_size - size)))); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ } ++ ++ emit_insn (gen_blockage ()); ++ dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size); ++ } ++ else ++ dump_stack_clash_frame_info (PROBE_INLINE, size != rounded_size); ++ ++ /* Handle any residuals. ++ Note that any residual must be probed. */ ++ if (residual) ++ { ++ aarch64_sub_sp (temp1, temp2, residual, true); ++ add_reg_note (get_last_insn (), REG_STACK_CHECK, const0_rtx); ++ emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, ++ (residual - GET_MODE_SIZE (word_mode)))); ++ emit_insn (gen_blockage ()); ++ } ++ return; ++} ++ + /* Add a REG_CFA_EXPRESSION note to INSN to say that register REG + is saved at BASE + OFFSET. */ + +@@ -4686,7 +4820,54 @@ aarch64_expand_prologue (void) + rtx ip0_rtx = gen_rtx_REG (Pmode, IP0_REGNUM); + rtx ip1_rtx = gen_rtx_REG (Pmode, IP1_REGNUM); + +- aarch64_sub_sp (ip0_rtx, ip1_rtx, initial_adjust, true); ++ /* We do not fully protect aarch64 against stack clash style attacks ++ as doing so would be prohibitively expensive with less utility over ++ time as newer compilers are deployed. ++ ++ We assume the guard is at least 64k. Furthermore, we assume that ++ the caller has not pushed the stack pointer more than 1k into ++ the guard. A caller that pushes the stack pointer than 1k into ++ the guard is considered invalid. ++ ++ Note that the caller's ability to push the stack pointer into the ++ guard is a function of the number and size of outgoing arguments and/or ++ dynamic stack allocations due to the mandatory save of the link register ++ in the caller's frame. ++ ++ With those assumptions the callee can allocate up to 63k of stack ++ space without probing. ++ ++ When probing is needed, we emit a probe at the start of the prologue ++ and every PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL bytes thereafter. ++ ++ We have to track how much space has been allocated, but we do not ++ track stores into the stack as implicit probes except for the ++ fp/lr store. */ ++ HOST_WIDE_INT guard_size ++ = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE); ++ HOST_WIDE_INT guard_used_by_caller = 1024; ++ if (flag_stack_clash_protection) ++ { ++ if (known_eq (frame_size, 0)) ++ dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false); ++ else if (known_lt (initial_adjust, guard_size - guard_used_by_caller) ++ && known_lt (final_adjust, guard_size - guard_used_by_caller)) ++ dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true); ++ } ++ ++ /* In theory we should never have both an initial adjustment ++ and a callee save adjustment. Verify that is the case since the ++ code below does not handle it for -fstack-clash-protection. */ ++ gcc_assert (known_eq (initial_adjust, 0) || callee_adjust == 0); ++ ++ /* Only probe if the initial adjustment is larger than the guard ++ less the amount of the guard reserved for use by the caller's ++ outgoing args. */ ++ if (flag_stack_clash_protection ++ && maybe_ge (initial_adjust, guard_size - guard_used_by_caller)) ++ aarch64_allocate_and_probe_stack_space (ip0_rtx, ip1_rtx, initial_adjust); ++ else ++ aarch64_sub_sp (ip0_rtx, ip1_rtx, initial_adjust, true); + + if (callee_adjust != 0) + aarch64_push_regs (reg1, reg2, callee_adjust); +@@ -4742,7 +4923,31 @@ aarch64_expand_prologue (void) + callee_adjust != 0 || emit_frame_chain); + aarch64_save_callee_saves (DFmode, callee_offset, V0_REGNUM, V31_REGNUM, + callee_adjust != 0 || emit_frame_chain); +- aarch64_sub_sp (ip1_rtx, ip0_rtx, final_adjust, !frame_pointer_needed); ++ ++ /* We may need to probe the final adjustment as well. */ ++ if (flag_stack_clash_protection && maybe_ne (final_adjust, 0)) ++ { ++ /* First probe if the final adjustment is larger than the guard size ++ less the amount of the guard reserved for use by the caller's ++ outgoing args. */ ++ if (maybe_ge (final_adjust, guard_size - guard_used_by_caller)) ++ aarch64_allocate_and_probe_stack_space (ip1_rtx, ip0_rtx, ++ final_adjust); ++ else ++ aarch64_sub_sp (ip1_rtx, ip0_rtx, final_adjust, !frame_pointer_needed); ++ ++ /* We must also probe if the final adjustment is larger than the guard ++ that is assumed used by the caller. This may be sub-optimal. */ ++ if (maybe_ge (final_adjust, guard_used_by_caller)) ++ { ++ if (dump_file) ++ fprintf (dump_file, ++ "Stack clash aarch64 large outgoing arg, probing\n"); ++ emit_stack_probe (stack_pointer_rtx); ++ } ++ } ++ else ++ aarch64_sub_sp (ip1_rtx, ip0_rtx, final_adjust, !frame_pointer_needed); + } + + /* Return TRUE if we can use a simple_return insn. +@@ -10476,6 +10681,12 @@ aarch64_override_options_internal (struct gcc_options *opts) + && opts->x_optimize >= aarch64_tune_params.prefetch->default_opt_level) + opts->x_flag_prefetch_loop_arrays = 1; + ++ /* We assume the guard page is 64k. */ ++ maybe_set_param_value (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE, ++ 16, ++ opts->x_param_values, ++ global_options_set.x_param_values); ++ + aarch64_override_options_after_change_1 (opts); + } + +@@ -17161,6 +17372,28 @@ aarch64_sched_can_speculate_insn (rtx_insn *insn) + } + } + ++/* It has been decided that to allow up to 1kb of outgoing argument ++ space to be allocated w/o probing. If more than 1kb of outgoing ++ argment space is allocated, then it must be probed and the last ++ probe must occur no more than 1kbyte away from the end of the ++ allocated space. ++ ++ This implies that the residual part of an alloca allocation may ++ need probing in cases where the generic code might not otherwise ++ think a probe is needed. ++ ++ This target hook returns TRUE when allocating RESIDUAL bytes of ++ alloca space requires an additional probe, otherwise FALSE is ++ returned. */ ++ ++static bool ++aarch64_stack_clash_protection_final_dynamic_probe (rtx residual) ++{ ++ return (residual == CONST0_RTX (Pmode) ++ || GET_CODE (residual) != CONST_INT ++ || INTVAL (residual) >= 1024); ++} ++ + /* Implement TARGET_COMPUTE_PRESSURE_CLASSES. */ + + static int +@@ -17669,6 +17902,10 @@ aarch64_libgcc_floating_mode_supported_p + #undef TARGET_CONSTANT_ALIGNMENT + #define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment + ++#undef TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE ++#define TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE \ ++ aarch64_stack_clash_protection_final_dynamic_probe ++ + #undef TARGET_COMPUTE_PRESSURE_CLASSES + #define TARGET_COMPUTE_PRESSURE_CLASSES aarch64_compute_pressure_classes + +--- gcc/config/aarch64/aarch64.md ++++ gcc/config/aarch64/aarch64.md +@@ -5812,7 +5812,7 @@ + ) + + (define_insn "probe_stack_range" +- [(set (match_operand:DI 0 "register_operand" "=r") ++ [(set (match_operand:DI 0 "register_operand" "=rk") + (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "register_operand" "r")] + UNSPECV_PROBE_STACK_RANGE))] +--- gcc/testsuite/gcc.target/aarch64/stack-check-12.c ++++ gcc/testsuite/gcc.target/aarch64/stack-check-12.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */ ++/* { dg-require-effective-target supports_stack_clash_protection } */ ++ ++extern void arf (unsigned long int *, unsigned long int *); ++void ++frob () ++{ ++ unsigned long int num[1000]; ++ unsigned long int den[1000]; ++ arf (den, num); ++} ++ ++/* This verifies that the scheduler did not break the dependencies ++ by adjusting the offsets within the probe and that the scheduler ++ did not reorder around the stack probes. */ ++/* { dg-final { scan-assembler-times "sub\\tsp, sp, #4096\\n\\tstr\\txzr, .sp, 4088." 3 } } */ ++ ++ ++ +--- gcc/testsuite/gcc.target/aarch64/stack-check-13.c ++++ gcc/testsuite/gcc.target/aarch64/stack-check-13.c +@@ -0,0 +1,28 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */ ++/* { dg-require-effective-target supports_stack_clash_protection } */ ++ ++#define ARG32(X) X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X ++#define ARG192(X) ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X) ++void out1(ARG192(__int128)); ++int t1(int); ++ ++int t3(int x) ++{ ++ if (x < 1000) ++ return t1 (x) + 1; ++ ++ out1 (ARG192(1)); ++ return 0; ++} ++ ++ ++ ++/* This test creates a large (> 1k) outgoing argument area that needs ++ to be probed. We don't test the exact size of the space or the ++ exact offset to make the test a little less sensitive to trivial ++ output changes. */ ++/* { dg-final { scan-assembler-times "sub\\tsp, sp, #....\\n\\tstr\\txzr, \\\[sp" 1 } } */ ++ ++ ++ +--- gcc/testsuite/gcc.target/aarch64/stack-check-14.c ++++ gcc/testsuite/gcc.target/aarch64/stack-check-14.c +@@ -0,0 +1,25 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */ ++/* { dg-require-effective-target supports_stack_clash_protection } */ ++ ++int t1(int); ++ ++int t2(int x) ++{ ++ char *p = __builtin_alloca (4050); ++ x = t1 (x); ++ return p[x]; ++} ++ ++ ++/* This test has a constant sized alloca that is smaller than the ++ probe interval. But it actually requires two probes instead ++ of one because of the optimistic assumptions we made in the ++ aarch64 prologue code WRT probing state. ++ ++ The form can change quite a bit so we just check for two ++ probes without looking at the actual address. */ ++/* { dg-final { scan-assembler-times "str\\txzr," 2 } } */ ++ ++ ++ +--- gcc/testsuite/gcc.target/aarch64/stack-check-15.c ++++ gcc/testsuite/gcc.target/aarch64/stack-check-15.c +@@ -0,0 +1,24 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */ ++/* { dg-require-effective-target supports_stack_clash_protection } */ ++ ++int t1(int); ++ ++int t2(int x) ++{ ++ char *p = __builtin_alloca (x); ++ x = t1 (x); ++ return p[x]; ++} ++ ++ ++/* This test has a variable sized alloca. It requires 3 probes. ++ One in the loop, one for the residual and at the end of the ++ alloca area. ++ ++ The form can change quite a bit so we just check for two ++ probes without looking at the actual address. */ ++/* { dg-final { scan-assembler-times "str\\txzr," 3 } } */ ++ ++ ++ +--- gcc/testsuite/lib/target-supports.exp ++++ gcc/testsuite/lib/target-supports.exp +@@ -9201,14 +9201,9 @@ proc check_effective_target_autoincdec { } { + # + proc check_effective_target_supports_stack_clash_protection { } { + +- # Temporary until the target bits are fully ACK'd. +-# if { [istarget aarch*-*-*] } { +-# return 1 +-# } +- + if { [istarget x86_64-*-*] || [istarget i?86-*-*] + || [istarget powerpc*-*-*] || [istarget rs6000*-*-*] +- || [istarget s390*-*-*] } { ++ || [istarget aarch64*-**] || [istarget s390*-*-*] } { + return 1 + } + return 0 +@@ -9217,9 +9212,9 @@ proc check_effective_target_supports_stack_clash_protection { } { + # Return 1 if the target creates a frame pointer for non-leaf functions + # Note we ignore cases where we apply tail call optimization here. + proc check_effective_target_frame_pointer_for_non_leaf { } { +- if { [istarget aarch*-*-*] } { +- return 1 +- } ++# if { [istarget aarch*-*-*] } { ++# return 1 ++# } + + # Solaris/x86 defaults to -fno-omit-frame-pointer. + if { [istarget i?86-*-solaris*] || [istarget x86_64-*-solaris*] } { diff --git a/SOURCES/gcc8-rh1574936.patch b/SOURCES/gcc8-rh1574936.patch new file mode 100644 index 0000000..32db990 --- /dev/null +++ b/SOURCES/gcc8-rh1574936.patch @@ -0,0 +1,31 @@ +crt files and statically linked libgcc objects cause false positives +in annobin coverage, so we add the assembler flag to generate notes +for them. + +The patch also adds notes to libgcc_s.so, but this is harmless because +these notes only confer that there is no other annobin markup. + +2018-07-25 Florian Weimer + + * Makefile.in (LIBGCC2_CFLAGS, CRTSTUFF_CFLAGS): Add + -Wa,--generate-missing-build-notes=yes. + +--- libgcc/Makefile.in 2018-01-13 13:05:41.000000000 +0100 ++++ libgcc/Makefile.in 2018-07-25 13:15:02.036226940 +0200 +@@ -244,6 +244,7 @@ + LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \ + $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \ + -fbuilding-libgcc -fno-stack-protector \ ++ -Wa,--generate-missing-build-notes=yes \ + $(INHIBIT_LIBC_CFLAGS) + + # Additional options to use when compiling libgcc2.a. +@@ -297,6 +298,7 @@ + $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \ + -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \ + -fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \ ++ -Wa,--generate-missing-build-notes=yes \ + $(INHIBIT_LIBC_CFLAGS) + + # Extra flags to use when compiling crt{begin,end}.o. + diff --git a/SOURCES/gcc8-rh1668903-1.patch b/SOURCES/gcc8-rh1668903-1.patch new file mode 100644 index 0000000..9ffff09 --- /dev/null +++ b/SOURCES/gcc8-rh1668903-1.patch @@ -0,0 +1,406 @@ +commit 126dab7c9d84294f256b1f7bf91c24a9e7103249 +Author: qinzhao +Date: Thu Nov 29 16:06:03 2018 +0000 + + Add a new option -flive-patching={inline-only-static|inline-clone} + to support live patching in GCC. + + 2018-11-29 qing zhao + + gcc/ChangeLog: + + * cif-code.def (EXTERN_LIVE_ONLY_STATIC): New CIF code. + * common.opt: Add -flive-patching flag. + * doc/invoke.texi: Document -flive-patching. + * flag-types.h (enum live_patching_level): New enum. + * ipa-inline.c (can_inline_edge_p): Disable external functions from + inlining when flag_live_patching is LIVE_PATCHING_INLINE_ONLY_STATIC. + * opts.c (control_options_for_live_patching): New function. + (finish_options): Make flag_live_patching incompatible with flag_lto. + Control IPA optimizations based on different levels of + flag_live_patching. + + gcc/testsuite/ChangeLog: + + * gcc.dg/live-patching-1.c: New test. + * gcc.dg/live-patching-2.c: New test. + * gcc.dg/live-patching-3.c: New test. + * gcc.dg/tree-ssa/writeonly-3.c: New test. + * gcc.target/i386/ipa-stack-alignment-2.c: New test. + + + git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266627 138bc75d-0d04-0410-961f-82ee72b054a4 + +--- gcc/cif-code.def ++++ gcc/cif-code.def +@@ -132,6 +132,12 @@ DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_ERROR, + DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR, + N_("function attribute mismatch")) + ++/* We can't inline because the user requests only static functions ++ but the function has external linkage for live patching purpose. */ ++DEFCIFCODE(EXTERN_LIVE_ONLY_STATIC, CIF_FINAL_ERROR, ++ N_("function has external linkage when the user requests only" ++ " inlining static for live patching")) ++ + /* We proved that the call is unreachable. */ + DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR, + N_("unreachable")) +--- gcc/common.opt ++++ gcc/common.opt +@@ -2181,6 +2181,24 @@ starts and when the destructor finishes. + flifetime-dse= + Common Joined RejectNegative UInteger Var(flag_lifetime_dse) Optimization IntegerRange(0, 2) + ++flive-patching ++Common RejectNegative Alias(flive-patching=,inline-clone) Optimization ++ ++flive-patching= ++Common Report Joined RejectNegative Enum(live_patching_level) Var(flag_live_patching) Init(LIVE_PATCHING_NONE) Optimization ++-flive-patching=[inline-only-static|inline-clone] Control IPA ++optimizations to provide a safe compilation for live-patching. At the same ++time, provides multiple-level control on the enabled IPA optimizations. ++ ++Enum ++Name(live_patching_level) Type(enum live_patching_level) UnknownError(unknown Live-Patching Level %qs) ++ ++EnumValue ++Enum(live_patching_level) String(inline-only-static) Value(LIVE_PATCHING_INLINE_ONLY_STATIC) ++ ++EnumValue ++Enum(live_patching_level) String(inline-clone) Value(LIVE_PATCHING_INLINE_CLONE) ++ + flive-range-shrinkage + Common Report Var(flag_live_range_shrinkage) Init(0) Optimization + Relief of register pressure through live range shrinkage. +--- gcc/doc/invoke.texi ++++ gcc/doc/invoke.texi +@@ -389,6 +389,7 @@ Objective-C and Objective-C++ Dialects}. + -fipa-bit-cp -fipa-vrp @gol + -fipa-pta -fipa-profile -fipa-pure-const -fipa-reference -fipa-icf @gol + -fira-algorithm=@var{algorithm} @gol ++-flive-patching=@var{level} @gol + -fira-region=@var{region} -fira-hoist-pressure @gol + -fira-loop-pressure -fno-ira-share-save-slots @gol + -fno-ira-share-spill-slots @gol +@@ -9291,6 +9292,65 @@ equivalences that are found only by GCC and equivalences found only by Gold. + + This flag is enabled by default at @option{-O2} and @option{-Os}. + ++@item -flive-patching=@var{level} ++@opindex flive-patching ++Control GCC's optimizations to provide a safe compilation for live-patching. ++ ++If the compiler's optimization uses a function's body or information extracted ++from its body to optimize/change another function, the latter is called an ++impacted function of the former. If a function is patched, its impacted ++functions should be patched too. ++ ++The impacted functions are decided by the compiler's interprocedural ++optimizations. For example, inlining a function into its caller, cloning ++a function and changing its caller to call this new clone, or extracting ++a function's pureness/constness information to optimize its direct or ++indirect callers, etc. ++ ++Usually, the more IPA optimizations enabled, the larger the number of ++impacted functions for each function. In order to control the number of ++impacted functions and computed the list of impacted function easily, ++we provide control to partially enable IPA optimizations on two different ++levels. ++ ++The @var{level} argument should be one of the following: ++ ++@table @samp ++ ++@item inline-clone ++ ++Only enable inlining and cloning optimizations, which includes inlining, ++cloning, interprocedural scalar replacement of aggregates and partial inlining. ++As a result, when patching a function, all its callers and its clones' ++callers need to be patched as well. ++ ++@option{-flive-patching=inline-clone} disables the following optimization flags: ++@gccoptlist{-fwhole-program -fipa-pta -fipa-reference -fipa-ra @gol ++-fipa-icf -fipa-icf-functions -fipa-icf-variables @gol ++-fipa-bit-cp -fipa-vrp -fipa-pure-const -fipa-reference-addressable @gol ++-fipa-stack-alignment} ++ ++@item inline-only-static ++ ++Only enable inlining of static functions. ++As a result, when patching a static function, all its callers need to be ++patches as well. ++ ++In addition to all the flags that -flive-patching=inline-clone disables, ++@option{-flive-patching=inline-only-static} disables the following additional ++optimization flags: ++@gccoptlist{-fipa-cp-clone -fipa-sra -fpartial-inlining -fipa-cp} ++ ++@end table ++ ++When -flive-patching specified without any value, the default value ++is "inline-clone". ++ ++This flag is disabled by default. ++ ++Note that -flive-patching is not supported with link-time optimizer. ++(@option{-flto}). ++ + @item -fisolate-erroneous-paths-dereference + @opindex fisolate-erroneous-paths-dereference + Detect paths that trigger erroneous or undefined behavior due to +--- gcc/flag-types.h ++++ gcc/flag-types.h +@@ -123,6 +123,14 @@ enum stack_reuse_level + SR_ALL + }; + ++/* The live patching level. */ ++enum live_patching_level ++{ ++ LIVE_PATCHING_NONE = 0, ++ LIVE_PATCHING_INLINE_ONLY_STATIC, ++ LIVE_PATCHING_INLINE_CLONE ++}; ++ + /* The algorithm used for basic block reordering. */ + enum reorder_blocks_algorithm + { +--- gcc/ipa-inline.c ++++ gcc/ipa-inline.c +@@ -379,6 +379,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, + e->inline_failed = CIF_ATTRIBUTE_MISMATCH; + inlinable = false; + } ++ else if (callee->externally_visible ++ && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC) ++ { ++ e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC; ++ inlinable = false; ++ } + if (!inlinable && report) + report_inline_failed_reason (e); + return inlinable; +--- gcc/opts.c ++++ gcc/opts.c +@@ -699,6 +699,152 @@ default_options_optimization (struct gcc + lang_mask, handlers, loc, dc); + } + ++/* Control IPA optimizations based on different live patching LEVEL. */ ++static void ++control_options_for_live_patching (struct gcc_options *opts, ++ struct gcc_options *opts_set, ++ enum live_patching_level level, ++ location_t loc) ++{ ++ gcc_assert (level > LIVE_PATCHING_NONE); ++ ++ switch (level) ++ { ++ case LIVE_PATCHING_INLINE_ONLY_STATIC: ++ if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone) ++ error_at (loc, ++ "%<-fipa-cp-clone%> is incompatible with " ++ "%<-flive-patching=inline-only-static%>"); ++ else ++ opts->x_flag_ipa_cp_clone = 0; ++ ++ if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra) ++ error_at (loc, ++ "%<-fipa-sra%> is incompatible with " ++ "%<-flive-patching=inline-only-static%>"); ++ else ++ opts->x_flag_ipa_sra = 0; ++ ++ if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining) ++ error_at (loc, ++ "%<-fpartial-inlining%> is incompatible with " ++ "%<-flive-patching=inline-only-static%>"); ++ else ++ opts->x_flag_partial_inlining = 0; ++ ++ if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp) ++ error_at (loc, ++ "%<-fipa-cp%> is incompatible with " ++ "%<-flive-patching=inline-only-static%>"); ++ else ++ opts->x_flag_ipa_cp = 0; ++ ++ /* FALLTHROUGH. */ ++ case LIVE_PATCHING_INLINE_CLONE: ++ /* live patching should disable whole-program optimization. */ ++ if (opts_set->x_flag_whole_program && opts->x_flag_whole_program) ++ error_at (loc, ++ "%<-fwhole-program%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_whole_program = 0; ++ ++ /* visibility change should be excluded by !flag_whole_program ++ && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra ++ && !flag_partial_inlining. */ ++ ++ if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta) ++ error_at (loc, ++ "%<-fipa-pta%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_pta = 0; ++ ++ if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference) ++ error_at (loc, ++ "%<-fipa-reference%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_reference = 0; ++ ++ if (opts_set->x_flag_ipa_ra && opts->x_flag_ipa_ra) ++ error_at (loc, ++ "%<-fipa-ra%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_ra = 0; ++ ++ if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf) ++ error_at (loc, ++ "%<-fipa-icf%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_icf = 0; ++ ++ if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions) ++ error_at (loc, ++ "%<-fipa-icf-functions%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_icf_functions = 0; ++ ++ if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables) ++ error_at (loc, ++ "%<-fipa-icf-variables%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_icf_variables = 0; ++ ++ if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp) ++ error_at (loc, ++ "%<-fipa-bit-cp%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_bit_cp = 0; ++ ++ if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp) ++ error_at (loc, ++ "%<-fipa-vrp%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_vrp = 0; ++ ++ if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const) ++ error_at (loc, ++ "%<-fipa-pure-const%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_pure_const = 0; ++ ++ /* FIXME: disable unreachable code removal. */ ++ ++ /* discovery of functions/variables with no address taken. */ ++// GCC 8 doesn't have these options. ++#if 0 ++ if (opts_set->x_flag_ipa_reference_addressable ++ && opts->x_flag_ipa_reference_addressable) ++ error_at (loc, ++ "%<-fipa-reference-addressable%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_reference_addressable = 0; ++ ++ /* ipa stack alignment propagation. */ ++ if (opts_set->x_flag_ipa_stack_alignment ++ && opts->x_flag_ipa_stack_alignment) ++ error_at (loc, ++ "%<-fipa-stack-alignment%> is incompatible with " ++ "%<-flive-patching=inline-only-static|inline-clone%>"); ++ else ++ opts->x_flag_ipa_stack_alignment = 0; ++#endif ++ ++ break; ++ default: ++ gcc_unreachable (); ++ } ++} ++ + /* After all options at LOC have been read into OPTS and OPTS_SET, + finalize settings of those options and diagnose incompatible + combinations. */ +@@ -1057,6 +1203,18 @@ finish_options (struct gcc_options *opts + sorry ("transactional memory is not supported with " + "%<-fsanitize=kernel-address%>"); + ++ /* Currently live patching is not support for LTO. */ ++ if (opts->x_flag_live_patching && opts->x_flag_lto) ++ sorry ("live patching is not supported with LTO"); ++ ++ /* Control IPA optimizations based on different -flive-patching level. */ ++ if (opts->x_flag_live_patching) ++ { ++ control_options_for_live_patching (opts, opts_set, ++ opts->x_flag_live_patching, ++ loc); ++ } ++ + /* Comes from final.c -- no real reason to change it. */ + #define MAX_CODE_ALIGN 16 + #define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN) +--- /dev/null ++++ gcc/testsuite/gcc.dg/live-patching-1.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -flive-patching=inline-only-static -fdump-ipa-inline" } */ ++ ++extern int sum, n, m; ++ ++int foo (int a) ++{ ++ return a + n; ++} ++ ++static int bar (int b) ++{ ++ return b * m; ++} ++ ++int main() ++{ ++ sum = foo (m) + bar (n); ++ return 0; ++} ++ ++/* { dg-final { scan-ipa-dump "foo/0 function has external linkage when the user requests only inlining static for live patching" "inline" } } */ +--- /dev/null ++++ gcc/testsuite/gcc.dg/live-patching-2.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -flive-patching -flto" } */ ++ ++int main() ++{ ++ return 0; ++} ++ ++/* { dg-message "sorry, unimplemented: live patching is not supported with LTO" "-flive-patching and -flto together" { target *-*-* } 0 } */ +--- /dev/null ++++ gcc/testsuite/gcc.dg/live-patching-3.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O1 -flive-patching -fwhole-program" } */ ++ ++int main() ++{ ++ return 0; ++} ++ ++/* { dg-message "'-fwhole-program' is incompatible with '-flive-patching=inline-only-static|inline-clone’" "" {target "*-*-*"} 0 } */ diff --git a/SOURCES/gcc8-rh1668903-2.patch b/SOURCES/gcc8-rh1668903-2.patch new file mode 100644 index 0000000..92eaf54 --- /dev/null +++ b/SOURCES/gcc8-rh1668903-2.patch @@ -0,0 +1,73 @@ +commit 9939b2f79bd9b75b99080a17f3d6f1214d543477 +Author: qinzhao +Date: Wed Apr 3 19:00:25 2019 +0000 + + 2019-04-03 qing zhao + + PR tree-optimization/89730 + * ipa-inline.c (can_inline_edge_p): Delete the checking for + -flive-patching=inline-only-static. + (can_inline_edge_by_limits_p): Add the checking for + -flive-patching=inline-only-static and grant always_inline + even when -flive-patching=inline-only-static is specified. + + * gcc.dg/live-patching-4.c: New test. + + + git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270134 138bc75d-0d04-0410-961f-82ee72b054a4 + +--- gcc/ipa-inline.c ++++ gcc/ipa-inline.c +@@ -385,12 +385,6 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, + e->inline_failed = CIF_ATTRIBUTE_MISMATCH; + inlinable = false; + } +- else if (callee->externally_visible +- && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC) +- { +- e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC; +- inlinable = false; +- } + if (!inlinable && report) + report_inline_failed_reason (e); + return inlinable; +@@ -433,6 +427,13 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report, + DECL_ATTRIBUTES (caller->decl)) + && !caller_growth_limits (e)) + inlinable = false; ++ else if (callee->externally_visible ++ && !DECL_DISREGARD_INLINE_LIMITS (callee->decl) ++ && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC) ++ { ++ e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC; ++ inlinable = false; ++ } + /* Don't inline a function with a higher optimization level than the + caller. FIXME: this is really just tip of iceberg of handling + optimization attribute. */ +--- /dev/null ++++ gcc/testsuite/gcc.dg/live-patching-4.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -flive-patching=inline-only-static -fdump-tree-einline-optimized" } */ ++ ++extern int sum, n, m; ++ ++extern inline __attribute__((always_inline)) int foo (int a); ++inline __attribute__((always_inline)) int foo (int a) ++{ ++ return a + n; ++} ++ ++static int bar (int b) ++{ ++ return b * m; ++} ++ ++int main() ++{ ++ sum = foo (m) + bar (n); ++ return 0; ++} ++ ++/* { dg-final { scan-tree-dump "Inlining foo into main" "einline" } } */ diff --git a/SOURCES/gcc8-rh1668903-3.patch b/SOURCES/gcc8-rh1668903-3.patch new file mode 100644 index 0000000..129d037 --- /dev/null +++ b/SOURCES/gcc8-rh1668903-3.patch @@ -0,0 +1,85 @@ +commit 77e6311332590004c5aec82ceeb45e4d4d93f690 +Author: redi +Date: Thu Apr 11 08:52:22 2019 +0000 + + Clarify documentation for -flive-patching + + * doc/invoke.texi (Optimize Options): Clarify -flive-patching docs. + + git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270276 138bc75d-0d04-0410-961f-82ee72b054a4 + +--- gcc/doc/invoke.texi ++++ gcc/doc/invoke.texi +@@ -9367,24 +9367,24 @@ This flag is enabled by default at @option{-O2} and @option{-Os}. + + @item -flive-patching=@var{level} + @opindex flive-patching +-Control GCC's optimizations to provide a safe compilation for live-patching. ++Control GCC's optimizations to produce output suitable for live-patching. + + If the compiler's optimization uses a function's body or information extracted + from its body to optimize/change another function, the latter is called an + impacted function of the former. If a function is patched, its impacted + functions should be patched too. + +-The impacted functions are decided by the compiler's interprocedural +-optimizations. For example, inlining a function into its caller, cloning +-a function and changing its caller to call this new clone, or extracting +-a function's pureness/constness information to optimize its direct or +-indirect callers, etc. ++The impacted functions are determined by the compiler's interprocedural ++optimizations. For example, a caller is impacted when inlining a function ++into its caller, ++cloning a function and changing its caller to call this new clone, ++or extracting a function's pureness/constness information to optimize ++its direct or indirect callers, etc. + + Usually, the more IPA optimizations enabled, the larger the number of + impacted functions for each function. In order to control the number of +-impacted functions and computed the list of impacted function easily, +-we provide control to partially enable IPA optimizations on two different +-levels. ++impacted functions and more easily compute the list of impacted function, ++IPA optimizations can be partially enabled at two different levels. + + The @var{level} argument should be one of the following: + +@@ -9395,7 +9395,7 @@ The @var{level} argument should be one of the following: + Only enable inlining and cloning optimizations, which includes inlining, + cloning, interprocedural scalar replacement of aggregates and partial inlining. + As a result, when patching a function, all its callers and its clones' +-callers need to be patched as well. ++callers are impacted, therefore need to be patched as well. + + @option{-flive-patching=inline-clone} disables the following optimization flags: + @gccoptlist{-fwhole-program -fipa-pta -fipa-reference -fipa-ra @gol +@@ -9406,22 +9406,23 @@ callers need to be patched as well. + @item inline-only-static + + Only enable inlining of static functions. +-As a result, when patching a static function, all its callers need to be +-patches as well. ++As a result, when patching a static function, all its callers are impacted ++and so need to be patched as well. + +-In addition to all the flags that -flive-patching=inline-clone disables, ++In addition to all the flags that @option{-flive-patching=inline-clone} ++disables, + @option{-flive-patching=inline-only-static} disables the following additional + optimization flags: + @gccoptlist{-fipa-cp-clone -fipa-sra -fpartial-inlining -fipa-cp} + + @end table + +-When -flive-patching specified without any value, the default value +-is "inline-clone". ++When @option{-flive-patching} is specified without any value, the default value ++is @var{inline-clone}. + + This flag is disabled by default. + +-Note that -flive-patching is not supported with link-time optimizer. ++Note that @option{-flive-patching} is not supported with link-time optimization + (@option{-flto}). + + @item -fisolate-erroneous-paths-dereference diff --git a/SOURCES/gcc8-rh1670535.patch b/SOURCES/gcc8-rh1670535.patch new file mode 100644 index 0000000..961c278 --- /dev/null +++ b/SOURCES/gcc8-rh1670535.patch @@ -0,0 +1,93 @@ +2018-11-08 Roman Geissler + + * collect2.c (linker_select): Add USE_LLD_LD. + (ld_suffixes): Add ld.lld. + (main): Handle -fuse-ld=lld. + * common.opt (-fuse-ld=lld): New option. + * doc/invoke.texi (-fuse-ld=lld): Document. + * opts.c (common_handle_option): Handle OPT_fuse_ld_lld. + +--- gcc/collect2.c ++++ gcc/collect2.c +@@ -831,6 +831,7 @@ main (int argc, char **argv) + USE_PLUGIN_LD, + USE_GOLD_LD, + USE_BFD_LD, ++ USE_LLD_LD, + USE_LD_MAX + } selected_linker = USE_DEFAULT_LD; + static const char *const ld_suffixes[USE_LD_MAX] = +@@ -838,7 +839,8 @@ main (int argc, char **argv) + "ld", + PLUGIN_LD_SUFFIX, + "ld.gold", +- "ld.bfd" ++ "ld.bfd", ++ "ld.lld" + }; + static const char *const real_ld_suffix = "real-ld"; + static const char *const collect_ld_suffix = "collect-ld"; +@@ -1007,6 +1009,8 @@ main (int argc, char **argv) + selected_linker = USE_BFD_LD; + else if (strcmp (argv[i], "-fuse-ld=gold") == 0) + selected_linker = USE_GOLD_LD; ++ else if (strcmp (argv[i], "-fuse-ld=lld") == 0) ++ selected_linker = USE_LLD_LD; + + #ifdef COLLECT_EXPORT_LIST + /* These flags are position independent, although their order +@@ -1096,7 +1100,8 @@ main (int argc, char **argv) + /* Maybe we know the right file to use (if not cross). */ + ld_file_name = 0; + #ifdef DEFAULT_LINKER +- if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD) ++ if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD || ++ selected_linker == USE_LLD_LD) + { + char *linker_name; + # ifdef HOST_EXECUTABLE_SUFFIX +@@ -1315,7 +1320,7 @@ main (int argc, char **argv) + else if (!use_collect_ld + && strncmp (arg, "-fuse-ld=", 9) == 0) + { +- /* Do not pass -fuse-ld={bfd|gold} to the linker. */ ++ /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */ + ld1--; + ld2--; + } +--- gcc/common.opt ++++ gcc/common.opt +@@ -2732,6 +2732,10 @@ fuse-ld=gold + Common Driver Negative(fuse-ld=bfd) + Use the gold linker instead of the default linker. + ++fuse-ld=lld ++Common Driver Negative(fuse-ld=lld) ++Use the lld LLVM linker instead of the default linker. ++ + fuse-linker-plugin + Common Undocumented Var(flag_use_linker_plugin) + +--- gcc/doc/invoke.texi ++++ gcc/doc/invoke.texi +@@ -12610,6 +12610,10 @@ Use the @command{bfd} linker instead of the default linker. + @opindex fuse-ld=gold + Use the @command{gold} linker instead of the default linker. + ++@item -fuse-ld=lld ++@opindex fuse-ld=lld ++Use the LLVM @command{lld} linker instead of the default linker. ++ + @cindex Libraries + @item -l@var{library} + @itemx -l @var{library} +--- gcc/opts.c ++++ gcc/opts.c +@@ -2557,6 +2557,7 @@ common_handle_option (struct gcc_options *opts, + + case OPT_fuse_ld_bfd: + case OPT_fuse_ld_gold: ++ case OPT_fuse_ld_lld: + case OPT_fuse_linker_plugin: + /* No-op. Used by the driver and passed to us because it starts with f.*/ + break; diff --git a/SOURCES/gcc8-rh1981822.patch b/SOURCES/gcc8-rh1981822.patch index af47325..08787bd 100644 --- a/SOURCES/gcc8-rh1981822.patch +++ b/SOURCES/gcc8-rh1981822.patch @@ -25,8 +25,6 @@ gcc/testsuite/ChangeLog: 2 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/lambda-defarg1.C -diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c -index 6c111342b97..4399165ee23 100644 --- gcc/cp/mangle.c +++ gcc/cp/mangle.c @@ -1628,6 +1628,7 @@ write_literal_operator_name (tree identifier) @@ -54,9 +52,6 @@ index 6c111342b97..4399165ee23 100644 write_char ('d'); write_compact_number (i - 1); } -diff --git a/gcc/testsuite/g++.dg/abi/lambda-defarg1.C b/gcc/testsuite/g++.dg/abi/lambda-defarg1.C -new file mode 100644 -index 00000000000..8c538581240 --- /dev/null +++ gcc/testsuite/g++.dg/abi/lambda-defarg1.C @@ -0,0 +1,11 @@ diff --git a/SOURCES/gcc8-sparc-config-detection.patch b/SOURCES/gcc8-sparc-config-detection.patch new file mode 100644 index 0000000..bb06b35 --- /dev/null +++ b/SOURCES/gcc8-sparc-config-detection.patch @@ -0,0 +1,40 @@ +--- gcc/config.gcc.jj 2008-04-24 15:42:46.000000000 -0500 ++++ gcc/config.gcc 2008-04-24 15:44:51.000000000 -0500 +@@ -2790,7 +2790,7 @@ sparc-*-rtems*) + tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/sp-elf.h sparc/rtemself.h rtems.h newlib-stdint.h" + tmake_file="${tmake_file} sparc/t-sparc sparc/t-rtems" + ;; +-sparc-*-linux*) ++sparc-*-linux* | sparcv9-*-linux*) + tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/tso.h" + extra_options="${extra_options} sparc/long-double-switch.opt" + case ${target} in +@@ -2844,7 +2844,7 @@ sparc64-*-rtems*) + extra_options="${extra_options}" + tmake_file="${tmake_file} sparc/t-sparc sparc/t-rtems-64" + ;; +-sparc64-*-linux*) ++sparc64*-*-linux*) + tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/default64.h sparc/linux64.h sparc/tso.h" + extra_options="${extra_options} sparc/long-double-switch.opt" + tmake_file="${tmake_file} sparc/t-sparc sparc/t-linux64" +--- libgcc/config.host.jj 2008-04-24 15:46:19.000000000 -0500 ++++ libgcc/config.host 2008-04-24 15:46:49.000000000 -0500 +@@ -1002,7 +1002,7 @@ sparc-*-elf*) + tmake_file="${tmake_file} t-fdpbit t-crtfm" + extra_parts="$extra_parts crti.o crtn.o crtfastmath.o" + ;; +-sparc-*-linux*) # SPARC's running GNU/Linux, libc6 ++sparc-*-linux* | sparcv9-*-linux*) # SPARC's running GNU/Linux, libc6 + tmake_file="${tmake_file} t-crtfm" + if test "${host_address}" = 64; then + tmake_file="$tmake_file sparc/t-linux64" +@@ -1050,7 +1050,7 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd* + tmake_file="$tmake_file t-crtfm" + extra_parts="$extra_parts crtfastmath.o" + ;; +-sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux ++sparc64*-*-linux*) # 64-bit SPARC's running GNU/Linux + extra_parts="$extra_parts crtfastmath.o" + tmake_file="${tmake_file} t-crtfm sparc/t-linux" + if test "${host_address}" = 64; then diff --git a/SOURCES/nvptx-tools-build.patch b/SOURCES/nvptx-tools-build.patch new file mode 100644 index 0000000..53d7483 --- /dev/null +++ b/SOURCES/nvptx-tools-build.patch @@ -0,0 +1,11 @@ +--- nvptx-tools/nvptx-as.c.jj 2017-01-20 12:40:18.000000000 +0100 ++++ nvptx-tools/nvptx-as.c 2017-01-20 12:43:53.864271442 +0100 +@@ -939,7 +939,7 @@ fork_execute (const char *prog, char *co + fatal_error ("%s: %m", errmsg); + } + else +- fatal_error (errmsg); ++ fatal_error ("%s", errmsg); + } + do_wait (prog, pex); + } diff --git a/SOURCES/nvptx-tools-glibc.patch b/SOURCES/nvptx-tools-glibc.patch new file mode 100644 index 0000000..4b50114 --- /dev/null +++ b/SOURCES/nvptx-tools-glibc.patch @@ -0,0 +1,32 @@ +--- nvptx-tools/configure.ac.jj 2017-01-13 12:48:31.000000000 +0100 ++++ nvptx-tools/configure.ac 2017-05-03 10:26:57.076092259 +0200 +@@ -66,6 +66,8 @@ CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ++AC_CHECK_DECLS(getopt) ++ + AC_CONFIG_SUBDIRS([libiberty]) + AC_CONFIG_FILES([Makefile dejagnu.exp]) + AC_OUTPUT +--- nvptx-tools/configure.jj 2017-01-13 12:48:54.000000000 +0100 ++++ nvptx-tools/configure 2017-05-03 10:27:13.503876809 +0200 +@@ -3963,6 +3963,18 @@ CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ++ac_fn_c_check_decl "$LINENO" "getopt" "ac_cv_have_decl_getopt" "$ac_includes_default" ++if test "x$ac_cv_have_decl_getopt" = x""yes; then : ++ ac_have_decl=1 ++else ++ ac_have_decl=0 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_DECL_GETOPT $ac_have_decl ++_ACEOF ++ ++ + + + subdirs="$subdirs libiberty" diff --git a/SOURCES/nvptx-tools-no-ptxas.patch b/SOURCES/nvptx-tools-no-ptxas.patch new file mode 100644 index 0000000..28bc597 --- /dev/null +++ b/SOURCES/nvptx-tools-no-ptxas.patch @@ -0,0 +1,947 @@ +--- nvptx-tools/configure.ac ++++ nvptx-tools/configure.ac +@@ -51,6 +51,7 @@ LIBS="$LIBS -lcuda" + AC_CHECK_FUNCS([[cuGetErrorName] [cuGetErrorString]]) + AC_CHECK_DECLS([[cuGetErrorName], [cuGetErrorString]], + [], [], [[#include ]]) ++AC_CHECK_HEADERS(unistd.h sys/stat.h) + + AC_MSG_CHECKING([for extra programs to build requiring -lcuda]) + NVPTX_RUN= +--- nvptx-tools/include/libiberty.h ++++ nvptx-tools/include/libiberty.h +@@ -390,6 +390,17 @@ extern void hex_init (void); + /* Save files used for communication between processes. */ + #define PEX_SAVE_TEMPS 0x4 + ++/* Max number of alloca bytes per call before we must switch to malloc. ++ ++ ?? Swiped from gnulib's regex_internal.h header. Is this actually ++ the case? This number seems arbitrary, though sane. ++ ++ The OS usually guarantees only one guard page at the bottom of the stack, ++ and a page size can be as small as 4096 bytes. So we cannot safely ++ allocate anything larger than 4096 bytes. Also care for the possibility ++ of a few compiler-allocated temporary stack slots. */ ++#define MAX_ALLOCA_SIZE 4032 ++ + /* Prepare to execute one or more programs, with standard output of + each program fed to standard input of the next. + FLAGS As above. +--- nvptx-tools/nvptx-as.c ++++ nvptx-tools/nvptx-as.c +@@ -30,6 +30,9 @@ + #include + #include + #include ++#ifdef HAVE_SYS_STAT_H ++#include ++#endif + #include + #define obstack_chunk_alloc malloc + #define obstack_chunk_free free +@@ -42,6 +45,38 @@ + + #include "version.h" + ++#ifndef R_OK ++#define R_OK 4 ++#define W_OK 2 ++#define X_OK 1 ++#endif ++ ++#ifndef DIR_SEPARATOR ++# define DIR_SEPARATOR '/' ++#endif ++ ++#if defined (_WIN32) || defined (__MSDOS__) \ ++ || defined (__DJGPP__) || defined (__OS2__) ++# define HAVE_DOS_BASED_FILE_SYSTEM ++# define HAVE_HOST_EXECUTABLE_SUFFIX ++# define HOST_EXECUTABLE_SUFFIX ".exe" ++# ifndef DIR_SEPARATOR_2 ++# define DIR_SEPARATOR_2 '\\' ++# endif ++# define PATH_SEPARATOR ';' ++#else ++# define PATH_SEPARATOR ':' ++#endif ++ ++#ifndef DIR_SEPARATOR_2 ++# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) ++#else ++# define IS_DIR_SEPARATOR(ch) \ ++ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) ++#endif ++ ++#define DIR_UP ".." ++ + static const char *outname = NULL; + + static void __attribute__ ((format (printf, 1, 2))) +@@ -816,7 +851,7 @@ traverse (void **slot, void *data) + } + + static void +-process (FILE *in, FILE *out) ++process (FILE *in, FILE *out, int verify, const char *outname) + { + symbol_table = htab_create (500, hash_string_hash, hash_string_eq, + NULL); +@@ -824,6 +859,18 @@ process (FILE *in, FILE *out) + const char *input = read_file (in); + Token *tok = tokenize (input); + ++ /* By default, when ptxas is not in PATH, do minimalistic verification, ++ just require that the first non-comment directive is .version. */ ++ if (verify < 0) ++ { ++ size_t i; ++ for (i = 0; tok[i].kind == K_comment; i++) ++ ; ++ if (tok[i].kind != K_dotted || !is_keyword (&tok[i], "version")) ++ fatal_error ("missing .version directive at start of file '%s'", ++ outname); ++ } ++ + do + tok = parse_file (tok); + while (tok->kind); +@@ -897,9 +944,83 @@ fork_execute (const char *prog, char *const *argv) + do_wait (prog, pex); + } + ++/* Determine if progname is available in PATH. */ ++static bool ++program_available (const char *progname) ++{ ++ char *temp = getenv ("PATH"); ++ if (temp) ++ { ++ char *startp, *endp, *nstore, *alloc_ptr = NULL; ++ size_t prefixlen = strlen (temp) + 1; ++ size_t len; ++ if (prefixlen < 2) ++ prefixlen = 2; ++ ++ len = prefixlen + strlen (progname) + 1; ++#ifdef HAVE_HOST_EXECUTABLE_SUFFIX ++ len += strlen (HOST_EXECUTABLE_SUFFIX); ++#endif ++ if (len < MAX_ALLOCA_SIZE) ++ nstore = (char *) alloca (len); ++ else ++ alloc_ptr = nstore = (char *) malloc (len); ++ ++ startp = endp = temp; ++ while (1) ++ { ++ if (*endp == PATH_SEPARATOR || *endp == 0) ++ { ++ if (endp == startp) ++ { ++ nstore[0] = '.'; ++ nstore[1] = DIR_SEPARATOR; ++ nstore[2] = '\0'; ++ } ++ else ++ { ++ memcpy (nstore, startp, endp - startp); ++ if (! IS_DIR_SEPARATOR (endp[-1])) ++ { ++ nstore[endp - startp] = DIR_SEPARATOR; ++ nstore[endp - startp + 1] = 0; ++ } ++ else ++ nstore[endp - startp] = 0; ++ } ++ strcat (nstore, progname); ++ if (! access (nstore, X_OK) ++#ifdef HAVE_HOST_EXECUTABLE_SUFFIX ++ || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK) ++#endif ++ ) ++ { ++#if defined (HAVE_SYS_STAT_H) && defined (S_ISREG) ++ struct stat st; ++ if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode)) ++#endif ++ { ++ free (alloc_ptr); ++ return true; ++ } ++ } ++ ++ if (*endp == 0) ++ break; ++ endp = startp = endp + 1; ++ } ++ else ++ endp++; ++ } ++ free (alloc_ptr); ++ } ++ return false; ++} ++ + static struct option long_options[] = { + {"traditional-format", no_argument, 0, 0 }, + {"save-temps", no_argument, 0, 0 }, ++ {"verify", no_argument, 0, 0 }, + {"no-verify", no_argument, 0, 0 }, + {"help", no_argument, 0, 'h' }, + {"version", no_argument, 0, 'V' }, +@@ -912,7 +1033,7 @@ main (int argc, char **argv) + FILE *in = stdin; + FILE *out = stdout; + bool verbose __attribute__((unused)) = false; +- bool verify = true; ++ int verify = -1; + const char *smver = "sm_30"; + + int o; +@@ -923,7 +1044,9 @@ main (int argc, char **argv) + { + case 0: + if (option_index == 2) +- verify = false; ++ verify = 1; ++ else if (option_index == 3) ++ verify = 0; + break; + case 'v': + verbose = true; +@@ -948,7 +1071,8 @@ Usage: nvptx-none-as [option...] [asmfile]\n\ + Options:\n\ + -o FILE Write output to FILE\n\ + -v Be verbose\n\ ++ --verify Do verify output is acceptable to ptxas\n\ + --no-verify Do not verify output is acceptable to ptxas\n\ + --help Print this help and exit\n\ + --version Print version number and exit\n\ + \n\ +@@ -983,11 +1108,17 @@ This program has absolutely no warranty.\n", + if (!in) + fatal_error ("cannot open input ptx file"); + +- process (in, out); +- if (outname) ++ if (outname == NULL) ++ verify = 0; ++ else if (verify == -1) ++ if (program_available ("ptxas")) ++ verify = 1; ++ ++ process (in, out, verify, outname); ++ if (outname) + fclose (out); + +- if (verify && outname) ++ if (verify > 0) + { + struct obstack argv_obstack; + obstack_init (&argv_obstack); +--- nvptx-tools/configure ++++ nvptx-tools/configure +@@ -168,7 +168,8 @@ test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && +- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" ++ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 ++test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes + else +@@ -552,11 +553,50 @@ PACKAGE_URL= + + ac_unique_file="nvptx-tools" + ac_unique_file="nvptx-as.c" ++# Factoring default headers for most tests. ++ac_includes_default="\ ++#include ++#ifdef HAVE_SYS_TYPES_H ++# include ++#endif ++#ifdef HAVE_SYS_STAT_H ++# include ++#endif ++#ifdef STDC_HEADERS ++# include ++# include ++#else ++# ifdef HAVE_STDLIB_H ++# include ++# endif ++#endif ++#ifdef HAVE_STRING_H ++# if !defined STDC_HEADERS && defined HAVE_MEMORY_H ++# include ++# endif ++# include ++#endif ++#ifdef HAVE_STRINGS_H ++# include ++#endif ++#ifdef HAVE_INTTYPES_H ++# include ++#endif ++#ifdef HAVE_STDINT_H ++# include ++#endif ++#ifdef HAVE_UNISTD_H ++# include ++#endif" ++ + enable_option_checking=no + ac_subst_vars='LTLIBOBJS + LIBOBJS + subdirs + NVPTX_RUN ++EGREP ++GREP ++CPP + CUDA_DRIVER_LDFLAGS + CUDA_DRIVER_CPPFLAGS + AR +@@ -635,7 +675,8 @@ LIBS + CPPFLAGS + CXX + CXXFLAGS +-CCC' ++CCC ++CPP' + ac_subdirs_all='libiberty' + + # Initialize some variables set by options. +@@ -1267,6 +1308,7 @@ Some influential environment variables: + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags ++ CPP C preprocessor + + Use these variables to override the choices made by `configure' or to help + it to find libraries and programs with nonstandard names/locations. +@@ -1575,6 +1617,203 @@ $as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + + } # ac_fn_c_check_decl ++ ++# ac_fn_c_try_cpp LINENO ++# ---------------------- ++# Try to preprocess conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_cpp () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_cpp conftest.$ac_ext" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } >/dev/null && { ++ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || ++ test ! -s conftest.err ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ return $ac_retval ++ ++} # ac_fn_c_try_cpp ++ ++# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES ++# ------------------------------------------------------- ++# Tests whether HEADER exists, giving a warning if it cannot be compiled using ++# the include files in INCLUDES and setting the cache variable VAR ++# accordingly. ++ac_fn_c_check_header_mongrel () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : ++ $as_echo_n "(cached) " >&6 ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++else ++ # Is the header compilable? ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 ++$as_echo_n "checking $2 usability... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++#include <$2> ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_header_compiler=yes ++else ++ ac_header_compiler=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 ++$as_echo "$ac_header_compiler" >&6; } ++ ++# Is the header present? ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 ++$as_echo_n "checking $2 presence... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include <$2> ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ac_header_preproc=yes ++else ++ ac_header_preproc=no ++fi ++rm -f conftest.err conftest.$ac_ext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 ++$as_echo "$ac_header_preproc" >&6; } ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( ++ yes:no: ) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 ++$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 ++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ++ ;; ++ no:yes:* ) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 ++$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 ++$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 ++$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 ++$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 ++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ++ ;; ++esac ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : ++ $as_echo_n "(cached) " >&6 ++else ++ eval "$3=\$ac_header_compiler" ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++fi ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ ++} # ac_fn_c_check_header_mongrel ++ ++# ac_fn_c_try_run LINENO ++# ---------------------- ++# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes ++# that executables *can* be run. ++ac_fn_c_try_run () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' ++ { { case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_try") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: program exited with status $ac_status" >&5 ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=$ac_status ++fi ++ rm -rf conftest.dSYM conftest_ipa8_conftest.oo ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ return $ac_retval ++ ++} # ac_fn_c_try_run ++ ++# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES ++# ------------------------------------------------------- ++# Tests whether HEADER exists and can be compiled using the include files in ++# INCLUDES, setting the cache variable VAR accordingly. ++ac_fn_c_check_header_compile () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++#include <$2> ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} ++ ++} # ac_fn_c_check_header_compile + cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. +@@ -3284,6 +3523,418 @@ cat >>confdefs.h <<_ACEOF + #define HAVE_DECL_CUGETERRORSTRING $ac_have_decl + _ACEOF + ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 ++$as_echo_n "checking how to run the C preprocessor... " >&6; } ++# On Suns, sometimes $CPP names a directory. ++if test -n "$CPP" && test -d "$CPP"; then ++ CPP= ++fi ++if test -z "$CPP"; then ++ if test "${ac_cv_prog_CPP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # Double quotes because CPP needs to be expanded ++ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ break ++fi ++ ++ done ++ ac_cv_prog_CPP=$CPP ++ ++fi ++ CPP=$ac_cv_prog_CPP ++else ++ ac_cv_prog_CPP=$CPP ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 ++$as_echo "$CPP" >&6; } ++ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ ++else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error "C preprocessor \"$CPP\" fails sanity check ++See \`config.log' for more details." "$LINENO" 5; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 ++$as_echo_n "checking for grep that handles long lines and -e... " >&6; } ++if test "${ac_cv_path_GREP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$GREP"; then ++ ac_path_GREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in grep ggrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue ++# Check for GNU ac_path_GREP and select it if it is found. ++ # Check for GNU $ac_path_GREP ++case `"$ac_path_GREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'GREP' >> "conftest.nl" ++ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_GREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_GREP="$ac_path_GREP" ++ ac_path_GREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_GREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_GREP"; then ++ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_GREP=$GREP ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 ++$as_echo "$ac_cv_path_GREP" >&6; } ++ GREP="$ac_cv_path_GREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 ++$as_echo_n "checking for egrep... " >&6; } ++if test "${ac_cv_path_EGREP+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 ++ then ac_cv_path_EGREP="$GREP -E" ++ else ++ if test -z "$EGREP"; then ++ ac_path_EGREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in egrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue ++# Check for GNU ac_path_EGREP and select it if it is found. ++ # Check for GNU $ac_path_EGREP ++case `"$ac_path_EGREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'EGREP' >> "conftest.nl" ++ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_EGREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_EGREP="$ac_path_EGREP" ++ ac_path_EGREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_EGREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_EGREP"; then ++ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_EGREP=$EGREP ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 ++$as_echo "$ac_cv_path_EGREP" >&6; } ++ EGREP="$ac_cv_path_EGREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 ++$as_echo_n "checking for ANSI C header files... " >&6; } ++if test "${ac_cv_header_stdc+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++#include ++#include ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_header_stdc=yes ++else ++ ac_cv_header_stdc=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++if test $ac_cv_header_stdc = yes; then ++ # SunOS 4.x string.h does not declare mem*, contrary to ANSI. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "memchr" >/dev/null 2>&1; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "free" >/dev/null 2>&1; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. ++ if test "$cross_compiling" = yes; then : ++ : ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++#include ++#if ((' ' & 0x0FF) == 0x020) ++# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') ++# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) ++#else ++# define ISLOWER(c) \ ++ (('a' <= (c) && (c) <= 'i') \ ++ || ('j' <= (c) && (c) <= 'r') \ ++ || ('s' <= (c) && (c) <= 'z')) ++# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) ++#endif ++ ++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) ++int ++main () ++{ ++ int i; ++ for (i = 0; i < 256; i++) ++ if (XOR (islower (i), ISLOWER (i)) ++ || toupper (i) != TOUPPER (i)) ++ return 2; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ++else ++ ac_cv_header_stdc=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 ++$as_echo "$ac_cv_header_stdc" >&6; } ++if test $ac_cv_header_stdc = yes; then ++ ++$as_echo "#define STDC_HEADERS 1" >>confdefs.h ++ ++fi ++ ++# On IRIX 5.3, sys/types and inttypes.h are conflicting. ++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ ++ inttypes.h stdint.h unistd.h ++do : ++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default ++" ++eval as_val=\$$as_ac_Header ++ if test "x$as_val" = x""yes; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++for ac_header in unistd.h sys/stat.h ++do : ++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ++eval as_val=\$$as_ac_Header ++ if test "x$as_val" = x""yes; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extra programs to build requiring -lcuda" >&5 + $as_echo_n "checking for extra programs to build requiring -lcuda... " >&6; } diff --git a/SPECS/gcc.spec b/SPECS/gcc.spec index d2627b3..a6bfab2 100644 --- a/SPECS/gcc.spec +++ b/SPECS/gcc.spec @@ -4,7 +4,7 @@ %global gcc_major 8 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 3 +%global gcc_release 5 %global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f %global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24 %global _unpackaged_files_terminate_build 0 @@ -279,6 +279,7 @@ Patch18: gcc8-remove-old-demangle.patch Patch19: gcc8-rh1960701.patch Patch20: gcc8-pr100797.patch Patch21: gcc8-rh1981822.patch +Patch22: gcc8-Wbidi-chars.patch Patch30: gcc8-rh1668903-1.patch Patch31: gcc8-rh1668903-2.patch @@ -859,6 +860,7 @@ to NVidia PTX capable devices if available. %patch19 -p0 -b .rh1960701~ %patch20 -p0 -b .pr100797~ %patch21 -p0 -b .rh1981822~ +%patch22 -p1 -b .bidi~ %patch30 -p0 -b .rh1668903-1~ %patch31 -p0 -b .rh1668903-2~ @@ -1357,7 +1359,7 @@ mkdir -p %{buildroot}/%{_lib} mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1 chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1 ln -sf libgcc_s-%{gcc_major}-%{DATE}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1 -%ifarch %{ix86} x86_64 ppc ppc64 ppc64p7 ppc64le %{arm} +%ifarch %{ix86} x86_64 ppc ppc64 ppc64p7 ppc64le %{arm} aarch64 rm -f $FULLPATH/libgcc_s.so echo '/* GNU ld script Use the shared library, but some functions are only in @@ -3175,6 +3177,12 @@ fi %endif %changelog +* Tue Nov 30 2021 Marek Polacek 8.5.0-5 +- when linking against libgcc_s, link libgcc.a too (#2022588) + +* Thu Nov 18 2021 Marek Polacek 8.5.0-4 +- add -Wbidi-chars patch (#2008392) + * Tue Jul 13 2021 Marek Polacek 8.5.0-3 - fix mangling of lambdas in default args (PR c++/91241, #1981822) - add a few Provides: bundled