diff --git a/gcc-error-logging.patch b/gcc-error-logging.patch new file mode 100644 index 0000000..4560407 --- /dev/null +++ b/gcc-error-logging.patch @@ -0,0 +1,1113 @@ +commit 423455963df19041b8dbea86fca8c1bb0549ccf0 +Author: Florian Weimer +Date: Tue Oct 18 16:28:33 2022 +0200 + + Log implicit ints/implicit function declarations to /usr/lib/gcc/errors + + Only do so for C99 and later language modes, both features were part + of C89. + + The directory and the file name prefix for files within can be + controlled using the GCC_ERROR_LOG_DIRECTORY and GCC_ERROR_LOG_PREFIX + environment variables. + +diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc +index 1b53f2d0785..4bf3b4a4c2a 100644 +--- a/gcc/c/c-decl.cc ++++ b/gcc/c/c-decl.cc +@@ -3468,6 +3468,14 @@ pushdecl (tree x) + static void + implicit_decl_warning (location_t loc, tree id, tree olddecl) + { ++ if (flag_isoc99) ++ { ++ log_error_to_directory (loc, "implicit function declaration", ++ IDENTIFIER_POINTER (id)); ++ error_at (loc, "implicit declaration of function %qE", id); ++ return; ++ } ++ + if (!warn_implicit_function_declaration) + return; + +@@ -6705,7 +6713,15 @@ grokdeclarator (const struct c_declarator *declarator, + + /* Diagnose defaulting to "int". */ + +- if (declspecs->default_int_p && !in_system_header_at (input_location)) ++ if (declspecs->default_int_p && flag_isoc99) ++ { ++ log_error_to_directory (loc, "defaulting to int"); ++ if (name) ++ error_at (loc, "type defaults to % in declaration of %qE", name); ++ else ++ error_at (loc, "type defaults to % in type name"); ++ } ++ else if (declspecs->default_int_p && !in_system_header_at (input_location)) + { + /* Issue a warning if this is an ISO C 99 program or if + -Wreturn-type and this is a function, or if -Wimplicit; +@@ -10469,9 +10485,12 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) + warn_if_shadowing (decl); + + if (flag_isoc99) +- pedwarn (DECL_SOURCE_LOCATION (decl), +- OPT_Wimplicit_int, "type of %qD defaults to %", +- decl); ++ { ++ log_error_to_directory (DECL_SOURCE_LOCATION (decl), ++ "type defaults to int"); ++ error_at (DECL_SOURCE_LOCATION (decl), ++ "type of %qD defaults to %", decl); ++ } + else + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wmissing_parameter_type, +diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc +index 0f093081161..73070cc11f9 100644 +--- a/gcc/diagnostic.cc ++++ b/gcc/diagnostic.cc +@@ -2737,3 +2737,44 @@ c_diagnostic_cc_tests () + #if __GNUC__ >= 10 + # pragma GCC diagnostic pop + #endif ++ ++/* Magic code to emit diagnostics to a log directory. */ ++void ++log_error_to_directory (location_t loc, const char *message, ++ const char *identifier) ++{ ++ const char *magic_path = getenv ("GCC_ERROR_LOG_DIRECTORY"); ++ if (magic_path == nullptr) ++ magic_path = "/usr/lib/gcc/errors"; ++ ++ // Do not log anything if the directory does not exist. ++ if (access (magic_path, R_OK | W_OK | X_OK) < 0) ++ return; ++ ++ const char *log_prefix = getenv ("GCC_ERROR_LOG_PREFIX"); ++ if (log_prefix == nullptr) ++ log_prefix = "gcc"; ++ ++ char *templ = xasprintf ("%s/%sXXXXXX", magic_path, log_prefix); ++ int fd = mkstemp (templ); ++ if (fd < 0) ++ abort(); ++ ++ auto exploc = expand_location (loc); ++ const char *file = exploc.file; ++ if (file == nullptr) ++ file = ""; ++ char *formatted; ++ if (identifier != nullptr) ++ formatted = xasprintf ("%s:%d: %s: %s\n", ++ file, exploc.line, message, identifier); ++ else ++ formatted = xasprintf ("%s:%d: %s\n", file, exploc.line, message); ++ ssize_t len = strlen (formatted); ++ if (write (fd, formatted, len) != len ++ || close (fd) < 0) ++ abort (); ++ ++ free (formatted); ++ free (templ); ++} +diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h +index 9a51097f146..b520de263ab 100644 +--- a/gcc/diagnostic.h ++++ b/gcc/diagnostic.h +@@ -619,4 +619,7 @@ extern bool warning_enabled_at (location_t, int); + + extern char *get_cwe_url (int cwe); + ++void log_error_to_directory (location_t loc, const char *message, ++ const char *identifier = nullptr); ++ + #endif /* ! GCC_DIAGNOSTIC_H */ + +commit 06d52570382a3b9e6041d58d10127ecc466af3b7 +Author: Florian Weimer +Date: Tue Nov 22 10:50:09 2022 +0100 + + Turn __declspec into a keyword + + This avoids diagnosing + + __declspec(thread) int foo; + + as an old-style function definition with an implicit int. + +diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc +index aae397ed755..fdc1f163ed0 100644 +--- a/gcc/c-family/c-common.cc ++++ b/gcc/c-family/c-common.cc +@@ -425,6 +425,7 @@ const struct c_common_resword c_common_reswords[] = + { "__GIMPLE", RID_GIMPLE, D_CONLY }, + { "__PHI", RID_PHI, D_CONLY }, + { "__RTL", RID_RTL, D_CONLY }, ++ { "__declspec", RID_DECLTYPE, D_CONLY }, + { "alignas", RID_ALIGNAS, D_C2X | D_CXX11 | D_CXXWARN }, + { "alignof", RID_ALIGNOF, D_C2X | D_CXX11 | D_CXXWARN }, + { "asm", RID_ASM, D_ASM }, +diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h +index f96350b64af..61cb0dfadf9 100644 +--- a/gcc/c-family/c-common.h ++++ b/gcc/c-family/c-common.h +@@ -136,6 +136,9 @@ enum rid + /* "__RTL", for the RTL-parsing extension to the C frontend. */ + RID_RTL, + ++ /* MSVC extension. */ ++ RID_DECLSPEC, ++ + /* C11 */ + RID_ALIGNAS, RID_GENERIC, + + +commit eda435e65520e4b58e7d407cca17c1fb810e02a9 +Author: Florian Weimer +Date: Thu May 4 09:30:24 2023 +0200 + + Enable error logging for -Wint-conversion + + Only for C99 and later language modes. + +diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc +index a17879698ec..b1c4fbf77f8 100644 +--- a/gcc/c/c-typeck.cc ++++ b/gcc/c/c-typeck.cc +@@ -7749,27 +7749,67 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); +- if (pedwarn (&richloc, OPT_Wint_conversion, ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-from-int-conversion" ++ " in argument"); ++ error_at (&richloc, ++ "passing argument %d of %qE makes pointer from " ++ "integer without a cast", parmnum, rname); ++ inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); ++ } ++ else if (pedwarn (&richloc, OPT_Wint_conversion, + "passing argument %d of %qE makes pointer from " + "integer without a cast", parmnum, rname)) + inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + } + break; + case ic_assign: +- pedwarn (location, OPT_Wint_conversion, +- "assignment to %qT from %qT makes pointer from integer " +- "without a cast", type, rhstype); ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-from-int-conversion" ++ " in assignment"); ++ error_at (location, ++ "assignment to %qT from %qT makes pointer from integer " ++ "without a cast", type, rhstype); ++ } ++ else ++ pedwarn (location, OPT_Wint_conversion, ++ "assignment to %qT from %qT makes pointer from integer " ++ "without a cast", type, rhstype); + break; + case ic_init: + case ic_init_const: +- pedwarn_init (location, OPT_Wint_conversion, ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-from-int-conversion" ++ " in initialization"); ++ error_at (location, + "initialization of %qT from %qT makes pointer from " + "integer without a cast", type, rhstype); ++ } ++ else ++ pedwarn_init (location, OPT_Wint_conversion, ++ "initialization of %qT from %qT makes pointer from " ++ "integer without a cast", type, rhstype); + break; + case ic_return: +- pedwarn (location, OPT_Wint_conversion, "returning %qT from a " +- "function with return type %qT makes pointer from " +- "integer without a cast", rhstype, type); ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-from-int-conversion" ++ " in return"); ++ error_at (location, "returning %qT from a " ++ "function with return type %qT makes pointer from " ++ "integer without a cast", rhstype, type); ++ } ++ else ++ pedwarn (location, OPT_Wint_conversion, "returning %qT from a " ++ "function with return type %qT makes pointer from " ++ "integer without a cast", rhstype, type); + break; + default: + gcc_unreachable (); +@@ -7786,27 +7826,66 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); +- if (pedwarn (&richloc, OPT_Wint_conversion, +- "passing argument %d of %qE makes integer from " +- "pointer without a cast", parmnum, rname)) ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-to-int-conversion" ++ " in argument"); ++ error_at (&richloc, ++ "passing argument %d of %qE makes integer from " ++ "pointer without a cast", parmnum, rname); ++ inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); ++ } ++ else if (pedwarn (&richloc, OPT_Wint_conversion, ++ "passing argument %d of %qE makes integer from " ++ "pointer without a cast", parmnum, rname)) + inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + } + break; + case ic_assign: +- pedwarn (location, OPT_Wint_conversion, +- "assignment to %qT from %qT makes integer from pointer " +- "without a cast", type, rhstype); ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-to-int-conversion" ++ " in assignment"); ++ error_at (location, ++ "assignment to %qT from %qT makes integer from pointer " ++ "without a cast", type, rhstype); ++ } ++ else ++ pedwarn (location, OPT_Wint_conversion, ++ "assignment to %qT from %qT makes integer from pointer " ++ "without a cast", type, rhstype); + break; + case ic_init: + case ic_init_const: +- pedwarn_init (location, OPT_Wint_conversion, ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-to-int-conversion" ++ " in initialization"); ++ error_at (location, + "initialization of %qT from %qT makes integer from " + "pointer without a cast", type, rhstype); ++ } ++ else ++ pedwarn_init (location, OPT_Wint_conversion, ++ "initialization of %qT from %qT makes integer from " ++ "pointer without a cast", type, rhstype); + break; + case ic_return: +- pedwarn (location, OPT_Wint_conversion, "returning %qT from a " +- "function with return type %qT makes integer from " +- "pointer without a cast", rhstype, type); ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, ++ "pointer-to-int-conversion" ++ " in return"); ++ error_at (location, "returning %qT from a " ++ "function with return type %qT makes integer from " ++ "pointer without a cast", rhstype, type); ++ } ++ else pedwarn (location, OPT_Wint_conversion, "returning %qT from a " ++ "function with return type %qT makes integer from " ++ "pointer without a cast", rhstype, type); + break; + default: + gcc_unreachable (); + +commit 586f855010cd171d8ec9bcc0864bfbf12b88adbf +Author: Florian Weimer +Date: Wed Nov 15 09:16:01 2023 +0100 + + Implement suppression of error logging + +diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc +index 73070cc11f9..a162caf1f0a 100644 +--- a/gcc/diagnostic.cc ++++ b/gcc/diagnostic.cc +@@ -2738,11 +2738,48 @@ c_diagnostic_cc_tests () + # pragma GCC diagnostic pop + #endif + ++#include ++#include ++ ++static bool suppress_logging; ++static std::vector logged_error_files; ++static std::vector logged_error_files_with_identifier; ++ ++static void ++remove_file_list (std::vector &files) ++{ ++ for (const std::string &path : files) ++ unlink (path.c_str ()); ++ files.clear(); ++} ++ ++void ++suppress_error_logging () ++{ ++ suppress_logging = true; ++ remove_file_list (logged_error_files); ++ remove_file_list (logged_error_files_with_identifier); ++} ++ + /* Magic code to emit diagnostics to a log directory. */ + void + log_error_to_directory (location_t loc, const char *message, + const char *identifier) + { ++ if (suppress_logging) ++ return; ++ ++ /* If logging with an identifier, remove the previous error reports ++ without an identifier. */ ++ if (identifier) ++ remove_file_list (logged_error_files); ++ ++ /* If already errored with an identifier, do not record ++ non-identifier errors. This enables ignoring errors based on ++ identifiers. */ ++ if (!identifier && !logged_error_files_with_identifier.empty()) ++ return; ++ + const char *magic_path = getenv ("GCC_ERROR_LOG_DIRECTORY"); + if (magic_path == nullptr) + magic_path = "/usr/lib/gcc/errors"; +@@ -2759,6 +2796,10 @@ log_error_to_directory (location_t loc, const char *message, + int fd = mkstemp (templ); + if (fd < 0) + abort(); ++ if (identifier) ++ logged_error_files_with_identifier.emplace_back(templ); ++ else ++ logged_error_files.emplace_back(templ); + + auto exploc = expand_location (loc); + const char *file = exploc.file; +diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h +index b520de263ab..249cfd87d78 100644 +--- a/gcc/diagnostic.h ++++ b/gcc/diagnostic.h +@@ -622,4 +622,9 @@ extern char *get_cwe_url (int cwe); + void log_error_to_directory (location_t loc, const char *message, + const char *identifier = nullptr); + ++/* Stop logging future errors and delete the existing reported errors. ++ This can be used for errors that happen unconditionally (e.g., ++ wrong number of function arguments). */ ++void suppress_error_logging (); ++ + #endif /* ! GCC_DIAGNOSTIC_H */ + +commit b23335868b5219e7c13c45a70714df75debfbd23 +Author: Florian Weimer +Date: Wed Nov 15 09:16:23 2023 +0100 + + Switch to warning names in error logs and more int-conversion coverage + +diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc +index 4bf3b4a4c2a..20b49a9d371 100644 +--- a/gcc/c/c-decl.cc ++++ b/gcc/c/c-decl.cc +@@ -3470,7 +3470,7 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl) + { + if (flag_isoc99) + { +- log_error_to_directory (loc, "implicit function declaration", ++ log_error_to_directory (loc, "implicit-function-declaration", + IDENTIFIER_POINTER (id)); + error_at (loc, "implicit declaration of function %qE", id); + return; +@@ -6715,7 +6715,7 @@ grokdeclarator (const struct c_declarator *declarator, + + if (declspecs->default_int_p && flag_isoc99) + { +- log_error_to_directory (loc, "defaulting to int"); ++ log_error_to_directory (loc, "implicit-int"); + if (name) + error_at (loc, "type defaults to % in declaration of %qE", name); + else +@@ -10487,7 +10487,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info) + if (flag_isoc99) + { + log_error_to_directory (DECL_SOURCE_LOCATION (decl), +- "type defaults to int"); ++ "implicit-int"); + error_at (DECL_SOURCE_LOCATION (decl), + "type of %qD defaults to %", decl); + } +diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc +index b1c4fbf77f8..c0b723970ed 100644 +--- a/gcc/c/c-typeck.cc ++++ b/gcc/c/c-typeck.cc +@@ -5611,8 +5611,17 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, + else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) + { + if (!null_pointer_constant_p (orig_op2)) +- pedwarn (colon_loc, 0, +- "pointer/integer type mismatch in conditional expression"); ++ { ++ if (flag_isoc99) ++ { ++ log_error_to_directory (colon_loc, "int-conversion"); ++ error_at (colon_loc, ++ "pointer/integer type mismatch in conditional expression"); ++ } ++ else ++ pedwarn (colon_loc, 0, ++ "pointer/integer type mismatch in conditional expression"); ++ } + else + { + op2 = null_pointer_node; +@@ -5622,8 +5631,17 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, + else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) + { + if (!null_pointer_constant_p (orig_op1)) +- pedwarn (colon_loc, 0, +- "pointer/integer type mismatch in conditional expression"); ++ { ++ if (flag_isoc99) ++ { ++ log_error_to_directory (colon_loc, "int-conversion"); ++ error_at (colon_loc, ++ "pointer/integer type mismatch in conditional expression"); ++ } ++ else ++ pedwarn (colon_loc, 0, ++ "pointer/integer type mismatch in conditional expression"); ++ } + else + { + op1 = null_pointer_node; +@@ -7751,9 +7769,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + gcc_rich_location richloc (expr_loc, &rhs_label); + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-from-int-conversion" +- " in argument"); ++ log_error_to_directory (location, "int-conversion"); + error_at (&richloc, + "passing argument %d of %qE makes pointer from " + "integer without a cast", parmnum, rname); +@@ -7768,9 +7784,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + case ic_assign: + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-from-int-conversion" +- " in assignment"); ++ log_error_to_directory (location, "int-conversion"); + error_at (location, + "assignment to %qT from %qT makes pointer from integer " + "without a cast", type, rhstype); +@@ -7784,9 +7798,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + case ic_init_const: + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-from-int-conversion" +- " in initialization"); ++ log_error_to_directory (location, "int-conversion"); + error_at (location, + "initialization of %qT from %qT makes pointer from " + "integer without a cast", type, rhstype); +@@ -7799,9 +7811,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + case ic_return: + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-from-int-conversion" +- " in return"); ++ log_error_to_directory (location, "int-conversion"); + error_at (location, "returning %qT from a " + "function with return type %qT makes pointer from " + "integer without a cast", rhstype, type); +@@ -7828,9 +7838,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + gcc_rich_location richloc (expr_loc, &rhs_label); + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-to-int-conversion" +- " in argument"); ++ log_error_to_directory (location, "int-conversion"); + error_at (&richloc, + "passing argument %d of %qE makes integer from " + "pointer without a cast", parmnum, rname); +@@ -7845,9 +7853,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + case ic_assign: + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-to-int-conversion" +- " in assignment"); ++ log_error_to_directory (location, "int-conversion"); + error_at (location, + "assignment to %qT from %qT makes integer from pointer " + "without a cast", type, rhstype); +@@ -7861,9 +7867,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + case ic_init_const: + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-to-int-conversion" +- " in initialization"); ++ log_error_to_directory (location, "int-conversion"); + error_at (location, + "initialization of %qT from %qT makes integer from " + "pointer without a cast", type, rhstype); +@@ -7876,9 +7880,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + case ic_return: + if (flag_isoc99) + { +- log_error_to_directory (location, +- "pointer-to-int-conversion" +- " in return"); ++ log_error_to_directory (location, "int-conversion"); + error_at (location, "returning %qT from a " + "function with return type %qT makes integer from " + "pointer without a cast", rhstype, type); + +commit 9a928ad657abd0843fd9362d93c3572b134270f5 +Author: Florian Weimer +Date: Wed Nov 15 09:21:18 2023 +0100 + + Introduce and log return-mismatch errors + +diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc +index c0b723970ed..3c509ea9428 100644 +--- a/gcc/c/c-typeck.cc ++++ b/gcc/c/c-typeck.cc +@@ -11376,9 +11376,11 @@ c_finish_return (location_t loc, tree retval, tree origtype) + { + bool warned_here; + if (flag_isoc99) +- warned_here = pedwarn +- (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0, +- "% with no value, in function returning non-void"); ++ { ++ log_error_to_directory (loc, "return-mismatch"); ++ warned_here = true; ++ error_at (loc, "% with no value, in function returning non-void"); ++ } + else + warned_here = warning_at + (loc, OPT_Wreturn_type, +@@ -11394,9 +11396,18 @@ c_finish_return (location_t loc, tree retval, tree origtype) + current_function_returns_null = 1; + bool warned_here; + if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) +- warned_here = pedwarn +- (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0, +- "% with a value, in function returning void"); ++ if (flag_isoc99) ++ { ++ warned_here = true; ++ log_error_to_directory (loc, "return-mismatch"); ++ error_at (xloc, "% with a value, in function returning void"); ++ } ++ else ++ { ++ warned_here = pedwarn ++ (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0, ++ "% with a value, in function returning void"); ++ } + else + warned_here = pedwarn + (xloc, OPT_Wpedantic, "ISO C forbids " + +commit 19cba38204b90e1e03618bf4cc574584fe53a124 +Author: Florian Weimer +Date: Wed Nov 15 09:32:46 2023 +0100 + + Log incompatible-pointer-types errors + +diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc +index 3c509ea9428..93724e38dea 100644 +--- a/gcc/c/c-typeck.cc ++++ b/gcc/c/c-typeck.cc +@@ -5596,14 +5596,23 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, + else + { + int qual = ENCODE_QUAL_ADDR_SPACE (as_common); +- if (bltin1 && bltin2) +- warning_at (colon_loc, OPT_Wincompatible_pointer_types, +- "pointer type mismatch between %qT and %qT " +- "of %qD and %qD in conditional expression", +- type1, type2, bltin1, bltin2); ++ if (flag_isoc99) ++ { ++ log_error_to_directory (colon_loc, "incompatible-pointer-types"); ++ error_at (colon_loc, ++ "pointer type mismatch in conditional expression"); ++ } + else +- pedwarn (colon_loc, 0, +- "pointer type mismatch in conditional expression"); ++ { ++ if (bltin1 && bltin2) ++ warning_at (colon_loc, OPT_Wincompatible_pointer_types, ++ "pointer type mismatch between %qT and %qT " ++ "of %qD and %qD in conditional expression", ++ type1, type2, bltin1, bltin2); ++ else ++ pedwarn (colon_loc, 0, ++ "pointer type mismatch in conditional expression"); ++ } + result_type = build_pointer_type + (build_qualified_type (void_type_node, qual)); + } +@@ -7690,13 +7699,32 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); +- if (pedwarn (&richloc, OPT_Wincompatible_pointer_types, +- "passing argument %d of %qE from incompatible " +- "pointer type", parmnum, rname)) ++ bool warned; ++ if (flag_isoc99) ++ { ++ warned = true; ++ log_error_to_directory (expr_loc, "incompatible-pointer-types"); ++ error_at (&richloc, ++ "passing argument %d of %qE from incompatible " ++ "pointer type", parmnum, rname); ++ } ++ else ++ warned = pedwarn (&richloc, OPT_Wincompatible_pointer_types, ++ "passing argument %d of %qE from incompatible " ++ "pointer type", parmnum, rname); ++ if (warned) + inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + } + break; + case ic_assign: ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, "incompatible-pointer-types"); ++ error_at (location, ++ "assignment to %qT from incompatible pointer type %qT", ++ type, rhstype); ++ break; ++ } + if (bltin) + pedwarn (location, OPT_Wincompatible_pointer_types, + "assignment to %qT from pointer to " +@@ -7709,6 +7737,15 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + break; + case ic_init: + case ic_init_const: ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, "incompatible-pointer-types"); ++ error_at (location, ++ "initialization of %qT from incompatible " ++ "pointer type %qT", ++ type, rhstype); ++ break; ++ } + if (bltin) + pedwarn_init (location, OPT_Wincompatible_pointer_types, + "initialization of %qT from pointer to " +@@ -7721,6 +7758,14 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, + type, rhstype); + break; + case ic_return: ++ if (flag_isoc99) ++ { ++ log_error_to_directory (location, "incompatible-pointer-types"); ++ error_at (location, ++ "returning %qT from a function with incompatible " ++ "return type %qT", rhstype, type); ++ break; ++ } + if (bltin) + pedwarn (location, OPT_Wincompatible_pointer_types, + "returning pointer to %qD of type %qT from " + +commit 5036b5df1a80a56cb56f0a905c1df0a8c3665aaa +Author: Florian Weimer +Date: Wed Nov 15 09:35:18 2023 +0100 + + Log declaration-missing-parameter-type errors + +diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc +index 20b49a9d371..64b62572144 100644 +--- a/gcc/c/c-decl.cc ++++ b/gcc/c/c-decl.cc +@@ -8231,8 +8231,15 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) + { + if (!funcdef_flag) + { +- pedwarn (input_location, 0, "parameter names (without types) in " +- "function declaration"); ++ if (flag_isoc99) ++ { ++ log_error_to_directory (input_location, "declaration-missing-parameter-type"); ++ error_at (input_location, "parameter names (without types) in " ++ "function declaration"); ++ } ++ else ++ pedwarn (input_location, 0, "parameter names (without types) in " ++ "function declaration"); + arg_info->parms = NULL_TREE; + } + else + +commit e9630535fa88e36e95cf098436b87dce205638c6 +Author: Florian Weimer +Date: Wed Nov 15 09:53:33 2023 +0100 + + Suppress error logging in case of a few common autoconf failures + +diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc +index fdc1f163ed0..1206bdfdf27 100644 +--- a/gcc/c-family/c-common.cc ++++ b/gcc/c-family/c-common.cc +@@ -6224,11 +6224,13 @@ builtin_function_validate_nargs (location_t loc, tree fndecl, int nargs, + { + if (nargs < required) + { ++ suppress_error_logging (); + error_at (loc, "too few arguments to function %qE", fndecl); + return false; + } + else if (nargs > required) + { ++ suppress_error_logging (); + error_at (loc, "too many arguments to function %qE", fndecl); + return false; + } +@@ -7075,6 +7077,7 @@ speculation_safe_value_resolve_call (tree function, vec *params) + + if (vec_safe_is_empty (params)) + { ++ suppress_error_logging (); + error ("too few arguments to function %qE", function); + return BUILT_IN_NONE; + } +@@ -7122,12 +7125,14 @@ speculation_safe_value_resolve_params (location_t loc, tree orig_function, + + if (params->length () == 0) + { ++ suppress_error_logging (); + error_at (loc, "too few arguments to function %qE", orig_function); + return false; + } + + else if (params->length () > 2) + { ++ suppress_error_logging (); + error_at (loc, "too many arguments to function %qE", orig_function); + return false; + } +@@ -7197,6 +7202,7 @@ sync_resolve_size (tree function, vec *params, bool fetch) + + if (vec_safe_is_empty (params)) + { ++ suppress_error_logging (); + error ("too few arguments to function %qE", function); + return 0; + } +@@ -7270,6 +7276,7 @@ sync_resolve_params (location_t loc, tree orig_function, tree function, + ++parmnum; + if (params->length () <= parmnum) + { ++ suppress_error_logging (); + error_at (loc, "too few arguments to function %qE", orig_function); + return false; + } +@@ -7296,6 +7303,7 @@ sync_resolve_params (location_t loc, tree orig_function, tree function, + /* __atomic routines are not variadic. */ + if (!orig_format && params->length () != parmnum + 1) + { ++ suppress_error_logging (); + error_at (loc, "too many arguments to function %qE", orig_function); + return false; + } +diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc +index 64b62572144..dafa70435c1 100644 +--- a/gcc/c/c-decl.cc ++++ b/gcc/c/c-decl.cc +@@ -3874,6 +3874,8 @@ undeclared_variable (location_t loc, tree id) + static bool already = false; + struct c_scope *scope; + ++ suppress_error_logging (); ++ + auto_diagnostic_group d; + if (current_function_decl == NULL_TREE) + { +diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc +index 93724e38dea..1943c232e70 100644 +--- a/gcc/c/c-typeck.cc ++++ b/gcc/c/c-typeck.cc +@@ -2576,6 +2576,7 @@ build_component_ref (location_t loc, tree datum, tree component, + + if (!field) + { ++ suppress_error_logging (); + tree guessed_id = lookup_field_fuzzy (type, component); + if (guessed_id) + { +@@ -9785,6 +9786,7 @@ set_init_label (location_t loc, tree fieldname, location_t fieldname_loc, + + if (field == NULL_TREE) + { ++ suppress_error_logging (); + tree guessed_id = lookup_field_fuzzy (constructor_type, fieldname); + if (guessed_id) + { + +commit 6b7d1a727cdd04b041df9ff0f2121e6103126093 +Author: Florian Weimer +Date: Thu Nov 16 05:20:15 2023 +0100 + + Additional logging suppression for missing function arguments + +diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc +index 1943c232e70..6d86d19f2d6 100644 +--- a/gcc/c/c-typeck.cc ++++ b/gcc/c/c-typeck.cc +@@ -3836,6 +3836,7 @@ convert_arguments (location_t loc, vec arg_loc, tree typelist, + + if (typetail != NULL_TREE && TREE_VALUE (typetail) != void_type_node) + { ++ suppress_error_logging (); + error_at (loc, "too few arguments to function %qE", function); + inform_declaration (fundecl); + return -1; + +commit 4bba0655b19ec541644150ac18553089a19c5b18 +Author: Florian Weimer +Date: Thu Nov 23 18:43:16 2023 +0100 + + Special case for strerror_r autoconf checks + +diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc +index 9ac43a1af6e..a0989e3d4d7 100644 +--- a/gcc/c-family/c-warn.cc ++++ b/gcc/c-family/c-warn.cc +@@ -1952,6 +1952,12 @@ invalid_indirection_error (location_t loc, tree type, ref_operator errstring) + type); + break; + case RO_UNARY_STAR: ++ /* It does not matter that the operand is not a pointer because ++ of an implicit function declaration. The non-instrumented ++ compiler fails in that case, too. This means that there is ++ no need to log past and future errors. This is relevant to ++ strerror_r return type autoconf checks. */ ++ suppress_error_logging (); + error_at (loc, + "invalid type argument of unary %<*%> (have %qT)", + type); + +commit 1f77edaa6bbec12a28a14a24ba9728e72f70d534 +Author: Florian Weimer +Date: Tue Nov 28 20:23:23 2023 +0100 + + Suppress error logging in case of unknown type errors + + These always happen with the non-instrumented compiler as well. + + Helps with this autoconf probe: + + configure:23354: gcc -o conftest -g -O2 -Wl,--as-needed conftest.c >&5 + conftest.c:63:40: error: unknown type name 'off64_t'; did you mean 'off_t'? + 63 | int fseeko64(FILE *stream, off64_t offset, int whence); + | ^~~~~~~ + | off_t + conftest.c: In function 'main': + conftest.c:69:24: error: implicit declaration of function 'fseeko64' + 69 | return fseeko64(stream, 256lu, 0); + | ^~~~~~~~ + + Code fragment: + + | #include + | #include + | #include + | + | #if !HAVE_DECL_FSEEKO64 + | int fseeko64(FILE *stream, off64_t offset, int whence); + | #endif + | + | int main() + | { + | FILE* stream; + | return fseeko64(stream, 256lu, 0); + | } + +diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc +index 3627a3fbdc7..2904b7bbf69 100644 +--- a/gcc/c/c-parser.cc ++++ b/gcc/c/c-parser.cc +@@ -2123,6 +2123,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, + with some kind of hint. + If the user forgot a "struct" etc, suggest inserting + it. Otherwise, attempt to look for misspellings. */ ++ suppress_error_logging (); + gcc_rich_location richloc (here); + if (tag_exists_p (RECORD_TYPE, name)) + { + +commit 3be96dbe1dfd2c99cf5e3dbf993db89321839a8f +Author: Florian Weimer +Date: Wed Nov 29 09:34:43 2023 +0100 + + Add error suppression for more unknown type names + +diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc +index 2904b7bbf69..f74434ca04c 100644 +--- a/gcc/c/c-parser.cc ++++ b/gcc/c/c-parser.cc +@@ -3180,6 +3180,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, + attrs_ok = true; + if (kind == C_ID_ID) + { ++ suppress_error_logging (); + error_at (loc, "unknown type name %qE", value); + t.kind = ctsk_typedef; + t.spec = error_mark_node; +@@ -4804,6 +4805,7 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs, + c_parser_set_source_position_from_token (token); + if (c_parser_next_tokens_start_typename (parser, cla_prefer_type)) + { ++ suppress_error_logging (); + auto_diagnostic_group d; + name_hint hint = lookup_name_fuzzy (token->value, + FUZZY_LOOKUP_TYPENAME, + +commit 16d065b3ce04278001d03d3fd38f01fd71ec8c2d +Author: Florian Weimer +Date: Wed Nov 29 11:43:19 2023 +0100 + + Suppress error logging if unknown struct types are encountered + +diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc +index dafa70435c1..6f1f33f34e8 100644 +--- a/gcc/c/c-decl.cc ++++ b/gcc/c/c-decl.cc +@@ -5732,6 +5732,7 @@ finish_decl (tree decl, location_t init_loc, tree init, + is an error. */ + : !DECL_EXTERNAL (decl))) + { ++ suppress_error_logging (); + error ("storage size of %q+D isn%'t known", decl); + TREE_TYPE (decl) = error_mark_node; + } +diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc +index f74434ca04c..2d57acf17f8 100644 +--- a/gcc/c/c-parser.cc ++++ b/gcc/c/c-parser.cc +@@ -1786,7 +1786,10 @@ c_parser_translation_unit (c_parser *parser) + tree decl; + FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl) + if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node) +- error ("storage size of %q+D isn%'t known", decl); ++ { ++ suppress_error_logging (); ++ error ("storage size of %q+D isn%'t known", decl); ++ } + + if (vec_safe_length (current_omp_declare_target_attribute)) + { + +commit a686be614951b191446781a436aecad849dab38c +Author: Florian Weimer +Date: Thu Nov 30 13:34:46 2023 +0100 + + Add more logging suppression in case of too many function arguments + +diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc +index 6d86d19f2d6..37dc18fb420 100644 +--- a/gcc/c/c-typeck.cc ++++ b/gcc/c/c-typeck.cc +@@ -3694,6 +3694,7 @@ convert_arguments (location_t loc, vec arg_loc, tree typelist, + + if (type == void_type_node) + { ++ suppress_error_logging (); + if (selector) + error_at (loc, "too many arguments to method %qE", selector); + else + +commit 5dccd006bf4e60ba843a9edda3bed230a59ae51f +Author: Pekka Seppänen +Date: Wed Sep 20 19:41:01 2023 +0100 + + aarch64: Ensure const and sign correctness + + Be const and sign correct by using a matching CIE augmentation type. + Use a builtin instead of relying being included. + + libgcc/ChangeLog: + + * config/aarch64/aarch64-unwind.h (aarch64_cie_signed_with_b_key): + Use const unsigned type and a builtin. + + Signed-off-by: Pekka Seppänen + (cherry picked from commit 0a59ff65df6da8267efb5c97dead8cd0dcd5b445) + +diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h +index 3ad2f8239ed..d669edd671b 100644 +--- a/libgcc/config/aarch64/aarch64-unwind.h ++++ b/libgcc/config/aarch64/aarch64-unwind.h +@@ -40,8 +40,9 @@ aarch64_cie_signed_with_b_key (struct _Unwind_Context *context) + const struct dwarf_cie *cie = get_cie (fde); + if (cie != NULL) + { +- char *aug_str = cie->augmentation; +- return strchr (aug_str, 'B') == NULL ? 0 : 1; ++ const unsigned char *aug_str = cie->augmentation; ++ return __builtin_strchr ((const char *) aug_str, ++ 'B') == NULL ? 0 : 1; + } + } + return 0; + +commit 91768f20003d28cf1adf8d9ed6318dd4396efaf3 +Author: Florian Weimer +Date: Fri Dec 1 08:10:12 2023 +0100 + + aarch64: Avoid -Wincompatible-pointer-types warning in Linux unwinder + + * config/aarch64/linux-unwind.h + (aarch64_fallback_frame_state): Add cast to the expected type + in sc assignment. + + (cherry picked from commit 335bd6c938c254e3ae4b019cfc8a94bb8009ca81) + +diff --git a/libgcc/config/aarch64/linux-unwind.h b/libgcc/config/aarch64/linux-unwind.h +index 00eba866049..18b3df71e7b 100644 +--- a/libgcc/config/aarch64/linux-unwind.h ++++ b/libgcc/config/aarch64/linux-unwind.h +@@ -77,7 +77,10 @@ aarch64_fallback_frame_state (struct _Unwind_Context *context, + } + + rt_ = context->cfa; +- sc = &rt_->uc.uc_mcontext; ++ /* Historically, the uc_mcontext member was of type struct sigcontext, but ++ glibc uses a different type now with member names in the implementation ++ namespace. */ ++ sc = (struct sigcontext *) &rt_->uc.uc_mcontext; + + /* This define duplicates the definition in aarch64.md */ + #define SP_REGNUM 31 diff --git a/gcc.spec b/gcc.spec index 664d00c..fa9061c 100644 --- a/gcc.spec +++ b/gcc.spec @@ -136,7 +136,7 @@ Summary: Various compilers (C, C++, Objective-C, ...) Name: gcc Version: %{gcc_version} -Release: %{gcc_release}%{?dist} +Release: %{gcc_release}.implicits.8%{?dist}.6 # libgcc, libgfortran, libgomp, libstdc++ and crtstuff have # GCC Runtime Exception. License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD @@ -292,6 +292,8 @@ Patch50: isl-rh2155127.patch Patch100: gcc13-fortran-fdec-duplicates.patch +Patch990: gcc-error-logging.patch + # On ARM EABI systems, we do want -gnueabi to be part of the # target triple. %ifnarch %{arm} @@ -873,6 +875,8 @@ touch -r isl-0.24/m4/ax_prog_cxx_for_build.m4 isl-0.24/m4/ax_prog_cc_for_build.m %patch -P100 -p1 -b .fortran-fdec-duplicates~ %endif +%patch -P 990 -p1 -b .error-logging + %ifarch %{arm} rm -f gcc/testsuite/go.test/test/fixedbugs/issue19182.go %endif @@ -911,6 +915,9 @@ fi rm -f gcc/testsuite/go.test/test/chan/goroutines.go %build +# Do not write the failures anywhere. Currently required for rebuilding +# with an instrumented GCC. +export GCC_ERROR_LOG_DIRECTORY=/disabled # Undo the broken autoconf change in recent Fedora versions export CONFIG_SITE=NONE @@ -1185,7 +1192,7 @@ CC="$CC" CXX="$CXX" CFLAGS="$OPT_FLAGS" \ %ifarch sparc sparcv9 sparc64 make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now bootstrap %else -make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now profiledbootstrap +make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now bootstrap %endif CC="`%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-cc`" @@ -2201,62 +2208,6 @@ ln -sf gcc-annobin.so.0.0.0 $FULLPATH/plugin/gcc-annobin.so.0 ln -sf gcc-annobin.so.0.0.0 $FULLPATH/plugin/gcc-annobin.so %endif -%check -cd obj-%{gcc_target_platform} - -# run the tests. -LC_ALL=C make %{?_smp_mflags} -k check ALT_CC_UNDER_TEST=gcc ALT_CXX_UNDER_TEST=g++ \ -%if 0%{?fedora} >= 20 || 0%{?rhel} > 7 - RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector-strong}'" || : -%else - RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector}'" || : -%endif -%if !%{build_annobin_plugin} -if [ -f %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/annobin.so ]; then - # Test whether current annobin plugin won't fail miserably with the newly built gcc. - echo -e '#include \nint main () { printf ("Hello, world!\\n"); return 0; }' > annobin-test.c - echo -e '#include \nint main () { std::cout << "Hello, world!" << std::endl; return 0; }' > annobin-test.C - `%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-cc` \ - -O2 -g -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS \ - -fexceptions -fstack-protector-strong -grecord-gcc-switches -o annobin-test{c,.c} \ - -Wl,-rpath,%{gcc_target_platform}/libgcc/ \ - -fplugin=%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/annobin.so \ - 2> ANNOBINOUT1 || echo Annobin test 1 FAIL > ANNOBINOUT2; - `%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-cxx` \ - `%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-includes` \ - -O2 -g -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS \ - -fexceptions -fstack-protector-strong -grecord-gcc-switches -o annobin-test{C,.C} \ - -Wl,-rpath,%{gcc_target_platform}/libgcc/:%{gcc_target_platform}/libstdc++-v3/src/.libs/ \ - -fplugin=%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/annobin.so \ - -B %{gcc_target_platform}/libstdc++-v3/src/.libs/ \ - 2> ANNOBINOUT3 || echo Annobin test 2 FAIL > ANNOBINOUT4; - [ -f ./annobin-testc ] || echo Annobin test 1 MISSING > ANNOBINOUT5; - [ -f ./annobin-testc ] && \ - ( ./annobin-testc > ANNOBINRES1 2>&1 || echo Annobin test 1 RUNFAIL > ANNOBINOUT6 ); - [ -f ./annobin-testC ] || echo Annobin test 2 MISSING > ANNOBINOUT7; - [ -f ./annobin-testC ] && \ - ( ./annobin-testC > ANNOBINRES2 2>&1 || echo Annobin test 2 RUNFAIL > ANNOBINOUT8 ); - cat ANNOBINOUT[1-8] > ANNOBINOUT - touch ANNOBINRES1 ANNOBINRES2 - [ -s ANNOBINOUT ] && echo Annobin testing FAILed > ANNOBINRES - cat ANNOBINOUT ANNOBINRES[12] >> ANNOBINRES - rm -f ANNOBINOUT* ANNOBINRES[12] annobin-test{c,C} -fi -%endif -echo ====================TESTING========================= -( LC_ALL=C ../contrib/test_summary || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}' -%if !%{build_annobin_plugin} -[ -f ANNOBINRES ] && cat ANNOBINRES -%endif -echo ====================TESTING END===================== -mkdir testlogs-%{_target_platform}-%{version}-%{release} -for i in `find . -name \*.log | grep -F testsuite/ | grep -v 'config.log\|acats.*/tests/'`; do - ln $i testlogs-%{_target_platform}-%{version}-%{release}/ || : -done -tar cf - testlogs-%{_target_platform}-%{version}-%{release} | xz -9e \ - | uuencode testlogs-%{_target_platform}.tar.xz || : -rm -rf testlogs-%{_target_platform}-%{version}-%{release} - %post go %{_sbindir}/update-alternatives --install \ %{_prefix}/bin/go go %{_prefix}/bin/go.gcc 92 \