public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/marxin/heads/str_starts_with-v2)] Come up with startswith function.
@ 2021-04-12 13:27 Martin Liska
  0 siblings, 0 replies; 3+ messages in thread
From: Martin Liska @ 2021-04-12 13:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ba18498cdd42f72742c11dcf598442846ce60ed0

commit ba18498cdd42f72742c11dcf598442846ce60ed0
Author: Martin Liska <mliska@suse.cz>
Date:   Wed Mar 17 16:36:44 2021 +0100

    Come up with startswith function.
    
    gcc/ada/ChangeLog:
    
            * adadecode.c (has_prefix): Remove has_prefix and replace it
            with startswith.
            (__gnat_decode): Likewise.
            * gcc-interface/utils.c (def_builtin_1): Use startswith
            function instead of strncmp.
            * init.c (__gnat_install_handler): Likewise.
    
    gcc/analyzer/ChangeLog:
    
            * sm-file.cc (is_file_using_fn_p): Use startswith
            function instead of strncmp.
    
    gcc/ChangeLog:
    
            * builtins.c (is_builtin_name): Use startswith
            function instead of strncmp.
            * collect2.c (main): Likewise.
            (has_lto_section): Likewise.
            (scan_libraries): Likewise.
            * coverage.c (coverage_checksum_string): Likewise.
            (coverage_init): Likewise.
            * dwarf2out.c (is_cxx): Likewise.
            (gen_compile_unit_die): Likewise.
            * gcc-ar.c (main): Likewise.
            * gcc.c (init_spec): Likewise.
            (read_specs): Likewise.
            (execute): Likewise.
            (check_live_switch): Likewise.
            * genattrtab.c (write_attr_case): Likewise.
            (IS_ATTR_GROUP): Likewise.
            * gencfn-macros.c (main): Likewise.
            * gengtype.c (type_for_name): Likewise.
            (gen_rtx_next): Likewise.
            (get_file_langdir): Likewise.
            (write_local): Likewise.
            * genmatch.c (get_operator): Likewise.
            (get_operand_type): Likewise.
            (expr::gen_transform): Likewise.
            * genoutput.c (validate_optab_operands): Likewise.
            * incpath.c (add_sysroot_to_chain): Likewise.
            * langhooks.c (lang_GNU_C): Likewise.
            (lang_GNU_CXX): Likewise.
            (lang_GNU_Fortran): Likewise.
            (lang_GNU_OBJC): Likewise.
            * lto-wrapper.c (run_gcc): Likewise.
            * omp-general.c (omp_max_simt_vf): Likewise.
            * omp-low.c (omp_runtime_api_call): Likewise.
            * opts-common.c (parse_options_from_collect_gcc_options): Likewise.
            * read-rtl-function.c (function_reader::read_rtx_operand_r): Likewise.
            * real.c (real_from_string): Likewise.
            * selftest.c (assert_str_startswith): Likewise.
            * timevar.c (timer::validate_phases): Likewise.
            * tree.c (get_file_function_name): Likewise.
            * ubsan.c (ubsan_use_new_style_p): Likewise.
            * varasm.c (default_function_rodata_section): Likewise.
            (incorporeal_function_p): Likewise.
            (default_section_type_flags): Likewise.
            * system.h (startswith): Define startswith.
    
    gcc/c-family/ChangeLog:
    
            * c-ada-spec.c (print_destructor): Use startswith
            function instead of strncmp.
            (dump_ada_declaration): Likewise.
            * c-common.c (disable_builtin_function): Likewise.
            (def_builtin_1): Likewise.
            * c-format.c (check_tokens): Likewise.
            (check_plain): Likewise.
            (convert_format_name_to_system_name): Likewise.
    
    gcc/c/ChangeLog:
    
            * c-aux-info.c (affix_data_type): Use startswith
            function instead of strncmp.
            * c-typeck.c (build_function_call_vec): Likewise.
            * gimple-parser.c (c_parser_gimple_parse_bb_spec): Likewise.
    
    gcc/cp/ChangeLog:
    
            * decl.c (duplicate_decls): Use startswith
            function instead of strncmp.
            (cxx_builtin_function): Likewise.
            (omp_declare_variant_finalize_one): Likewise.
            (grokfndecl): Likewise.
            * error.c (dump_decl_name): Likewise.
            * mangle.c (find_decomp_unqualified_name): Likewise.
            (write_guarded_var_name): Likewise.
            (decl_tls_wrapper_p): Likewise.
            * parser.c (cp_parser_simple_type_specifier): Likewise.
            (cp_parser_tx_qualifier_opt): Likewise.
            * pt.c (template_parm_object_p): Likewise.
            (dguide_name_p): Likewise.
    
    gcc/d/ChangeLog:
    
            * d-builtins.cc (do_build_builtin_fn): Use startswith
            function instead of strncmp.
            * dmd/dinterpret.c (evaluateIfBuiltin): Likewise.
            * dmd/dmangle.c: Likewise.
            * dmd/hdrgen.c: Likewise.
            * dmd/identifier.c (Identifier::toHChars2): Likewise.
    
    gcc/fortran/ChangeLog:
    
            * decl.c (variable_decl): Use startswith
            function instead of strncmp.
            (gfc_match_end): Likewise.
            * gfortran.h (gfc_str_startswith): Likewise.
            * module.c (load_omp_udrs): Likewise.
            (read_module): Likewise.
            * options.c (gfc_handle_runtime_check_option): Likewise.
            * primary.c (match_arg_list_function): Likewise.
            * trans-decl.c (gfc_get_symbol_decl): Likewise.
            * trans-expr.c (gfc_conv_procedure_call): Likewise.
            * trans-intrinsic.c (gfc_conv_ieee_arithmetic_function): Likewise.
    
    gcc/go/ChangeLog:
    
            * gofrontend/runtime.cc (Runtime::name_to_code): Use startswith
            function instead of strncmp.
    
    gcc/objc/ChangeLog:
    
            * objc-act.c (objc_string_ref_type_p): Use startswith
            function instead of strncmp.
            * objc-encoding.c (encode_type): Likewise.
            * objc-next-runtime-abi-02.c (has_load_impl): Likewise.

Diff:
---
 gcc/ada/adadecode.c                 | 14 +++--------
 gcc/ada/gcc-interface/utils.c       |  3 +--
 gcc/ada/init.c                      |  8 +++----
 gcc/analyzer/sm-file.cc             |  5 ++--
 gcc/builtins.c                      | 10 +++-----
 gcc/c-family/c-ada-spec.c           |  8 +++----
 gcc/c-family/c-common.c             |  5 ++--
 gcc/c-family/c-format.c             | 20 ++++++++--------
 gcc/c/c-aux-info.c                  |  4 ++--
 gcc/c/c-typeck.c                    |  4 ++--
 gcc/c/gimple-parser.c               |  2 +-
 gcc/collect2.c                      | 48 +++++++++++++++++--------------------
 gcc/coverage.c                      |  7 +++---
 gcc/cp/decl.c                       | 15 ++++++------
 gcc/cp/error.c                      |  2 +-
 gcc/cp/mangle.c                     | 11 ++++-----
 gcc/cp/parser.c                     |  7 +++---
 gcc/cp/pt.c                         |  5 ++--
 gcc/d/d-builtins.cc                 |  3 +--
 gcc/d/dmd/dinterpret.c              |  2 +-
 gcc/d/dmd/dmangle.c                 |  2 +-
 gcc/d/dmd/hdrgen.c                  |  2 +-
 gcc/d/dmd/identifier.c              |  6 ++---
 gcc/dwarf2out.c                     | 14 +++++------
 gcc/fortran/decl.c                  |  4 ++--
 gcc/fortran/gfortran.h              |  4 ----
 gcc/fortran/module.c                | 10 ++++----
 gcc/fortran/options.c               |  2 +-
 gcc/fortran/primary.c               |  6 ++---
 gcc/fortran/trans-decl.c            |  2 +-
 gcc/fortran/trans-expr.c            |  2 +-
 gcc/fortran/trans-intrinsic.c       | 22 ++++++++---------
 gcc/gcc-ar.c                        |  2 +-
 gcc/gcc.c                           | 14 +++++------
 gcc/genattrtab.c                    |  8 +++----
 gcc/gencfn-macros.c                 |  2 +-
 gcc/gengtype.c                      |  8 +++----
 gcc/genmatch.c                      |  8 +++----
 gcc/genoutput.c                     |  2 +-
 gcc/go/gofrontend/runtime.cc        |  2 +-
 gcc/incpath.c                       |  2 +-
 gcc/langhooks.c                     |  8 +++----
 gcc/lto-wrapper.c                   |  3 +--
 gcc/objc/objc-act.c                 |  2 +-
 gcc/objc/objc-encoding.c            |  2 +-
 gcc/objc/objc-next-runtime-abi-02.c |  2 +-
 gcc/omp-general.c                   |  2 +-
 gcc/omp-low.c                       |  2 +-
 gcc/opts-common.c                   |  2 +-
 gcc/read-rtl-function.c             |  2 +-
 gcc/real.c                          |  6 ++---
 gcc/selftest.c                      |  3 +--
 gcc/system.h                        |  8 +++++++
 gcc/timevar.c                       |  2 +-
 gcc/tree.c                          |  2 +-
 gcc/ubsan.c                         |  2 +-
 gcc/varasm.c                        | 22 ++++++++---------
 57 files changed, 176 insertions(+), 201 deletions(-)

diff --git a/gcc/ada/adadecode.c b/gcc/ada/adadecode.c
index 43a378f9058..1154e628311 100644
--- a/gcc/ada/adadecode.c
+++ b/gcc/ada/adadecode.c
@@ -29,8 +29,9 @@
  *                                                                          *
  ****************************************************************************/
 
+#include "config.h"
+#include "system.h"
 #include "runtime.h"
-#include <string.h>
 #include <stdio.h>
 #include <ctype.h>
 
@@ -47,7 +48,6 @@
 #include "adadecode.h"
 
 static void add_verbose (const char *, char *);
-static int has_prefix (const char *, const char *);
 static int has_suffix (const char *, const char *);
 
 /* This is a safe version of strcpy that can be used with overlapped
@@ -68,14 +68,6 @@ static void add_verbose (const char *text, char *ada_name)
   verbose_info = 1;
 }
 
-/* Returns 1 if NAME starts with PREFIX.  */
-
-static int
-has_prefix (const char *name, const char *prefix)
-{
-  return strncmp (name, prefix, strlen (prefix)) == 0;
-}
-
 /* Returns 1 if NAME ends with SUFFIX.  */
 
 static int
@@ -167,7 +159,7 @@ __gnat_decode (const char *coded_name, char *ada_name, int verbose)
     }
 
   /* Check for library level subprogram.  */
-  else if (has_prefix (coded_name, "_ada_"))
+  else if (startswith (coded_name, "_ada_"))
     {
       strcpy (ada_name, coded_name + 5);
       lib_subprog = 1;
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 952f032072b..2d5ca4ba456 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -7016,8 +7016,7 @@ def_builtin_1 (enum built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
   decl = add_builtin_function (name, fntype, fncode, fnclass,
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 3ceb1a31b02..24eb67bbf0d 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -2111,10 +2111,10 @@ __gnat_install_handler (void)
       prefix for vxsim when running on Linux and Windows.  */
   {
     char *model = sysModel ();
-    if ((strncmp (model, "Linux", 5) == 0)
-        || (strncmp (model, "Windows", 7) == 0)
-        || (strncmp (model, "SIMLINUX", 8) == 0) /* vx7 */
-        || (strncmp (model, "SIMNT", 5) == 0)) /* ditto */
+    if ((startswith(model, "Linux")
+        || startswith (model, "Windows")
+        || startswith (model, "SIMLINUX") /* vx7 */
+	|| startswith (model, "SIMNT")) /* ditto */
       __gnat_set_is_vxsim (TRUE);
   }
 #endif
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index d64c313e31c..3a5f95def34 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -312,9 +312,8 @@ is_file_using_fn_p (tree fndecl)
 
   /* Also support variants of these names prefixed with "_IO_".  */
   const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
-  if (strncmp (name, "_IO_", 4) == 0)
-    if (fs.contains_name_p (name + 4))
-      return true;
+  if (startswith (name, "_IO_") && fs.contains_name_p (name + 4))
+    return true;
 
   return false;
 }
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 196dda3fa5e..af71caf2f08 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -740,13 +740,9 @@ pointer_query::flush_cache ()
 static bool
 is_builtin_name (const char *name)
 {
-  if (strncmp (name, "__builtin_", 10) == 0)
-    return true;
-  if (strncmp (name, "__sync_", 7) == 0)
-    return true;
-  if (strncmp (name, "__atomic_", 9) == 0)
-    return true;
-  return false;
+  return (startswith (name, "__builtin_")
+	  || startswith (name, "__sync_")
+	  || startswith (name, "__atomic_"));
 }
 
 /* Return true if NODE should be considered for inline expansion regardless
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 9fef5f05cc8..29eb0b01a91 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -2696,7 +2696,7 @@ print_destructor (pretty_printer *buffer, tree t, tree type)
   tree decl_name = DECL_NAME (TYPE_NAME (type));
 
   pp_string (buffer, "Delete_");
-  if (strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del", 8) == 0)
+  if (startswith (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del"))
     pp_string (buffer, "And_Free_");
   pp_ada_tree_identifier (buffer, decl_name, t, false);
 }
@@ -2980,9 +2980,9 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
 	    return 0;
 
 	  /* Only consider complete constructors and deleting destructors.  */
-	  if (strncmp (IDENTIFIER_POINTER (decl_name), "__ct_comp", 9) != 0
-	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_comp", 9) != 0
-	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_del", 8) != 0)
+	  if (!startswith (IDENTIFIER_POINTER (decl_name), "__ct_comp")
+	      && !startswith (IDENTIFIER_POINTER (decl_name), "__dt_comp")
+	      && !startswith (IDENTIFIER_POINTER (decl_name), "__dt_del"))
 	    return 0;
 	}
 
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d227686a030..7bd799d1825 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4670,7 +4670,7 @@ static bool builtin_function_disabled_p (const char *);
 void
 disable_builtin_function (const char *name)
 {
-  if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
+  if (startswith (name, "__builtin_"))
     error ("cannot disable built-in function %qs", name);
   else
     {
@@ -4718,8 +4718,7 @@ def_builtin_1 (enum built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
   decl = add_builtin_function (name, fntype, fncode, fnclass,
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 0a63cacb0d9..bda3b18fcd0 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -3097,7 +3097,7 @@ check_tokens (const token_t *tokens, unsigned ntoks,
       /* Allow this ugly warning for the time being.  */
       if (toklen == 2
 	  && format_chars - orig_format_chars > 6
-	  && !strncmp (format_chars - 7, " count >= width of ", 19))
+	  && startswith (format_chars - 7, " count >= width of "))
 	return format_chars + 10;
 
       /* The token is a type if it ends in an alphabetic character.  */
@@ -3127,7 +3127,7 @@ check_tokens (const token_t *tokens, unsigned ntoks,
   /* Diagnose unquoted __attribute__.  Consider any parenthesized
      argument to the attribute to avoid redundant warnings for
      the double parentheses that might follow.  */
-  if (!strncmp (format_chars, "__attribute", sizeof "__attribute" - 1))
+  if (startswith (format_chars, "__attribute"))
     {
       unsigned nchars = sizeof "__attribute" - 1;
       while ('_' == format_chars[nchars])
@@ -3178,9 +3178,9 @@ check_tokens (const token_t *tokens, unsigned ntoks,
   /* Diagnose unquoted built-ins.  */
   if (format_chars[0] == '_'
       && format_chars[1] == '_'
-      && (!strncmp (format_chars + 2, "atomic", sizeof "atomic" - 1)
-	  || !strncmp (format_chars + 2, "builtin", sizeof "builtin" - 1)
-	  || !strncmp (format_chars + 2, "sync", sizeof "sync" - 1)))
+      && (startswith (format_chars + 2, "atomic")
+	  || startswith (format_chars + 2, "builtin")
+	  || startswith (format_chars + 2, "sync")))
     {
       format_warning_substr (format_string_loc, format_string_cst,
 			     fmtchrpos, fmtchrpos + wlen, opt,
@@ -3267,7 +3267,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
   if (*format_chars == '%')
     {
       /* Diagnose %<%s%> and suggest using %qs instead.  */
-      if (!strncmp (format_chars, "%<%s%>", 6))
+      if (startswith (format_chars, "%<%s%>"))
 	format_warning_substr (format_string_loc, format_string_cst,
 			       fmtchrpos, fmtchrpos + 6, opt,
 			       "quoted %qs directive in format; "
@@ -3593,7 +3593,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 
       if (nchars == 1)
 	{
-	  if (!strncmp (format_chars, "\"%s\"", 4))
+	  if (startswith (format_chars, "\"%s\""))
 	    {
 	      if (format_warning_substr (format_string_loc, format_string_cst,
 					 fmtchrpos, fmtchrpos + 4, opt,
@@ -3621,7 +3621,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 	      && format_chars[0] == '(')
 	    ;   /* Text beginning in an open parenthesis.  */
 	  else if (nchars == 3
-	      && !strncmp (format_chars, "...", 3)
+	      && startswith (format_chars, "...")
 	      && format_chars[3])
 	    ;   /* Text beginning in an ellipsis.  */
 	  else
@@ -3663,7 +3663,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 		   a period at the end of a capitalized sentence.  */
 	  else if (nchars == 3
 		   && format_chars - orig_format_chars > 0
-		   && !strncmp (format_chars, "...", 3))
+		   && startswith (format_chars, "..."))
 	    ;   /* Text ending in the ellipsis.  */
 	  else
 	    format_warning_substr (format_string_loc, format_string_cst,
@@ -5104,7 +5104,7 @@ convert_format_name_to_system_name (const char *attr_name)
   int i;
 
   if (attr_name == NULL || *attr_name == 0
-      || strncmp (attr_name, "gcc_", 4) == 0)
+      || startswith (attr_name, "gcc_"))
     return attr_name;
 #ifdef TARGET_OVERRIDES_FORMAT_INIT
   TARGET_OVERRIDES_FORMAT_INIT ();
diff --git a/gcc/c/c-aux-info.c b/gcc/c/c-aux-info.c
index bae5757ad13..81860cb48cb 100644
--- a/gcc/c/c-aux-info.c
+++ b/gcc/c/c-aux-info.c
@@ -67,12 +67,12 @@ affix_data_type (const char *param)
 
   for (;;)
     {
-      if (!strncmp (p, "volatile ", 9))
+      if (startswith (p, "volatile "))
 	{
 	  p += 9;
 	  continue;
 	}
-      if (!strncmp (p, "const ", 6))
+      if (startswith (p, "const "))
 	{
 	  p += 6;
 	  continue;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 21eab00d4b3..f70b1036cc9 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3107,7 +3107,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
 	orig_fundecl = fundecl;
       /* Atomic functions have type checking/casting already done.  They are 
 	 often rewritten and don't match the original parameter list.  */
-      if (name && !strncmp (IDENTIFIER_POINTER (name), "__atomic_", 9))
+      if (name && startswith (IDENTIFIER_POINTER (name), "__atomic_"))
         origtypes = NULL;
     }
   if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
@@ -3193,7 +3193,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
 					    nargs, argarray, &arg_loc);
 
   if (name != NULL_TREE
-      && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
+      && startswith (IDENTIFIER_POINTER (name), "__builtin_"))
     {
       if (require_constant_value)
 	result
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 58b161b7c76..3a6e72ef002 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -131,7 +131,7 @@ static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *);
 static bool
 c_parser_gimple_parse_bb_spec (tree val, int *index)
 {
-  if (strncmp (IDENTIFIER_POINTER (val), "__BB", 4) != 0)
+  if (!startswith (IDENTIFIER_POINTER (val), "__BB"))
     return false;
   for (const char *p = IDENTIFIER_POINTER (val) + 4; *p; ++p)
     if (!ISDIGIT (*p))
diff --git a/gcc/collect2.c b/gcc/collect2.c
index bd371430ab7..0ddb1693b67 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -956,7 +956,7 @@ main (int argc, char **argv)
       {
 	if (! strcmp (argv[i], "-debug"))
 	  debug = true;
-	else if (!strncmp (argv[i], "-fno-lto", 8))
+	else if (startswith (argv[i], "-fno-lto"))
 	  lto_mode = LTO_MODE_NONE;
         else if (! strcmp (argv[i], "-plugin"))
 	  {
@@ -970,7 +970,7 @@ main (int argc, char **argv)
 	  selected_linker = USE_GOLD_LD;
 	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
 	  selected_linker = USE_LLD_LD;
-	else if (strncmp (argv[i], "-o", 2) == 0)
+	else if (startswith (argv[i], "-o"))
 	  {
 	    /* Parse the output filename if it's given so that we can make
 	       meaningful temp filenames.  */
@@ -984,19 +984,19 @@ main (int argc, char **argv)
 	/* These flags are position independent, although their order
 	   is important - subsequent flags override earlier ones. */
 	else if (strcmp (argv[i], "-b64") == 0)
-	    aix64_flag = 1;
+	  aix64_flag = 1;
 	/* -bexport:filename always needs the :filename */
-	else if (strncmp (argv[i], "-bE:", 4) == 0
-	      || strncmp (argv[i], "-bexport:", 9) == 0)
-	    export_flag = 1;
+	else if (startswith (argv[i], "-bE:")
+		 || startswith (argv[i], "-bexport:"))
+	  export_flag = 1;
 	else if (strcmp (argv[i], "-brtl") == 0
 	      || strcmp (argv[i], "-bsvr4") == 0
 	      || strcmp (argv[i], "-G") == 0)
-	    aixrtl_flag = 1;
+	  aixrtl_flag = 1;
 	else if (strcmp (argv[i], "-bnortl") == 0)
-	    aixrtl_flag = 0;
+	  aixrtl_flag = 0;
 	else if (strcmp (argv[i], "-blazy") == 0)
-	    aixlazy_flag = 1;
+	  aixlazy_flag = 1;
 #endif
       }
 
@@ -1016,11 +1016,11 @@ main (int argc, char **argv)
 	const char *q = extract_string (&p);
 	if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
 	  num_c_args++;
-	if (strncmp (q, "-flto-partition=none", 20) == 0)
+	if (startswith (q, "-flto-partition=none"))
 	  no_partition = true;
-	else if (strncmp (q, "-fno-lto", 8) == 0)
+	else if (startswith (q, "-fno-lto"))
 	  lto_mode = LTO_MODE_NONE;
-	else if (strncmp (q, "-save-temps", 11) == 0)
+	else if (startswith (q, "-save-temps"))
 	  /* FIXME: Honour =obj.  */
 	  save_temps = true;
 	else if (strcmp (q, "-dumpdir") == 0)
@@ -1254,7 +1254,7 @@ main (int argc, char **argv)
 	(void) extract_string (&p);
 #ifdef COLLECT_EXPORT_LIST
       /* Detect any invocation with -fvisibility.  */
-      if (strncmp (q, "-fvisibility", 12) == 0)
+      if (startswith (q, "-fvisibility"))
 	visibility_flag = 1;
 #endif
     }
@@ -1303,7 +1303,7 @@ main (int argc, char **argv)
 	      break;
 
             case 'f':
-	      if (strncmp (arg, "-flto", 5) == 0)
+	      if (startswith (arg, "-flto"))
 		{
 #ifdef ENABLE_LTO
 		  /* Do not pass LTO flag to the linker. */
@@ -1315,13 +1315,13 @@ main (int argc, char **argv)
 #endif
 		}
 	      else if (!use_collect_ld
-		       && strncmp (arg, "-fuse-ld=", 9) == 0)
+		       && startswith (arg, "-fuse-ld="))
 		{
 		  /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */
 		  ld1--;
 		  ld2--;
 		}
-	      else if (strncmp (arg, "-fno-lto", 8) == 0)
+	      else if (startswith (arg, "-fno-lto"))
 		{
 		  /* Do not pass -fno-lto to the linker. */
 		  ld1--;
@@ -1462,7 +1462,7 @@ main (int argc, char **argv)
 		  ld2--;
 #endif
 		}
-	      else if (strncmp (arg, "--demangle", 10) == 0)
+	      else if (startswith (arg, "--demangle"))
 		{
 #ifndef HAVE_LD_DEMANGLE
 		  no_demangle = 0;
@@ -1479,7 +1479,7 @@ main (int argc, char **argv)
 		  ld2--;
 #endif
 		}
-	      else if (strncmp (arg, "--sysroot=", 10) == 0)
+	      else if (startswith (arg, "--sysroot="))
 		target_system_root = arg + 10;
 	      else if (strcmp (arg, "--version") == 0)
 		verbose = true;
@@ -2307,13 +2307,9 @@ has_lto_section (void *data, const char *name ATTRIBUTE_UNUSED,
 {
   int *found = (int *) data;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
-	       sizeof (LTO_SECTION_NAME_PREFIX) - 1) != 0)
-    {
-      if (strncmp (name, OFFLOAD_SECTION_NAME_PREFIX,
-	           sizeof (OFFLOAD_SECTION_NAME_PREFIX) - 1) != 0)
-        return 1;
-    }
+  if (!startswith (name, LTO_SECTION_NAME_PREFIX)
+      && !startswith (name, OFFLOAD_SECTION_NAME_PREFIX))
+    return 1;
 
   *found = 1;
 
@@ -2619,7 +2615,7 @@ scan_libraries (const char *prog_name)
 	continue;
 
       name = p;
-      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
+      if (startswith (name, "not found"))
 	fatal_error (input_location, "dynamic dependency %s not found", buf);
 
       /* Find the end of the symbol name.  */
diff --git a/gcc/coverage.c b/gcc/coverage.c
index dc9ea6f3ee1..5a344cdfc17 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -488,9 +488,9 @@ coverage_checksum_string (unsigned chksum, const char *string)
   for (i = 0; string[i]; i++)
     {
       int offset = 0;
-      if (!strncmp (string + i, "_GLOBAL__N_", 11))
+      if (startswith (string + i, "_GLOBAL__N_"))
       offset = 11;
-      if (!strncmp (string + i, "_GLOBAL__", 9))
+      if (startswith (string + i, "_GLOBAL__"))
       offset = 9;
 
       /* C++ namespaces do have scheme:
@@ -1256,8 +1256,7 @@ coverage_init (const char *filename)
 	  filename = concat (getpwd (), separator, filename, NULL);
 	  if (profile_prefix_path)
 	    {
-	      if (!strncmp (filename, profile_prefix_path,
-			    strlen (profile_prefix_path)))
+	      if (startswith (filename, profile_prefix_path))
 		{
 		  filename += strlen (profile_prefix_path);
 		  while (*filename == *separator)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index ec05ee1f0b4..8cf0d29b55f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1609,8 +1609,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
 
 		  if (name[0] == '_'
 		      && name[1] == '_'
-		      && (strncmp (name + 2, "builtin_",
-				   strlen ("builtin_")) == 0
+		      && (startswith (name + 2, "builtin_")
 			  || (len = strlen (name)) <= strlen ("___chk")
 			  || memcmp (name + len - strlen ("_chk"),
 				     "_chk", strlen ("_chk") + 1) != 0))
@@ -4821,7 +4820,7 @@ cxx_builtin_function (tree decl)
     /* In the user's namespace, it must be declared before use.  */
     hiding = true;
   else if (IDENTIFIER_LENGTH (id) > strlen ("___chk")
-	   && 0 != strncmp (name + 2, "builtin_", strlen ("builtin_"))
+	   && !startswith (name + 2, "builtin_")
 	   && 0 == memcmp (name + IDENTIFIER_LENGTH (id) - strlen ("_chk"),
 			   "_chk", strlen ("_chk") + 1))
     /* Treat __*_chk fortification functions as anticipated as well,
@@ -7558,9 +7557,9 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
 	  return true;
 	}
       if (fndecl_built_in_p (variant)
-	  && (strncmp (varname, "__builtin_", strlen ("__builtin_")) == 0
-	      || strncmp (varname, "__sync_", strlen ("__sync_")) == 0
-	      || strncmp (varname, "__atomic_", strlen ("__atomic_")) == 0))
+	  && (startswith (varname, "__builtin_")
+	      || startswith (varname, "__sync_")
+	      || startswith (varname, "__atomic_")))
 	{
 	  error_at (varid_loc, "variant %qD is a built-in", variant);
 	  return true;
@@ -9826,8 +9825,8 @@ grokfndecl (tree ctype,
 	  || (IDENTIFIER_LENGTH (declarator) > 10
 	      && IDENTIFIER_POINTER (declarator)[0] == '_'
 	      && IDENTIFIER_POINTER (declarator)[1] == '_'
-	      && strncmp (IDENTIFIER_POINTER (declarator)+2,
-			  "builtin_", 8) == 0)
+	      && startswith (IDENTIFIER_POINTER (declarator) + 2,
+			     "builtin_"))
 	  || (targetcm.cxx_implicit_extern_c
 	      && (targetcm.cxx_implicit_extern_c
 		  (IDENTIFIER_POINTER (declarator))))))
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ff4ae6f4b23..a4e9b2a6ad9 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1138,7 +1138,7 @@ dump_decl_name (cxx_pretty_printer *pp, tree t, int flags)
     }
 
   const char *str = IDENTIFIER_POINTER (t);
-  if (!strncmp (str, "_ZGR", 4))
+  if (startswith (str, "_ZGR"))
     {
       pp_cxx_ws_string (pp, "<temporary>");
       return;
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 4399165ee23..72e4d9f7727 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1308,10 +1308,10 @@ find_decomp_unqualified_name (tree decl, size_t *len)
   const char *p = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
   const char *end = p + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
   bool nested = false;
-  if (strncmp (p, "_Z", 2))
+  if (!startswith (p, "_Z"))
     return NULL;
   p += 2;
-  if (!strncmp (p, "St", 2))
+  if (startswith (p, "St"))
     p += 2;
   else if (*p == 'N')
     {
@@ -1327,7 +1327,7 @@ find_decomp_unqualified_name (tree decl, size_t *len)
 	    break;
 	}
     }
-  if (strncmp (p, "DC", 2))
+  if (!startswith (p, "DC"))
     return NULL;
   if (nested)
     {
@@ -4410,7 +4410,7 @@ static void
 write_guarded_var_name (const tree variable)
 {
   if (DECL_NAME (variable)
-      && strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
+      && startswith (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR"))
     /* The name of a guard variable for a reference temporary should refer
        to the reference, not the temporary.  */
     write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
@@ -4468,8 +4468,7 @@ decl_tls_wrapper_p (const tree fn)
   if (TREE_CODE (fn) != FUNCTION_DECL)
     return false;
   tree name = DECL_NAME (fn);
-  return strncmp (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX,
-		  strlen (TLS_WRAPPER_PREFIX)) == 0;
+  return startswith (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX);
 }
 
 /* Return an identifier for the name of a temporary variable used to
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b6f94bdda23..cb4b552f63a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18642,9 +18642,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	  decl_specs->int_n_idx = idx;
 	  /* Check if the alternate "__intN__" form has been used instead of
 	     "__intN".  */
-	  if (strncmp (IDENTIFIER_POINTER (token->u.value)
-			+ (IDENTIFIER_LENGTH (token->u.value) - 2),
-			"__", 2) == 0)
+	  if (startswith (IDENTIFIER_POINTER (token->u.value)
+			  + (IDENTIFIER_LENGTH (token->u.value) - 2), "__"))
 	    decl_specs->int_n_alt = true;
 	}
       type = int_n_trees [idx].signed_type;
@@ -22931,7 +22930,7 @@ cp_parser_tx_qualifier_opt (cp_parser *parser)
       tree name = token->u.value;
       const char *p = IDENTIFIER_POINTER (name);
       const int len = strlen ("transaction_safe");
-      if (!strncmp (p, "transaction_safe", len))
+      if (startswith (p, "transaction_safe"))
 	{
 	  p += len;
 	  if (*p == '\0'
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index abd1ad4d1a6..b611ef11316 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6973,7 +6973,7 @@ bool
 template_parm_object_p (const_tree t)
 {
   return (TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t) && DECL_NAME (t)
-	  && !strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA", 4));
+	  && startswith (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA"));
 }
 
 /* Subroutine of convert_nontype_argument, to check whether EXPR, as an
@@ -28412,8 +28412,7 @@ dguide_name_p (tree name)
 {
   return (TREE_CODE (name) == IDENTIFIER_NODE
 	  && TREE_TYPE (name)
-	  && !strncmp (IDENTIFIER_POINTER (name), dguide_base,
-		       strlen (dguide_base)));
+	  && startswith (IDENTIFIER_POINTER (name), dguide_base));
 }
 
 /* True if FN is a deduction guide.  */
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index ce098617c62..7561552a0ad 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -758,8 +758,7 @@ do_build_builtin_fn (built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
 
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index 5e71f3b24a1..9e74a0dbf1f 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -6881,7 +6881,7 @@ Expression *evaluateIfBuiltin(UnionExp *pue, InterState *istate, Loc loc,
         const char *id = fd->ident->toChars();
         size_t idlen = strlen(id);
         if (nargs == 2 && (idlen == 10 || idlen == 11) &&
-            !strncmp(id, "_aApply", 7))
+            startswith (id, "_aApply"))
         {
             // Functions from aApply.d and aApplyR.d in the runtime
             bool rvs = (idlen == 11);   // true if foreach_reverse
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index 83f4c18bee8..f112243cf5f 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -673,7 +673,7 @@ public:
                 cd == ClassDeclaration::object ||
                 cd == Type::typeinfoclass ||
                 cd == Module::moduleinfo ||
-                strncmp(cd->ident->toChars(), "TypeInfo_", 9) == 0)
+                startswith (cd->ident->toChars(), "TypeInfo_"))
             {
                 // Don't mangle parent
                 ad->parent = NULL;
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index 9397b1e8abd..e72273b2dbd 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -3212,7 +3212,7 @@ public:
         }
         else if (p->type->ty == Tident &&
                  strlen(((TypeIdentifier *)p->type)->ident->toChars()) > 3 &&
-                 strncmp(((TypeIdentifier *)p->type)->ident->toChars(), "__T", 3) == 0)
+                 startswith (((TypeIdentifier *)p->type)->ident->toChars(), "__T"))
         {
             // print parameter name, instead of undetermined type parameter
             buf->writestring(p->ident->toChars());
diff --git a/gcc/d/dmd/identifier.c b/gcc/d/dmd/identifier.c
index 197d288e532..dd2c58fd657 100644
--- a/gcc/d/dmd/identifier.c
+++ b/gcc/d/dmd/identifier.c
@@ -73,11 +73,11 @@ const char *Identifier::toHChars2()
     {   p = toChars();
         if (*p == '_')
         {
-            if (strncmp(p, "_staticCtor", 11) == 0)
+            if (startswith(p, "_staticCtor"))
                 p = "static this";
-            else if (strncmp(p, "_staticDtor", 11) == 0)
+            else if (startswith(p, "_staticDtor"))
                 p = "static ~this";
-            else if (strncmp(p, "__invariant", 11) == 0)
+            else if (startswith(p, "__invariant"))
                 p = "invariant";
         }
     }
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 7a15debcb48..728e89b331d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5474,7 +5474,7 @@ is_cxx (const_tree decl)
     {
       const_tree context = get_ultimate_context (decl);
       if (context && TRANSLATION_UNIT_LANGUAGE (context))
-	return strncmp (TRANSLATION_UNIT_LANGUAGE (context), "GNU C++", 7) == 0;
+	return startswith (TRANSLATION_UNIT_LANGUAGE (context), "GNU C++");
     }
   return is_cxx ();
 }
@@ -24732,8 +24732,8 @@ gen_compile_unit_die (const char *filename)
 	    common_lang = TRANSLATION_UNIT_LANGUAGE (t);
 	  else if (strcmp (common_lang, TRANSLATION_UNIT_LANGUAGE (t)) == 0)
 	    ;
-	  else if (strncmp (common_lang, "GNU C", 5) == 0
-		    && strncmp (TRANSLATION_UNIT_LANGUAGE (t), "GNU C", 5) == 0)
+	  else if (startswith (common_lang, "GNU C")
+		    && startswith (TRANSLATION_UNIT_LANGUAGE (t), "GNU C"))
 	    /* Mixing C and C++ is ok, use C++ in that case.  */
 	    common_lang = highest_c_language (common_lang,
 					      TRANSLATION_UNIT_LANGUAGE (t));
@@ -24750,7 +24750,7 @@ gen_compile_unit_die (const char *filename)
     }
 
   language = DW_LANG_C;
-  if (strncmp (language_string, "GNU C", 5) == 0
+  if (startswith (language_string, "GNU C")
       && ISDIGIT (language_string[5]))
     {
       language = DW_LANG_C89;
@@ -24766,7 +24766,7 @@ gen_compile_unit_die (const char *filename)
 	      language = DW_LANG_C11;
 	}
     }
-  else if (strncmp (language_string, "GNU C++", 7) == 0)
+  else if (startswith (language_string, "GNU C++"))
     {
       language = DW_LANG_C_plus_plus;
       if (dwarf_version >= 5 /* || !dwarf_strict */)
@@ -24788,7 +24788,7 @@ gen_compile_unit_die (const char *filename)
     {
       if (strcmp (language_string, "GNU Ada") == 0)
 	language = DW_LANG_Ada95;
-      else if (strncmp (language_string, "GNU Fortran", 11) == 0)
+      else if (startswith (language_string, "GNU Fortran"))
 	{
 	  language = DW_LANG_Fortran95;
 	  if (dwarf_version >= 5 /* || !dwarf_strict */)
@@ -24812,7 +24812,7 @@ gen_compile_unit_die (const char *filename)
 	}
     }
   /* Use a degraded Fortran setting in strict DWARF2 so is_fortran works.  */
-  else if (strncmp (language_string, "GNU Fortran", 11) == 0)
+  else if (startswith (language_string, "GNU Fortran"))
     language = DW_LANG_Fortran90;
   /* Likewise for Ada.  */
   else if (strcmp (language_string, "GNU Ada") == 0)
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 947e4f868a1..413c7a75e0c 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -2721,7 +2721,7 @@ variable_decl (int elem)
     }
 
   /* %FILL components may not have initializers.  */
-  if (gfc_str_startswith (name, "%FILL") && gfc_match_eos () != MATCH_YES)
+  if (startswith (name, "%FILL") && gfc_match_eos () != MATCH_YES)
     {
       gfc_error ("%qs entity cannot have an initializer at %C", "%FILL");
       m = MATCH_ERROR;
@@ -8221,7 +8221,7 @@ gfc_match_end (gfc_statement *st)
     {
     case COMP_ASSOCIATE:
     case COMP_BLOCK:
-      if (gfc_str_startswith (block_name, "block@"))
+      if (startswith (block_name, "block@"))
 	block_name = NULL;
       break;
 
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 7935aca23db..b8e67bcc03e 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3514,10 +3514,6 @@ bool gfc_is_compile_time_shape (gfc_array_spec *);
 
 bool gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *, mpz_t *);
 
-
-#define gfc_str_startswith(str, pref) \
-	(strncmp ((str), (pref), strlen (pref)) == 0)
-
 /* interface.c -- FIXME: some of these should be in symbol.c */
 void gfc_free_interface (gfc_interface *);
 bool gfc_compare_derived_types (gfc_symbol *, gfc_symbol *);
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 4db0a3ac76d..a55855548b4 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -5029,7 +5029,7 @@ load_omp_udrs (void)
       mio_pool_string (&name);
       gfc_clear_ts (&ts);
       mio_typespec (&ts);
-      if (gfc_str_startswith (name, "operator "))
+      if (startswith (name, "operator "))
 	{
 	  const char *p = name + sizeof ("operator ") - 1;
 	  if (strcmp (p, "+") == 0)
@@ -5477,8 +5477,8 @@ read_module (void)
 
 	  /* Exception: Always import vtabs & vtypes.  */
 	  if (p == NULL && name[0] == '_'
-	      && (gfc_str_startswith (name, "__vtab_")
-		  || gfc_str_startswith (name, "__vtype_")))
+	      && (startswith (name, "__vtab_")
+		  || startswith (name, "__vtype_")))
 	    p = name;
 
 	  /* Skip symtree nodes not in an ONLY clause, unless there
@@ -5563,8 +5563,8 @@ read_module (void)
 		sym->attr.use_rename = 1;
 
 	      if (name[0] != '_'
-		  || (!gfc_str_startswith (name, "__vtab_")
-		      && !gfc_str_startswith (name, "__vtype_")))
+		  || (!startswith (name, "__vtab_")
+		      && !startswith (name, "__vtype_")))
 		sym->attr.use_only = only_flag;
 
 	      /* Store the symtree pointing to this symbol.  */
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 3a0b98bf1ec..1723f689a57 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -615,7 +615,7 @@ gfc_handle_runtime_check_option (const char *arg)
 	      result = 1;
 	      break;
 	    }
-	  else if (optname[n] && pos > 3 && gfc_str_startswith (arg, "no-")
+	  else if (optname[n] && pos > 3 && startswith (arg, "no-")
 		   && strncmp (optname[n], arg+3, pos-3) == 0)
 	    {
 	      gfc_option.rtcheck &= ~optmask[n];
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index a6df885c80c..9fe8d1ee20c 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1786,21 +1786,21 @@ match_arg_list_function (gfc_actual_arglist *result)
       switch (name[0])
 	{
 	case 'l':
-	  if (gfc_str_startswith (name, "loc"))
+	  if (startswith (name, "loc"))
 	    {
 	      result->name = "%LOC";
 	      break;
 	    }
 	  /* FALLTHRU */
 	case 'r':
-	  if (gfc_str_startswith (name, "ref"))
+	  if (startswith (name, "ref"))
 	    {
 	      result->name = "%REF";
 	      break;
 	    }
 	  /* FALLTHRU */
 	case 'v':
-	  if (gfc_str_startswith (name, "val"))
+	  if (startswith (name, "val"))
 	    {
 	      result->name = "%VAL";
 	      break;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 34a0d49bae7..48b987f08fc 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1940,7 +1940,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
      Marking this as artificial means that OpenMP will treat this as
      predetermined shared.  */
 
-  bool def_init = gfc_str_startswith (sym->name, "__def_init");
+  bool def_init = startswith (sym->name, "__def_init");
 
   if (sym->attr.vtab || def_init)
     {
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 2fa17b36c03..27bb8b9099e 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6803,7 +6803,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
       /* When calling __copy for character expressions to unlimited
 	 polymorphic entities, the dst argument needs a string length.  */
       if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
-	  && gfc_str_startswith (sym->name, "__vtab_CHARACTER")
+	  && startswith (sym->name, "__vtab_CHARACTER")
 	  && arg->next && arg->next->expr
 	  && (arg->next->expr->ts.type == BT_DERIVED
 	      || arg->next->expr->ts.type == BT_CLASS)
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 5e53d1162fa..1369d2f76b9 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -10072,27 +10072,27 @@ gfc_conv_ieee_arithmetic_function (gfc_se * se, gfc_expr * expr)
 {
   const char *name = expr->value.function.name;
 
-  if (gfc_str_startswith (name, "_gfortran_ieee_is_nan"))
+  if (startswith (name, "_gfortran_ieee_is_nan"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISNAN, 1);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_finite"))
+  else if (startswith (name, "_gfortran_ieee_is_finite"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISFINITE, 1);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_unordered"))
+  else if (startswith (name, "_gfortran_ieee_unordered"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISUNORDERED, 2);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_normal"))
+  else if (startswith (name, "_gfortran_ieee_is_normal"))
     conv_intrinsic_ieee_is_normal (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_negative"))
+  else if (startswith (name, "_gfortran_ieee_is_negative"))
     conv_intrinsic_ieee_is_negative (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_copy_sign"))
+  else if (startswith (name, "_gfortran_ieee_copy_sign"))
     conv_intrinsic_ieee_copy_sign (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_scalb"))
+  else if (startswith (name, "_gfortran_ieee_scalb"))
     conv_intrinsic_ieee_scalb (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_next_after"))
+  else if (startswith (name, "_gfortran_ieee_next_after"))
     conv_intrinsic_ieee_next_after (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_rem"))
+  else if (startswith (name, "_gfortran_ieee_rem"))
     conv_intrinsic_ieee_rem (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_logb"))
+  else if (startswith (name, "_gfortran_ieee_logb"))
     conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_LOGB);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_rint"))
+  else if (startswith (name, "_gfortran_ieee_rint"))
     conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_RINT);
   else
     /* It is not among the functions we translate directly.  We return
diff --git a/gcc/gcc-ar.c b/gcc/gcc-ar.c
index e76d4525e0c..cbc7662e03d 100644
--- a/gcc/gcc-ar.c
+++ b/gcc/gcc-ar.c
@@ -140,7 +140,7 @@ main (int ac, char **av)
 
   /* Not using getopt for now.  */
   for (i = 0; i < ac; i++)
-      if (!strncmp (av[i], "-B", 2))
+      if (startswith (av[i], "-B"))
 	{
 	  const char *arg = av[i] + 2;
 	  const char *end;
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 7837553958b..0a17e86ccea 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1900,7 +1900,7 @@ init_spec (void)
        when given the proper command line arguments.  */
     while (*p)
       {
-	if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
+	if (in_sep && *p == '-' && startswith (p, "-lgcc"))
 	  {
 	    init_gcc_specs (&obstack,
 			    "-lgcc_s"
@@ -1923,7 +1923,7 @@ init_spec (void)
 	    p += 5;
 	    in_sep = 0;
 	  }
-	else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
+	else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
 	  {
 	    /* Ug.  We don't know shared library extensions.  Hope that
 	       systems that use this form don't do shared libraries.  */
@@ -2378,7 +2378,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 	  /* Skip '\n'.  */
 	  p++;
 
-	  if (!strncmp (p1, "%include", sizeof ("%include") - 1)
+	  if (startswith (p1, "%include")
 	      && (p1[sizeof "%include" - 1] == ' '
 		  || p1[sizeof "%include" - 1] == '\t'))
 	    {
@@ -2399,7 +2399,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 	      read_specs (new_filename ? new_filename : p1, false, user_p);
 	      continue;
 	    }
-	  else if (!strncmp (p1, "%include_noerr", sizeof "%include_noerr" - 1)
+	  else if (startswith (p1, "%include_noerr")
 		   && (p1[sizeof "%include_noerr" - 1] == ' '
 		       || p1[sizeof "%include_noerr" - 1] == '\t'))
 	    {
@@ -2423,7 +2423,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 		fnotice (stderr, "could not find specs file %s\n", p1);
 	      continue;
 	    }
-	  else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
+	  else if (startswith (p1, "%rename")
 		   && (p1[sizeof "%rename" - 1] == ' '
 		       || p1[sizeof "%rename" - 1] == '\t'))
 	    {
@@ -3496,7 +3496,7 @@ execute (void)
 		&& WEXITSTATUS (status) == ICE_EXIT_CODE
 		&& i == 0
 		&& (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
-		&& ! strncmp (p + 1, "cc1", 3))
+		&& startswith (p + 1, "cc1"))
 	      try_generate_repro (commands[0].argv);
 	    if (WEXITSTATUS (status) > greatest_status)
 	      greatest_status = WEXITSTATUS (status);
@@ -7324,7 +7324,7 @@ check_live_switch (int switchnum, int prefix_length)
       break;
 
     case 'W':  case 'f':  case 'm': case 'g':
-      if (! strncmp (name + 1, "no-", 3))
+      if (startswith (name + 1, "no-"))
 	{
 	  /* We have Xno-YYY, search for XYYY.  */
 	  for (i = switchnum + 1; i < n_switches; i++)
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index afea3602e50..e69d175a05a 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -4344,7 +4344,7 @@ write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
     write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
 		    known_true, -2, 0, 0);
 
-  if (strncmp (prefix, "return", 6))
+  if (!startswith (prefix, "return"))
     {
       write_indent (outf, indent + 2);
       fprintf (outf, "break;\n");
@@ -5377,14 +5377,12 @@ main (int argc, const char **argv)
       {
         FILE *outf;
 
-#define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
-	if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
+	if (startswith(attr->name, "*internal_dfa_insn_code"))
 	  outf = dfa_file;
-	else if (IS_ATTR_GROUP ("*insn_default_latency"))
+	else if (startswith (attr->name, "*insn_default_latency"))
 	  outf = latency_file;  
 	else
 	  outf = attr_file;
-#undef IS_ATTR_GROUP
 
 	if (! attr->is_special && ! attr->is_const)
 	  write_attr_get (outf, attr);
diff --git a/gcc/gencfn-macros.c b/gcc/gencfn-macros.c
index b620fe6aebc..fd9ae14fc04 100644
--- a/gcc/gencfn-macros.c
+++ b/gcc/gencfn-macros.c
@@ -208,7 +208,7 @@ main (int argc, char **argv)
   for (unsigned int i = 0; builtin_names[i]; ++i)
     {
       const char *name = builtin_names[i];
-      if (strncmp (name, "BUILT_IN_", 9) == 0)
+      if (startswith (name, "BUILT_IN_"))
 	{
 	  const char *root = name + 9;
 	  for (unsigned int j = 0; suffix_lists[j]; ++j)
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 5f50242e857..7122ff763e3 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -671,7 +671,7 @@ type_for_name (const char *s)
          extern GTY(()) gcc::some_type *some_ptr;
      where the autogenerated functions will refer to simply "some_type",
      where they can be resolved into their namespace.  */
-  if (strncmp (s, "gcc::", 5) == 0)
+  if (startswith (s, "gcc::"))
     s += 5;
 
   for (p = typedefs; p != NULL; p = p->next)
@@ -1102,7 +1102,7 @@ gen_rtx_next (void)
       int k;
 
       rtx_next_new[i] = -1;
-      if (strncmp (rtx_format[i], "uu", 2) == 0)
+      if (startswith (rtx_format[i], "uu"))
 	rtx_next_new[i] = 1;
       else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
 	rtx_next_new[i] = 1;
@@ -1828,7 +1828,7 @@ get_file_langdir (const input_file *inpf)
     return NULL;
 
   lang_index = get_prefix_langdir_index (srcdir_relative_path);
-  if (lang_index < 0 && strncmp (srcdir_relative_path, "c-family", 8) == 0)
+  if (lang_index < 0 && startswith (srcdir_relative_path, "c-family"))
     r = "c-family";
   else if (lang_index >= 0)
     r = lang_dir_names[lang_index];
@@ -4044,7 +4044,7 @@ write_local (outf_p output_header, type_p structures)
 	   || ((s)->gc_used == GC_MAYBE_POINTED_TO			\
 	       && s->u.s.line.file != NULL)				\
 	   || ((s)->gc_used == GC_USED					\
-	       && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))) \
+	       && !startswith (s->u.s.tag, "anonymous"))		\
 	   || (s->u.s.base_class && opts_have (s->u.s.opt, "tag")))))
 
 
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 8311f5d768a..332afc842b7 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -605,10 +605,10 @@ get_operator (const char *id, bool allow_null = false)
       for (unsigned int i = 0; id2[i]; ++i)
 	id2[i] = TOUPPER (id2[i]);
     }
-  else if (all_upper && strncmp (id, "IFN_", 4) == 0)
+  else if (all_upper && startswith (id, "IFN_"))
     /* Try CFN_ instead of IFN_.  */
     id2 = ACONCAT (("CFN_", id + 4, NULL));
-  else if (all_upper && strncmp (id, "BUILT_IN_", 9) == 0)
+  else if (all_upper && startswith (id, "BUILT_IN_"))
     /* Try prepending CFN_.  */
     id2 = ACONCAT (("CFN_", id, NULL));
   else
@@ -2391,7 +2391,7 @@ get_operand_type (id_base *op, unsigned pos,
   else if (*op == COND_EXPR
 	   && pos == 0)
     return "boolean_type_node";
-  else if (strncmp (op->id, "CFN_COND_", 9) == 0)
+  else if (startswith (op->id, "CFN_COND_"))
     {
       /* IFN_COND_* operands 1 and later by default have the same type
 	 as the result.  The type of operand 0 needs to be specified
@@ -2464,7 +2464,7 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
     }
   else if (*opr == COND_EXPR
 	   || *opr == VEC_COND_EXPR
-	   || strncmp (opr->id, "CFN_COND_", 9) == 0)
+	   || startswith (opr->id, "CFN_COND_"))
     {
       /* Conditions are of the same type as their first alternative.  */
       snprintf (optype, sizeof (optype), "TREE_TYPE (_o%d[1])", depth);
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 25af4375d9c..8e911cce2f5 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -841,7 +841,7 @@ validate_optab_operands (class data *d)
     return;
 
   /* Miscellaneous tests.  */
-  if (strncmp (d->name, "cstore", 6) == 0
+  if (startswith (d->name, "cstore")
       && d->name[strlen (d->name) - 1] == '4'
       && d->operand[0].mode == VOIDmode)
     {
diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc
index 3cc5ded3617..514c045a68f 100644
--- a/gcc/go/gofrontend/runtime.cc
+++ b/gcc/go/gofrontend/runtime.cc
@@ -463,7 +463,7 @@ Runtime::name_to_code(const std::string& name)
       // The names in the table have "runtime." prefix. We may be
       // called with a name without the prefix. Try matching
       // without the prefix as well.
-      if (strncmp(runtime_function_name, "runtime.", 8) == 0
+      if (startswith(runtime_function_name, "runtime.")
           && strcmp(runtime_function_name + 8, name.c_str()) == 0)
         code = static_cast<Runtime::Function>(i);
     }
diff --git a/gcc/incpath.c b/gcc/incpath.c
index 446d280321d..52dbb806b1b 100644
--- a/gcc/incpath.c
+++ b/gcc/incpath.c
@@ -330,7 +330,7 @@ add_sysroot_to_chain (const char *sysroot, int chain)
 	{
 	  if (p->name[0] == '=')
 	    p->name = concat (sysroot, p->name + 1, NULL);
-	  if (strncmp (p->name, "$SYSROOT", strlen ("$SYSROOT")) == 0)
+	  if (startswith (p->name, "$SYSROOT"))
 	    p->name = concat (sysroot, p->name + strlen ("$SYSROOT"), NULL);
 	}
     }
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 2354386f7b4..12c99888e6c 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -901,7 +901,7 @@ lhd_finalize_early_debug (void)
 bool
 lang_GNU_C (void)
 {
-  return (strncmp (lang_hooks.name, "GNU C", 5) == 0
+  return (startswith (lang_hooks.name, "GNU C")
 	  && (lang_hooks.name[5] == '\0' || ISDIGIT (lang_hooks.name[5])));
 }
 
@@ -910,7 +910,7 @@ lang_GNU_C (void)
 bool
 lang_GNU_CXX (void)
 {
-  return strncmp (lang_hooks.name, "GNU C++", 7) == 0;
+  return startswith (lang_hooks.name, "GNU C++");
 }
 
 /* Returns true if the current lang_hooks represents the GNU Fortran frontend.  */
@@ -918,7 +918,7 @@ lang_GNU_CXX (void)
 bool
 lang_GNU_Fortran (void)
 {
-  return strncmp (lang_hooks.name, "GNU Fortran", 11) == 0;
+  return startswith (lang_hooks.name, "GNU Fortran");
 }
 
 /* Returns true if the current lang_hooks represents the GNU Objective-C
@@ -927,5 +927,5 @@ lang_GNU_Fortran (void)
 bool
 lang_GNU_OBJC (void)
 {
-  return strncmp (lang_hooks.name, "GNU Objective-C", 15) == 0;
+  return startswith (lang_hooks.name, "GNU Objective-C");
 }
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 03a5922f8ea..efb6ee644f4 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -1437,8 +1437,7 @@ run_gcc (unsigned argc, char *argv[])
       int consumed;
       char *filename = argv[i];
 
-      if (strncmp (argv[i], "-foffload-objects=",
-		   sizeof ("-foffload-objects=") - 1) == 0)
+      if (startswith (argv[i], "-foffload-objects="))
 	{
 	  have_offload = true;
 	  offload_objects_file_name
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 1cbd586b8fb..796256d437e 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -10275,7 +10275,7 @@ objc_string_ref_type_p (tree strp)
   return (tmv
 	  && TREE_CODE (tmv) == IDENTIFIER_NODE
 	  && IDENTIFIER_POINTER (tmv)
-	  && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
+	  && startswith (IDENTIFIER_POINTER (tmv), "NSString"));
 }
 
 /* At present the behavior of this is undefined and it does nothing.  */
diff --git a/gcc/objc/objc-encoding.c b/gcc/objc/objc-encoding.c
index c4067b1d527..7ad920a2c35 100644
--- a/gcc/objc/objc-encoding.c
+++ b/gcc/objc/objc-encoding.c
@@ -733,7 +733,7 @@ encode_type (tree type, int curtype, int format)
 	  char *enc = (char *) obstack_base (&util_obstack) + curtype;
 
 	  /* Rewrite "in const" from "nr" to "rn".  */
-	  if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
+	  if (curtype >= 1 && startswith (enc - 1, "nr"))
 	    memcpy (enc - 1, "rn", 2);
 	}
     }
diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c
index af68c1c84a3..3cfcd0b1a57 100644
--- a/gcc/objc/objc-next-runtime-abi-02.c
+++ b/gcc/objc/objc-next-runtime-abi-02.c
@@ -2209,7 +2209,7 @@ has_load_impl (tree clsmeth)
     {
       tree id = METHOD_SEL_NAME (clsmeth);
       if (IDENTIFIER_LENGTH (id) == 4
-	  && strncmp (IDENTIFIER_POINTER (id), "load", 4) == 0)
+	  && startswith (IDENTIFIER_POINTER (id), "load"))
         return true;
       clsmeth = DECL_CHAIN (clsmeth);
     }
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index fa6de01722b..a1bb9d8d25d 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -968,7 +968,7 @@ omp_max_simt_vf (void)
   if (ENABLE_OFFLOADING)
     for (const char *c = getenv ("OFFLOAD_TARGET_NAMES"); c;)
       {
-	if (!strncmp (c, "nvptx", strlen ("nvptx")))
+	if (startswith (c, "nvptx"))
 	  return 32;
 	else if ((c = strchr (c, ':')))
 	  c++;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 7b122059c6e..e735af974ee 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3786,7 +3786,7 @@ omp_runtime_api_call (const_tree fndecl)
     return false;
 
   const char *name = IDENTIFIER_POINTER (declname);
-  if (strncmp (name, "omp_", 4) != 0)
+  if (!startswith (name, "omp_"))
     return false;
 
   static const char *omp_runtime_apis[] =
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 5e10edeb4cf..9d1914ff2ff 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -1805,7 +1805,7 @@ parse_options_from_collect_gcc_options (const char *collect_gcc_options,
 	      if (argv_storage[j] == '\0')
 		fatal_error (input_location,
 			     "malformed %<COLLECT_GCC_OPTIONS%>");
-	      else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
+	      else if (startswith (&argv_storage[j], "'\\''"))
 		{
 		  argv_storage[k++] = '\'';
 		  j += 4;
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index 2a1fb4bac9c..eaf380dd466 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -1082,7 +1082,7 @@ function_reader::read_rtx_operand_r (rtx x)
 	 "orig:%i", ORIGINAL_REGNO (rtx).
 	 Consume it, we don't set ORIGINAL_REGNO, since we can
 	 get that from the 2nd copy later.  */
-      if (strncmp (desc, "orig:", 5) == 0)
+      if (startswith (desc, "orig:"))
 	{
 	  expect_original_regno = true;
 	  desc_start += 5;
diff --git a/gcc/real.c b/gcc/real.c
index 09957a91b7c..555cf44c142 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -1972,17 +1972,17 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
   else if (*str == '+')
     str++;
 
-  if (!strncmp (str, "QNaN", 4))
+  if (startswith (str, "QNaN"))
     {
       get_canonical_qnan (r, sign);
       return 0;
     }
-  else if (!strncmp (str, "SNaN", 4))
+  else if (startswith (str, "SNaN"))
     {
       get_canonical_snan (r, sign);
       return 0;
     }
-  else if (!strncmp (str, "Inf", 3))
+  else if (startswith (str, "Inf"))
     {
       get_inf (r, sign);
       return 0;
diff --git a/gcc/selftest.c b/gcc/selftest.c
index 6e26ea553f2..8f1cde0cc19 100644
--- a/gcc/selftest.c
+++ b/gcc/selftest.c
@@ -150,8 +150,7 @@ assert_str_startswith (const location &loc,
 		    "ASSERT_STR_STARTSWITH (%s, %s) str=\"%s\" prefix=NULL",
 		    desc_str, desc_prefix, val_str);
 
-  const char *test = strstr (val_str, val_prefix);
-  if (test == val_str)
+  if (startswith (val_str, val_prefix))
     pass (loc, "ASSERT_STR_STARTSWITH");
   else
     fail_formatted
diff --git a/gcc/system.h b/gcc/system.h
index a3f5948aaee..51ccf753fd4 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1291,4 +1291,12 @@ void gcc_stablesort (void *, size_t, size_t,
 #define NULL nullptr
 #endif
 
+/* Return true if STR string starts with PREFIX.  */
+
+static inline bool
+startswith (const char *str, const char *prefix)
+{
+  return strncmp (str, prefix, strlen (prefix)) == 0;
+}
+
 #endif /* ! GCC_SYSTEM_H */
diff --git a/gcc/timevar.c b/gcc/timevar.c
index 5d4e1597f23..8fc122ba9fe 100644
--- a/gcc/timevar.c
+++ b/gcc/timevar.c
@@ -600,7 +600,7 @@ timer::validate_phases (FILE *fp) const
       if (!tv->used)
 	continue;
 
-      if (strncmp (tv->name, phase_prefix, sizeof phase_prefix - 1) == 0)
+      if (startswith (tv->name, phase_prefix))
 	{
 	  phase_user += tv->elapsed.user;
 	  phase_sys += tv->elapsed.sys;
diff --git a/gcc/tree.c b/gcc/tree.c
index e4e74ac8afc..3ed7ea349f6 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9725,7 +9725,7 @@ get_file_function_name (const char *type)
      We also assign sub_I and sub_D sufixes to constructors called from
      the global static constructors.  These are always local.  */
   else if (((type[0] == 'I' || type[0] == 'D') && targetm.have_ctors_dtors)
-	   || (strncmp (type, "sub_", 4) == 0
+	   || (startswith (type, "sub_")
 	       && (type[4] == 'I' || type[4] == 'D')))
     {
       const char *file = main_input_filename;
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 1089aef639f..7ee93436378 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -1783,7 +1783,7 @@ ubsan_use_new_style_p (location_t loc)
     return false;
 
   expanded_location xloc = expand_location (loc);
-  if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
+  if (xloc.file == NULL || startswith (xloc.file, "\1")
       || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
       || xloc.file[1] == '\xff')
     return false;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 8bb921faa26..bc2727c9303 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -792,7 +792,7 @@ default_function_rodata_section (tree decl, bool relocatable)
       /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo or
 	 .gnu.linkonce.d.rel.ro.local.foo if the jump table is relocatable.  */
       else if (DECL_COMDAT_GROUP (decl)
-	       && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
+	       && startswith (name, ".gnu.linkonce.t."))
 	{
 	  size_t len;
 	  char *rname;
@@ -817,7 +817,7 @@ default_function_rodata_section (tree decl, bool relocatable)
 	}
       /* For .text.foo we want to use .rodata.foo.  */
       else if (flag_function_sections && flag_data_sections
-	       && strncmp (name, ".text.", 6) == 0)
+	       && startswith (name, ".text."))
 	{
 	  size_t len = strlen (name) + 1;
 	  char *rname = (char *) alloca (len + strlen (sname) - 5);
@@ -2485,7 +2485,7 @@ incorporeal_function_p (tree decl)
       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
       /* Atomic or sync builtins which have survived this far will be
 	 resolved externally and therefore are not incorporeal.  */
-      if (strncmp (name, "__builtin_", 10) == 0)
+      if (startswith (name, "__builtin_"))
 	return true;
     }
   return false;
@@ -6713,22 +6713,22 @@ default_section_type_flags (tree decl, const char *name, int reloc)
     flags |= SECTION_TLS | SECTION_WRITE;
 
   if (strcmp (name, ".bss") == 0
-      || strncmp (name, ".bss.", 5) == 0
-      || strncmp (name, ".gnu.linkonce.b.", 16) == 0
+      || startswith (name, ".bss.")
+      || startswith (name, ".gnu.linkonce.b.")
       || strcmp (name, ".persistent.bss") == 0
       || strcmp (name, ".sbss") == 0
-      || strncmp (name, ".sbss.", 6) == 0
-      || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
+      || startswith (name, ".sbss.")
+      || startswith (name, ".gnu.linkonce.sb."))
     flags |= SECTION_BSS;
 
   if (strcmp (name, ".tdata") == 0
-      || strncmp (name, ".tdata.", 7) == 0
-      || strncmp (name, ".gnu.linkonce.td.", 17) == 0)
+      || startswith (name, ".tdata.")
+      || startswith (name, ".gnu.linkonce.td."))
     flags |= SECTION_TLS;
 
   if (strcmp (name, ".tbss") == 0
-      || strncmp (name, ".tbss.", 6) == 0
-      || strncmp (name, ".gnu.linkonce.tb.", 17) == 0)
+      || startswith (name, ".tbss.")
+      || startswith (name, ".gnu.linkonce.tb."))
     flags |= SECTION_TLS | SECTION_BSS;
 
   if (strcmp (name, ".noinit") == 0)


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [gcc(refs/users/marxin/heads/str_starts_with-v2)] Come up with startswith function.
@ 2021-04-21  8:35 Martin Liska
  0 siblings, 0 replies; 3+ messages in thread
From: Martin Liska @ 2021-04-21  8:35 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:23431b3fa62222e0ad69e66cc7d3fe8bee5da29a

commit 23431b3fa62222e0ad69e66cc7d3fe8bee5da29a
Author: Martin Liska <mliska@suse.cz>
Date:   Wed Mar 17 16:36:44 2021 +0100

    Come up with startswith function.
    
    gcc/ada/ChangeLog:
    
            * gcc-interface/utils.c (def_builtin_1): Use startswith
            function instead of strncmp.
    
    gcc/analyzer/ChangeLog:
    
            * sm-file.cc (is_file_using_fn_p): Use startswith
            function instead of strncmp.
    
    gcc/ChangeLog:
    
            * builtins.c (is_builtin_name): Use startswith
            function instead of strncmp.
            * collect2.c (main): Likewise.
            (has_lto_section): Likewise.
            (scan_libraries): Likewise.
            * coverage.c (coverage_checksum_string): Likewise.
            (coverage_init): Likewise.
            * dwarf2out.c (is_cxx): Likewise.
            (gen_compile_unit_die): Likewise.
            * gcc-ar.c (main): Likewise.
            * gcc.c (init_spec): Likewise.
            (read_specs): Likewise.
            (execute): Likewise.
            (check_live_switch): Likewise.
            * genattrtab.c (write_attr_case): Likewise.
            (IS_ATTR_GROUP): Likewise.
            * gencfn-macros.c (main): Likewise.
            * gengtype.c (type_for_name): Likewise.
            (gen_rtx_next): Likewise.
            (get_file_langdir): Likewise.
            (write_local): Likewise.
            * genmatch.c (get_operator): Likewise.
            (get_operand_type): Likewise.
            (expr::gen_transform): Likewise.
            * genoutput.c (validate_optab_operands): Likewise.
            * incpath.c (add_sysroot_to_chain): Likewise.
            * langhooks.c (lang_GNU_C): Likewise.
            (lang_GNU_CXX): Likewise.
            (lang_GNU_Fortran): Likewise.
            (lang_GNU_OBJC): Likewise.
            * lto-wrapper.c (run_gcc): Likewise.
            * omp-general.c (omp_max_simt_vf): Likewise.
            * omp-low.c (omp_runtime_api_call): Likewise.
            * opts-common.c (parse_options_from_collect_gcc_options): Likewise.
            * read-rtl-function.c (function_reader::read_rtx_operand_r): Likewise.
            * real.c (real_from_string): Likewise.
            * selftest.c (assert_str_startswith): Likewise.
            * timevar.c (timer::validate_phases): Likewise.
            * tree.c (get_file_function_name): Likewise.
            * ubsan.c (ubsan_use_new_style_p): Likewise.
            * varasm.c (default_function_rodata_section): Likewise.
            (incorporeal_function_p): Likewise.
            (default_section_type_flags): Likewise.
            * system.h (startswith): Define startswith.
    
    gcc/c-family/ChangeLog:
    
            * c-ada-spec.c (print_destructor): Use startswith
            function instead of strncmp.
            (dump_ada_declaration): Likewise.
            * c-common.c (disable_builtin_function): Likewise.
            (def_builtin_1): Likewise.
            * c-format.c (check_tokens): Likewise.
            (check_plain): Likewise.
            (convert_format_name_to_system_name): Likewise.
    
    gcc/c/ChangeLog:
    
            * c-aux-info.c (affix_data_type): Use startswith
            function instead of strncmp.
            * c-typeck.c (build_function_call_vec): Likewise.
            * gimple-parser.c (c_parser_gimple_parse_bb_spec): Likewise.
    
    gcc/cp/ChangeLog:
    
            * decl.c (duplicate_decls): Use startswith
            function instead of strncmp.
            (cxx_builtin_function): Likewise.
            (omp_declare_variant_finalize_one): Likewise.
            (grokfndecl): Likewise.
            * error.c (dump_decl_name): Likewise.
            * mangle.c (find_decomp_unqualified_name): Likewise.
            (write_guarded_var_name): Likewise.
            (decl_tls_wrapper_p): Likewise.
            * parser.c (cp_parser_simple_type_specifier): Likewise.
            (cp_parser_tx_qualifier_opt): Likewise.
            * pt.c (template_parm_object_p): Likewise.
            (dguide_name_p): Likewise.
    
    gcc/d/ChangeLog:
    
            * d-builtins.cc (do_build_builtin_fn): Use startswith
            function instead of strncmp.
            * dmd/dinterpret.c (evaluateIfBuiltin): Likewise.
            * dmd/dmangle.c: Likewise.
            * dmd/hdrgen.c: Likewise.
            * dmd/identifier.c (Identifier::toHChars2): Likewise.
    
    gcc/fortran/ChangeLog:
    
            * decl.c (variable_decl): Use startswith
            function instead of strncmp.
            (gfc_match_end): Likewise.
            * gfortran.h (gfc_str_startswith): Likewise.
            * module.c (load_omp_udrs): Likewise.
            (read_module): Likewise.
            * options.c (gfc_handle_runtime_check_option): Likewise.
            * primary.c (match_arg_list_function): Likewise.
            * trans-decl.c (gfc_get_symbol_decl): Likewise.
            * trans-expr.c (gfc_conv_procedure_call): Likewise.
            * trans-intrinsic.c (gfc_conv_ieee_arithmetic_function): Likewise.
    
    gcc/go/ChangeLog:
    
            * gofrontend/runtime.cc (Runtime::name_to_code): Use startswith
            function instead of strncmp.
    
    gcc/objc/ChangeLog:
    
            * objc-act.c (objc_string_ref_type_p): Use startswith
            function instead of strncmp.
            * objc-encoding.c (encode_type): Likewise.
            * objc-next-runtime-abi-02.c (has_load_impl): Likewise.

Diff:
---
 gcc/ada/gcc-interface/utils.c       |  3 +--
 gcc/analyzer/sm-file.cc             |  5 ++--
 gcc/builtins.c                      | 10 +++-----
 gcc/c-family/c-ada-spec.c           |  8 +++----
 gcc/c-family/c-common.c             |  5 ++--
 gcc/c-family/c-format.c             | 20 ++++++++--------
 gcc/c/c-aux-info.c                  |  4 ++--
 gcc/c/c-typeck.c                    |  4 ++--
 gcc/c/gimple-parser.c               |  2 +-
 gcc/collect2.c                      | 48 +++++++++++++++++--------------------
 gcc/coverage.c                      |  7 +++---
 gcc/cp/decl.c                       | 15 ++++++------
 gcc/cp/error.c                      |  2 +-
 gcc/cp/mangle.c                     | 11 ++++-----
 gcc/cp/parser.c                     |  7 +++---
 gcc/cp/pt.c                         |  5 ++--
 gcc/d/d-builtins.cc                 |  3 +--
 gcc/d/dmd/dinterpret.c              |  2 +-
 gcc/d/dmd/dmangle.c                 |  2 +-
 gcc/d/dmd/hdrgen.c                  |  2 +-
 gcc/d/dmd/identifier.c              |  6 ++---
 gcc/dwarf2out.c                     | 14 +++++------
 gcc/fortran/decl.c                  |  4 ++--
 gcc/fortran/gfortran.h              |  4 ----
 gcc/fortran/module.c                | 10 ++++----
 gcc/fortran/options.c               |  2 +-
 gcc/fortran/primary.c               |  6 ++---
 gcc/fortran/trans-decl.c            |  2 +-
 gcc/fortran/trans-expr.c            |  2 +-
 gcc/fortran/trans-intrinsic.c       | 22 ++++++++---------
 gcc/gcc-ar.c                        |  2 +-
 gcc/gcc.c                           | 14 +++++------
 gcc/genattrtab.c                    |  8 +++----
 gcc/gencfn-macros.c                 |  2 +-
 gcc/gengtype.c                      |  8 +++----
 gcc/genmatch.c                      |  8 +++----
 gcc/genoutput.c                     |  2 +-
 gcc/go/gofrontend/runtime.cc        |  2 +-
 gcc/incpath.c                       |  2 +-
 gcc/langhooks.c                     |  8 +++----
 gcc/lto-wrapper.c                   |  3 +--
 gcc/objc/objc-act.c                 |  2 +-
 gcc/objc/objc-encoding.c            |  2 +-
 gcc/objc/objc-next-runtime-abi-02.c |  2 +-
 gcc/omp-general.c                   |  2 +-
 gcc/omp-low.c                       |  2 +-
 gcc/opts-common.c                   |  2 +-
 gcc/read-rtl-function.c             |  2 +-
 gcc/real.c                          |  6 ++---
 gcc/selftest.c                      |  3 +--
 gcc/system.h                        |  8 +++++++
 gcc/timevar.c                       |  2 +-
 gcc/tree.c                          |  2 +-
 gcc/ubsan.c                         |  2 +-
 gcc/varasm.c                        | 22 ++++++++---------
 55 files changed, 169 insertions(+), 186 deletions(-)

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 952f032072b..2d5ca4ba456 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -7016,8 +7016,7 @@ def_builtin_1 (enum built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
   decl = add_builtin_function (name, fntype, fncode, fnclass,
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index d64c313e31c..3a5f95def34 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -312,9 +312,8 @@ is_file_using_fn_p (tree fndecl)
 
   /* Also support variants of these names prefixed with "_IO_".  */
   const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
-  if (strncmp (name, "_IO_", 4) == 0)
-    if (fs.contains_name_p (name + 4))
-      return true;
+  if (startswith (name, "_IO_") && fs.contains_name_p (name + 4))
+    return true;
 
   return false;
 }
diff --git a/gcc/builtins.c b/gcc/builtins.c
index d30c4eb62fc..b8764fed597 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -740,13 +740,9 @@ pointer_query::flush_cache ()
 static bool
 is_builtin_name (const char *name)
 {
-  if (strncmp (name, "__builtin_", 10) == 0)
-    return true;
-  if (strncmp (name, "__sync_", 7) == 0)
-    return true;
-  if (strncmp (name, "__atomic_", 9) == 0)
-    return true;
-  return false;
+  return (startswith (name, "__builtin_")
+	  || startswith (name, "__sync_")
+	  || startswith (name, "__atomic_"));
 }
 
 /* Return true if NODE should be considered for inline expansion regardless
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 9fef5f05cc8..29eb0b01a91 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -2696,7 +2696,7 @@ print_destructor (pretty_printer *buffer, tree t, tree type)
   tree decl_name = DECL_NAME (TYPE_NAME (type));
 
   pp_string (buffer, "Delete_");
-  if (strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del", 8) == 0)
+  if (startswith (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del"))
     pp_string (buffer, "And_Free_");
   pp_ada_tree_identifier (buffer, decl_name, t, false);
 }
@@ -2980,9 +2980,9 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
 	    return 0;
 
 	  /* Only consider complete constructors and deleting destructors.  */
-	  if (strncmp (IDENTIFIER_POINTER (decl_name), "__ct_comp", 9) != 0
-	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_comp", 9) != 0
-	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_del", 8) != 0)
+	  if (!startswith (IDENTIFIER_POINTER (decl_name), "__ct_comp")
+	      && !startswith (IDENTIFIER_POINTER (decl_name), "__dt_comp")
+	      && !startswith (IDENTIFIER_POINTER (decl_name), "__dt_del"))
 	    return 0;
 	}
 
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d227686a030..7bd799d1825 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4670,7 +4670,7 @@ static bool builtin_function_disabled_p (const char *);
 void
 disable_builtin_function (const char *name)
 {
-  if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
+  if (startswith (name, "__builtin_"))
     error ("cannot disable built-in function %qs", name);
   else
     {
@@ -4718,8 +4718,7 @@ def_builtin_1 (enum built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
   decl = add_builtin_function (name, fntype, fncode, fnclass,
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 0a63cacb0d9..bda3b18fcd0 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -3097,7 +3097,7 @@ check_tokens (const token_t *tokens, unsigned ntoks,
       /* Allow this ugly warning for the time being.  */
       if (toklen == 2
 	  && format_chars - orig_format_chars > 6
-	  && !strncmp (format_chars - 7, " count >= width of ", 19))
+	  && startswith (format_chars - 7, " count >= width of "))
 	return format_chars + 10;
 
       /* The token is a type if it ends in an alphabetic character.  */
@@ -3127,7 +3127,7 @@ check_tokens (const token_t *tokens, unsigned ntoks,
   /* Diagnose unquoted __attribute__.  Consider any parenthesized
      argument to the attribute to avoid redundant warnings for
      the double parentheses that might follow.  */
-  if (!strncmp (format_chars, "__attribute", sizeof "__attribute" - 1))
+  if (startswith (format_chars, "__attribute"))
     {
       unsigned nchars = sizeof "__attribute" - 1;
       while ('_' == format_chars[nchars])
@@ -3178,9 +3178,9 @@ check_tokens (const token_t *tokens, unsigned ntoks,
   /* Diagnose unquoted built-ins.  */
   if (format_chars[0] == '_'
       && format_chars[1] == '_'
-      && (!strncmp (format_chars + 2, "atomic", sizeof "atomic" - 1)
-	  || !strncmp (format_chars + 2, "builtin", sizeof "builtin" - 1)
-	  || !strncmp (format_chars + 2, "sync", sizeof "sync" - 1)))
+      && (startswith (format_chars + 2, "atomic")
+	  || startswith (format_chars + 2, "builtin")
+	  || startswith (format_chars + 2, "sync")))
     {
       format_warning_substr (format_string_loc, format_string_cst,
 			     fmtchrpos, fmtchrpos + wlen, opt,
@@ -3267,7 +3267,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
   if (*format_chars == '%')
     {
       /* Diagnose %<%s%> and suggest using %qs instead.  */
-      if (!strncmp (format_chars, "%<%s%>", 6))
+      if (startswith (format_chars, "%<%s%>"))
 	format_warning_substr (format_string_loc, format_string_cst,
 			       fmtchrpos, fmtchrpos + 6, opt,
 			       "quoted %qs directive in format; "
@@ -3593,7 +3593,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 
       if (nchars == 1)
 	{
-	  if (!strncmp (format_chars, "\"%s\"", 4))
+	  if (startswith (format_chars, "\"%s\""))
 	    {
 	      if (format_warning_substr (format_string_loc, format_string_cst,
 					 fmtchrpos, fmtchrpos + 4, opt,
@@ -3621,7 +3621,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 	      && format_chars[0] == '(')
 	    ;   /* Text beginning in an open parenthesis.  */
 	  else if (nchars == 3
-	      && !strncmp (format_chars, "...", 3)
+	      && startswith (format_chars, "...")
 	      && format_chars[3])
 	    ;   /* Text beginning in an ellipsis.  */
 	  else
@@ -3663,7 +3663,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 		   a period at the end of a capitalized sentence.  */
 	  else if (nchars == 3
 		   && format_chars - orig_format_chars > 0
-		   && !strncmp (format_chars, "...", 3))
+		   && startswith (format_chars, "..."))
 	    ;   /* Text ending in the ellipsis.  */
 	  else
 	    format_warning_substr (format_string_loc, format_string_cst,
@@ -5104,7 +5104,7 @@ convert_format_name_to_system_name (const char *attr_name)
   int i;
 
   if (attr_name == NULL || *attr_name == 0
-      || strncmp (attr_name, "gcc_", 4) == 0)
+      || startswith (attr_name, "gcc_"))
     return attr_name;
 #ifdef TARGET_OVERRIDES_FORMAT_INIT
   TARGET_OVERRIDES_FORMAT_INIT ();
diff --git a/gcc/c/c-aux-info.c b/gcc/c/c-aux-info.c
index bae5757ad13..81860cb48cb 100644
--- a/gcc/c/c-aux-info.c
+++ b/gcc/c/c-aux-info.c
@@ -67,12 +67,12 @@ affix_data_type (const char *param)
 
   for (;;)
     {
-      if (!strncmp (p, "volatile ", 9))
+      if (startswith (p, "volatile "))
 	{
 	  p += 9;
 	  continue;
 	}
-      if (!strncmp (p, "const ", 6))
+      if (startswith (p, "const "))
 	{
 	  p += 6;
 	  continue;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 51a62c800f7..a523b934303 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3113,7 +3113,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
 	orig_fundecl = fundecl;
       /* Atomic functions have type checking/casting already done.  They are 
 	 often rewritten and don't match the original parameter list.  */
-      if (name && !strncmp (IDENTIFIER_POINTER (name), "__atomic_", 9))
+      if (name && startswith (IDENTIFIER_POINTER (name), "__atomic_"))
         origtypes = NULL;
     }
   if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
@@ -3199,7 +3199,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
 					    nargs, argarray, &arg_loc);
 
   if (name != NULL_TREE
-      && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
+      && startswith (IDENTIFIER_POINTER (name), "__builtin_"))
     {
       if (require_constant_value)
 	result
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 58b161b7c76..3a6e72ef002 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -131,7 +131,7 @@ static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *);
 static bool
 c_parser_gimple_parse_bb_spec (tree val, int *index)
 {
-  if (strncmp (IDENTIFIER_POINTER (val), "__BB", 4) != 0)
+  if (!startswith (IDENTIFIER_POINTER (val), "__BB"))
     return false;
   for (const char *p = IDENTIFIER_POINTER (val) + 4; *p; ++p)
     if (!ISDIGIT (*p))
diff --git a/gcc/collect2.c b/gcc/collect2.c
index bd371430ab7..0ddb1693b67 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -956,7 +956,7 @@ main (int argc, char **argv)
       {
 	if (! strcmp (argv[i], "-debug"))
 	  debug = true;
-	else if (!strncmp (argv[i], "-fno-lto", 8))
+	else if (startswith (argv[i], "-fno-lto"))
 	  lto_mode = LTO_MODE_NONE;
         else if (! strcmp (argv[i], "-plugin"))
 	  {
@@ -970,7 +970,7 @@ main (int argc, char **argv)
 	  selected_linker = USE_GOLD_LD;
 	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
 	  selected_linker = USE_LLD_LD;
-	else if (strncmp (argv[i], "-o", 2) == 0)
+	else if (startswith (argv[i], "-o"))
 	  {
 	    /* Parse the output filename if it's given so that we can make
 	       meaningful temp filenames.  */
@@ -984,19 +984,19 @@ main (int argc, char **argv)
 	/* These flags are position independent, although their order
 	   is important - subsequent flags override earlier ones. */
 	else if (strcmp (argv[i], "-b64") == 0)
-	    aix64_flag = 1;
+	  aix64_flag = 1;
 	/* -bexport:filename always needs the :filename */
-	else if (strncmp (argv[i], "-bE:", 4) == 0
-	      || strncmp (argv[i], "-bexport:", 9) == 0)
-	    export_flag = 1;
+	else if (startswith (argv[i], "-bE:")
+		 || startswith (argv[i], "-bexport:"))
+	  export_flag = 1;
 	else if (strcmp (argv[i], "-brtl") == 0
 	      || strcmp (argv[i], "-bsvr4") == 0
 	      || strcmp (argv[i], "-G") == 0)
-	    aixrtl_flag = 1;
+	  aixrtl_flag = 1;
 	else if (strcmp (argv[i], "-bnortl") == 0)
-	    aixrtl_flag = 0;
+	  aixrtl_flag = 0;
 	else if (strcmp (argv[i], "-blazy") == 0)
-	    aixlazy_flag = 1;
+	  aixlazy_flag = 1;
 #endif
       }
 
@@ -1016,11 +1016,11 @@ main (int argc, char **argv)
 	const char *q = extract_string (&p);
 	if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
 	  num_c_args++;
-	if (strncmp (q, "-flto-partition=none", 20) == 0)
+	if (startswith (q, "-flto-partition=none"))
 	  no_partition = true;
-	else if (strncmp (q, "-fno-lto", 8) == 0)
+	else if (startswith (q, "-fno-lto"))
 	  lto_mode = LTO_MODE_NONE;
-	else if (strncmp (q, "-save-temps", 11) == 0)
+	else if (startswith (q, "-save-temps"))
 	  /* FIXME: Honour =obj.  */
 	  save_temps = true;
 	else if (strcmp (q, "-dumpdir") == 0)
@@ -1254,7 +1254,7 @@ main (int argc, char **argv)
 	(void) extract_string (&p);
 #ifdef COLLECT_EXPORT_LIST
       /* Detect any invocation with -fvisibility.  */
-      if (strncmp (q, "-fvisibility", 12) == 0)
+      if (startswith (q, "-fvisibility"))
 	visibility_flag = 1;
 #endif
     }
@@ -1303,7 +1303,7 @@ main (int argc, char **argv)
 	      break;
 
             case 'f':
-	      if (strncmp (arg, "-flto", 5) == 0)
+	      if (startswith (arg, "-flto"))
 		{
 #ifdef ENABLE_LTO
 		  /* Do not pass LTO flag to the linker. */
@@ -1315,13 +1315,13 @@ main (int argc, char **argv)
 #endif
 		}
 	      else if (!use_collect_ld
-		       && strncmp (arg, "-fuse-ld=", 9) == 0)
+		       && startswith (arg, "-fuse-ld="))
 		{
 		  /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */
 		  ld1--;
 		  ld2--;
 		}
-	      else if (strncmp (arg, "-fno-lto", 8) == 0)
+	      else if (startswith (arg, "-fno-lto"))
 		{
 		  /* Do not pass -fno-lto to the linker. */
 		  ld1--;
@@ -1462,7 +1462,7 @@ main (int argc, char **argv)
 		  ld2--;
 #endif
 		}
-	      else if (strncmp (arg, "--demangle", 10) == 0)
+	      else if (startswith (arg, "--demangle"))
 		{
 #ifndef HAVE_LD_DEMANGLE
 		  no_demangle = 0;
@@ -1479,7 +1479,7 @@ main (int argc, char **argv)
 		  ld2--;
 #endif
 		}
-	      else if (strncmp (arg, "--sysroot=", 10) == 0)
+	      else if (startswith (arg, "--sysroot="))
 		target_system_root = arg + 10;
 	      else if (strcmp (arg, "--version") == 0)
 		verbose = true;
@@ -2307,13 +2307,9 @@ has_lto_section (void *data, const char *name ATTRIBUTE_UNUSED,
 {
   int *found = (int *) data;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
-	       sizeof (LTO_SECTION_NAME_PREFIX) - 1) != 0)
-    {
-      if (strncmp (name, OFFLOAD_SECTION_NAME_PREFIX,
-	           sizeof (OFFLOAD_SECTION_NAME_PREFIX) - 1) != 0)
-        return 1;
-    }
+  if (!startswith (name, LTO_SECTION_NAME_PREFIX)
+      && !startswith (name, OFFLOAD_SECTION_NAME_PREFIX))
+    return 1;
 
   *found = 1;
 
@@ -2619,7 +2615,7 @@ scan_libraries (const char *prog_name)
 	continue;
 
       name = p;
-      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
+      if (startswith (name, "not found"))
 	fatal_error (input_location, "dynamic dependency %s not found", buf);
 
       /* Find the end of the symbol name.  */
diff --git a/gcc/coverage.c b/gcc/coverage.c
index dc9ea6f3ee1..5a344cdfc17 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -488,9 +488,9 @@ coverage_checksum_string (unsigned chksum, const char *string)
   for (i = 0; string[i]; i++)
     {
       int offset = 0;
-      if (!strncmp (string + i, "_GLOBAL__N_", 11))
+      if (startswith (string + i, "_GLOBAL__N_"))
       offset = 11;
-      if (!strncmp (string + i, "_GLOBAL__", 9))
+      if (startswith (string + i, "_GLOBAL__"))
       offset = 9;
 
       /* C++ namespaces do have scheme:
@@ -1256,8 +1256,7 @@ coverage_init (const char *filename)
 	  filename = concat (getpwd (), separator, filename, NULL);
 	  if (profile_prefix_path)
 	    {
-	      if (!strncmp (filename, profile_prefix_path,
-			    strlen (profile_prefix_path)))
+	      if (startswith (filename, profile_prefix_path))
 		{
 		  filename += strlen (profile_prefix_path);
 		  while (*filename == *separator)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b81de8ef934..d6c7bc70823 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1609,8 +1609,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
 
 		  if (name[0] == '_'
 		      && name[1] == '_'
-		      && (strncmp (name + 2, "builtin_",
-				   strlen ("builtin_")) == 0
+		      && (startswith (name + 2, "builtin_")
 			  || (len = strlen (name)) <= strlen ("___chk")
 			  || memcmp (name + len - strlen ("_chk"),
 				     "_chk", strlen ("_chk") + 1) != 0))
@@ -4828,7 +4827,7 @@ cxx_builtin_function (tree decl)
     /* In the user's namespace, it must be declared before use.  */
     hiding = true;
   else if (IDENTIFIER_LENGTH (id) > strlen ("___chk")
-	   && 0 != strncmp (name + 2, "builtin_", strlen ("builtin_"))
+	   && !startswith (name + 2, "builtin_")
 	   && 0 == memcmp (name + IDENTIFIER_LENGTH (id) - strlen ("_chk"),
 			   "_chk", strlen ("_chk") + 1))
     /* Treat __*_chk fortification functions as anticipated as well,
@@ -7565,9 +7564,9 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
 	  return true;
 	}
       if (fndecl_built_in_p (variant)
-	  && (strncmp (varname, "__builtin_", strlen ("__builtin_")) == 0
-	      || strncmp (varname, "__sync_", strlen ("__sync_")) == 0
-	      || strncmp (varname, "__atomic_", strlen ("__atomic_")) == 0))
+	  && (startswith (varname, "__builtin_")
+	      || startswith (varname, "__sync_")
+	      || startswith (varname, "__atomic_")))
 	{
 	  error_at (varid_loc, "variant %qD is a built-in", variant);
 	  return true;
@@ -9833,8 +9832,8 @@ grokfndecl (tree ctype,
 	  || (IDENTIFIER_LENGTH (declarator) > 10
 	      && IDENTIFIER_POINTER (declarator)[0] == '_'
 	      && IDENTIFIER_POINTER (declarator)[1] == '_'
-	      && strncmp (IDENTIFIER_POINTER (declarator)+2,
-			  "builtin_", 8) == 0)
+	      && startswith (IDENTIFIER_POINTER (declarator) + 2,
+			     "builtin_"))
 	  || (targetcm.cxx_implicit_extern_c
 	      && (targetcm.cxx_implicit_extern_c
 		  (IDENTIFIER_POINTER (declarator))))))
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ff4ae6f4b23..a4e9b2a6ad9 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1138,7 +1138,7 @@ dump_decl_name (cxx_pretty_printer *pp, tree t, int flags)
     }
 
   const char *str = IDENTIFIER_POINTER (t);
-  if (!strncmp (str, "_ZGR", 4))
+  if (startswith (str, "_ZGR"))
     {
       pp_cxx_ws_string (pp, "<temporary>");
       return;
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 49f1266bef3..f0e1f416804 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1308,10 +1308,10 @@ find_decomp_unqualified_name (tree decl, size_t *len)
   const char *p = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
   const char *end = p + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
   bool nested = false;
-  if (strncmp (p, "_Z", 2))
+  if (!startswith (p, "_Z"))
     return NULL;
   p += 2;
-  if (!strncmp (p, "St", 2))
+  if (startswith (p, "St"))
     p += 2;
   else if (*p == 'N')
     {
@@ -1327,7 +1327,7 @@ find_decomp_unqualified_name (tree decl, size_t *len)
 	    break;
 	}
     }
-  if (strncmp (p, "DC", 2))
+  if (!startswith (p, "DC"))
     return NULL;
   if (nested)
     {
@@ -4430,7 +4430,7 @@ static void
 write_guarded_var_name (const tree variable)
 {
   if (DECL_NAME (variable)
-      && strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
+      && startswith (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR"))
     /* The name of a guard variable for a reference temporary should refer
        to the reference, not the temporary.  */
     write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
@@ -4488,8 +4488,7 @@ decl_tls_wrapper_p (const tree fn)
   if (TREE_CODE (fn) != FUNCTION_DECL)
     return false;
   tree name = DECL_NAME (fn);
-  return strncmp (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX,
-		  strlen (TLS_WRAPPER_PREFIX)) == 0;
+  return startswith (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX);
 }
 
 /* Return an identifier for the name of a temporary variable used to
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 99eccf0c5e4..5e076ffa34a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18661,9 +18661,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	  decl_specs->int_n_idx = idx;
 	  /* Check if the alternate "__intN__" form has been used instead of
 	     "__intN".  */
-	  if (strncmp (IDENTIFIER_POINTER (token->u.value)
-			+ (IDENTIFIER_LENGTH (token->u.value) - 2),
-			"__", 2) == 0)
+	  if (startswith (IDENTIFIER_POINTER (token->u.value)
+			  + (IDENTIFIER_LENGTH (token->u.value) - 2), "__"))
 	    decl_specs->int_n_alt = true;
 	}
       type = int_n_trees [idx].signed_type;
@@ -22950,7 +22949,7 @@ cp_parser_tx_qualifier_opt (cp_parser *parser)
       tree name = token->u.value;
       const char *p = IDENTIFIER_POINTER (name);
       const int len = strlen ("transaction_safe");
-      if (!strncmp (p, "transaction_safe", len))
+      if (startswith (p, "transaction_safe"))
 	{
 	  p += len;
 	  if (*p == '\0'
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7bcbe6dc3ce..bf1ef09fe05 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6994,7 +6994,7 @@ bool
 template_parm_object_p (const_tree t)
 {
   return (TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t) && DECL_NAME (t)
-	  && !strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA", 4));
+	  && startswith (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA"));
 }
 
 /* Subroutine of convert_nontype_argument, to check whether EXPR, as an
@@ -28474,8 +28474,7 @@ dguide_name_p (tree name)
 {
   return (TREE_CODE (name) == IDENTIFIER_NODE
 	  && TREE_TYPE (name)
-	  && !strncmp (IDENTIFIER_POINTER (name), dguide_base,
-		       strlen (dguide_base)));
+	  && startswith (IDENTIFIER_POINTER (name), dguide_base));
 }
 
 /* True if FN is a deduction guide.  */
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 400bce0a141..859a8ce2a59 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -739,8 +739,7 @@ do_build_builtin_fn (built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
 
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index 5e71f3b24a1..9e74a0dbf1f 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -6881,7 +6881,7 @@ Expression *evaluateIfBuiltin(UnionExp *pue, InterState *istate, Loc loc,
         const char *id = fd->ident->toChars();
         size_t idlen = strlen(id);
         if (nargs == 2 && (idlen == 10 || idlen == 11) &&
-            !strncmp(id, "_aApply", 7))
+            startswith (id, "_aApply"))
         {
             // Functions from aApply.d and aApplyR.d in the runtime
             bool rvs = (idlen == 11);   // true if foreach_reverse
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index 83f4c18bee8..f112243cf5f 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -673,7 +673,7 @@ public:
                 cd == ClassDeclaration::object ||
                 cd == Type::typeinfoclass ||
                 cd == Module::moduleinfo ||
-                strncmp(cd->ident->toChars(), "TypeInfo_", 9) == 0)
+                startswith (cd->ident->toChars(), "TypeInfo_"))
             {
                 // Don't mangle parent
                 ad->parent = NULL;
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index 9397b1e8abd..e72273b2dbd 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -3212,7 +3212,7 @@ public:
         }
         else if (p->type->ty == Tident &&
                  strlen(((TypeIdentifier *)p->type)->ident->toChars()) > 3 &&
-                 strncmp(((TypeIdentifier *)p->type)->ident->toChars(), "__T", 3) == 0)
+                 startswith (((TypeIdentifier *)p->type)->ident->toChars(), "__T"))
         {
             // print parameter name, instead of undetermined type parameter
             buf->writestring(p->ident->toChars());
diff --git a/gcc/d/dmd/identifier.c b/gcc/d/dmd/identifier.c
index 197d288e532..dd2c58fd657 100644
--- a/gcc/d/dmd/identifier.c
+++ b/gcc/d/dmd/identifier.c
@@ -73,11 +73,11 @@ const char *Identifier::toHChars2()
     {   p = toChars();
         if (*p == '_')
         {
-            if (strncmp(p, "_staticCtor", 11) == 0)
+            if (startswith(p, "_staticCtor"))
                 p = "static this";
-            else if (strncmp(p, "_staticDtor", 11) == 0)
+            else if (startswith(p, "_staticDtor"))
                 p = "static ~this";
-            else if (strncmp(p, "__invariant", 11) == 0)
+            else if (startswith(p, "__invariant"))
                 p = "invariant";
         }
     }
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 7a15debcb48..728e89b331d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5474,7 +5474,7 @@ is_cxx (const_tree decl)
     {
       const_tree context = get_ultimate_context (decl);
       if (context && TRANSLATION_UNIT_LANGUAGE (context))
-	return strncmp (TRANSLATION_UNIT_LANGUAGE (context), "GNU C++", 7) == 0;
+	return startswith (TRANSLATION_UNIT_LANGUAGE (context), "GNU C++");
     }
   return is_cxx ();
 }
@@ -24732,8 +24732,8 @@ gen_compile_unit_die (const char *filename)
 	    common_lang = TRANSLATION_UNIT_LANGUAGE (t);
 	  else if (strcmp (common_lang, TRANSLATION_UNIT_LANGUAGE (t)) == 0)
 	    ;
-	  else if (strncmp (common_lang, "GNU C", 5) == 0
-		    && strncmp (TRANSLATION_UNIT_LANGUAGE (t), "GNU C", 5) == 0)
+	  else if (startswith (common_lang, "GNU C")
+		    && startswith (TRANSLATION_UNIT_LANGUAGE (t), "GNU C"))
 	    /* Mixing C and C++ is ok, use C++ in that case.  */
 	    common_lang = highest_c_language (common_lang,
 					      TRANSLATION_UNIT_LANGUAGE (t));
@@ -24750,7 +24750,7 @@ gen_compile_unit_die (const char *filename)
     }
 
   language = DW_LANG_C;
-  if (strncmp (language_string, "GNU C", 5) == 0
+  if (startswith (language_string, "GNU C")
       && ISDIGIT (language_string[5]))
     {
       language = DW_LANG_C89;
@@ -24766,7 +24766,7 @@ gen_compile_unit_die (const char *filename)
 	      language = DW_LANG_C11;
 	}
     }
-  else if (strncmp (language_string, "GNU C++", 7) == 0)
+  else if (startswith (language_string, "GNU C++"))
     {
       language = DW_LANG_C_plus_plus;
       if (dwarf_version >= 5 /* || !dwarf_strict */)
@@ -24788,7 +24788,7 @@ gen_compile_unit_die (const char *filename)
     {
       if (strcmp (language_string, "GNU Ada") == 0)
 	language = DW_LANG_Ada95;
-      else if (strncmp (language_string, "GNU Fortran", 11) == 0)
+      else if (startswith (language_string, "GNU Fortran"))
 	{
 	  language = DW_LANG_Fortran95;
 	  if (dwarf_version >= 5 /* || !dwarf_strict */)
@@ -24812,7 +24812,7 @@ gen_compile_unit_die (const char *filename)
 	}
     }
   /* Use a degraded Fortran setting in strict DWARF2 so is_fortran works.  */
-  else if (strncmp (language_string, "GNU Fortran", 11) == 0)
+  else if (startswith (language_string, "GNU Fortran"))
     language = DW_LANG_Fortran90;
   /* Likewise for Ada.  */
   else if (strcmp (language_string, "GNU Ada") == 0)
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 947e4f868a1..413c7a75e0c 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -2721,7 +2721,7 @@ variable_decl (int elem)
     }
 
   /* %FILL components may not have initializers.  */
-  if (gfc_str_startswith (name, "%FILL") && gfc_match_eos () != MATCH_YES)
+  if (startswith (name, "%FILL") && gfc_match_eos () != MATCH_YES)
     {
       gfc_error ("%qs entity cannot have an initializer at %C", "%FILL");
       m = MATCH_ERROR;
@@ -8221,7 +8221,7 @@ gfc_match_end (gfc_statement *st)
     {
     case COMP_ASSOCIATE:
     case COMP_BLOCK:
-      if (gfc_str_startswith (block_name, "block@"))
+      if (startswith (block_name, "block@"))
 	block_name = NULL;
       break;
 
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 7935aca23db..b8e67bcc03e 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3514,10 +3514,6 @@ bool gfc_is_compile_time_shape (gfc_array_spec *);
 
 bool gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *, mpz_t *);
 
-
-#define gfc_str_startswith(str, pref) \
-	(strncmp ((str), (pref), strlen (pref)) == 0)
-
 /* interface.c -- FIXME: some of these should be in symbol.c */
 void gfc_free_interface (gfc_interface *);
 bool gfc_compare_derived_types (gfc_symbol *, gfc_symbol *);
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 089453caa03..321d3256eba 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -5029,7 +5029,7 @@ load_omp_udrs (void)
       mio_pool_string (&name);
       gfc_clear_ts (&ts);
       mio_typespec (&ts);
-      if (gfc_str_startswith (name, "operator "))
+      if (startswith (name, "operator "))
 	{
 	  const char *p = name + sizeof ("operator ") - 1;
 	  if (strcmp (p, "+") == 0)
@@ -5477,8 +5477,8 @@ read_module (void)
 
 	  /* Exception: Always import vtabs & vtypes.  */
 	  if (p == NULL && name[0] == '_'
-	      && (gfc_str_startswith (name, "__vtab_")
-		  || gfc_str_startswith (name, "__vtype_")))
+	      && (startswith (name, "__vtab_")
+		  || startswith (name, "__vtype_")))
 	    p = name;
 
 	  /* Skip symtree nodes not in an ONLY clause, unless there
@@ -5563,8 +5563,8 @@ read_module (void)
 		sym->attr.use_rename = 1;
 
 	      if (name[0] != '_'
-		  || (!gfc_str_startswith (name, "__vtab_")
-		      && !gfc_str_startswith (name, "__vtype_")))
+		  || (!startswith (name, "__vtab_")
+		      && !startswith (name, "__vtype_")))
 		sym->attr.use_only = only_flag;
 
 	      /* Store the symtree pointing to this symbol.  */
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 3a0b98bf1ec..1723f689a57 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -615,7 +615,7 @@ gfc_handle_runtime_check_option (const char *arg)
 	      result = 1;
 	      break;
 	    }
-	  else if (optname[n] && pos > 3 && gfc_str_startswith (arg, "no-")
+	  else if (optname[n] && pos > 3 && startswith (arg, "no-")
 		   && strncmp (optname[n], arg+3, pos-3) == 0)
 	    {
 	      gfc_option.rtcheck &= ~optmask[n];
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index a6df885c80c..9fe8d1ee20c 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1786,21 +1786,21 @@ match_arg_list_function (gfc_actual_arglist *result)
       switch (name[0])
 	{
 	case 'l':
-	  if (gfc_str_startswith (name, "loc"))
+	  if (startswith (name, "loc"))
 	    {
 	      result->name = "%LOC";
 	      break;
 	    }
 	  /* FALLTHRU */
 	case 'r':
-	  if (gfc_str_startswith (name, "ref"))
+	  if (startswith (name, "ref"))
 	    {
 	      result->name = "%REF";
 	      break;
 	    }
 	  /* FALLTHRU */
 	case 'v':
-	  if (gfc_str_startswith (name, "val"))
+	  if (startswith (name, "val"))
 	    {
 	      result->name = "%VAL";
 	      break;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index cc9d85543ca..a1701887c8b 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1941,7 +1941,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
      Marking this as artificial means that OpenMP will treat this as
      predetermined shared.  */
 
-  bool def_init = gfc_str_startswith (sym->name, "__def_init");
+  bool def_init = startswith (sym->name, "__def_init");
 
   if (sym->attr.vtab || def_init)
     {
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 213f32b0a67..0295617a1ae 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6840,7 +6840,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
       /* When calling __copy for character expressions to unlimited
 	 polymorphic entities, the dst argument needs a string length.  */
       if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
-	  && gfc_str_startswith (sym->name, "__vtab_CHARACTER")
+	  && startswith (sym->name, "__vtab_CHARACTER")
 	  && arg->next && arg->next->expr
 	  && (arg->next->expr->ts.type == BT_DERIVED
 	      || arg->next->expr->ts.type == BT_CLASS)
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 5e53d1162fa..1369d2f76b9 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -10072,27 +10072,27 @@ gfc_conv_ieee_arithmetic_function (gfc_se * se, gfc_expr * expr)
 {
   const char *name = expr->value.function.name;
 
-  if (gfc_str_startswith (name, "_gfortran_ieee_is_nan"))
+  if (startswith (name, "_gfortran_ieee_is_nan"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISNAN, 1);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_finite"))
+  else if (startswith (name, "_gfortran_ieee_is_finite"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISFINITE, 1);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_unordered"))
+  else if (startswith (name, "_gfortran_ieee_unordered"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISUNORDERED, 2);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_normal"))
+  else if (startswith (name, "_gfortran_ieee_is_normal"))
     conv_intrinsic_ieee_is_normal (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_negative"))
+  else if (startswith (name, "_gfortran_ieee_is_negative"))
     conv_intrinsic_ieee_is_negative (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_copy_sign"))
+  else if (startswith (name, "_gfortran_ieee_copy_sign"))
     conv_intrinsic_ieee_copy_sign (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_scalb"))
+  else if (startswith (name, "_gfortran_ieee_scalb"))
     conv_intrinsic_ieee_scalb (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_next_after"))
+  else if (startswith (name, "_gfortran_ieee_next_after"))
     conv_intrinsic_ieee_next_after (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_rem"))
+  else if (startswith (name, "_gfortran_ieee_rem"))
     conv_intrinsic_ieee_rem (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_logb"))
+  else if (startswith (name, "_gfortran_ieee_logb"))
     conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_LOGB);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_rint"))
+  else if (startswith (name, "_gfortran_ieee_rint"))
     conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_RINT);
   else
     /* It is not among the functions we translate directly.  We return
diff --git a/gcc/gcc-ar.c b/gcc/gcc-ar.c
index e76d4525e0c..cbc7662e03d 100644
--- a/gcc/gcc-ar.c
+++ b/gcc/gcc-ar.c
@@ -140,7 +140,7 @@ main (int ac, char **av)
 
   /* Not using getopt for now.  */
   for (i = 0; i < ac; i++)
-      if (!strncmp (av[i], "-B", 2))
+      if (startswith (av[i], "-B"))
 	{
 	  const char *arg = av[i] + 2;
 	  const char *end;
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 7837553958b..0a17e86ccea 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1900,7 +1900,7 @@ init_spec (void)
        when given the proper command line arguments.  */
     while (*p)
       {
-	if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
+	if (in_sep && *p == '-' && startswith (p, "-lgcc"))
 	  {
 	    init_gcc_specs (&obstack,
 			    "-lgcc_s"
@@ -1923,7 +1923,7 @@ init_spec (void)
 	    p += 5;
 	    in_sep = 0;
 	  }
-	else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
+	else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
 	  {
 	    /* Ug.  We don't know shared library extensions.  Hope that
 	       systems that use this form don't do shared libraries.  */
@@ -2378,7 +2378,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 	  /* Skip '\n'.  */
 	  p++;
 
-	  if (!strncmp (p1, "%include", sizeof ("%include") - 1)
+	  if (startswith (p1, "%include")
 	      && (p1[sizeof "%include" - 1] == ' '
 		  || p1[sizeof "%include" - 1] == '\t'))
 	    {
@@ -2399,7 +2399,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 	      read_specs (new_filename ? new_filename : p1, false, user_p);
 	      continue;
 	    }
-	  else if (!strncmp (p1, "%include_noerr", sizeof "%include_noerr" - 1)
+	  else if (startswith (p1, "%include_noerr")
 		   && (p1[sizeof "%include_noerr" - 1] == ' '
 		       || p1[sizeof "%include_noerr" - 1] == '\t'))
 	    {
@@ -2423,7 +2423,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 		fnotice (stderr, "could not find specs file %s\n", p1);
 	      continue;
 	    }
-	  else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
+	  else if (startswith (p1, "%rename")
 		   && (p1[sizeof "%rename" - 1] == ' '
 		       || p1[sizeof "%rename" - 1] == '\t'))
 	    {
@@ -3496,7 +3496,7 @@ execute (void)
 		&& WEXITSTATUS (status) == ICE_EXIT_CODE
 		&& i == 0
 		&& (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
-		&& ! strncmp (p + 1, "cc1", 3))
+		&& startswith (p + 1, "cc1"))
 	      try_generate_repro (commands[0].argv);
 	    if (WEXITSTATUS (status) > greatest_status)
 	      greatest_status = WEXITSTATUS (status);
@@ -7324,7 +7324,7 @@ check_live_switch (int switchnum, int prefix_length)
       break;
 
     case 'W':  case 'f':  case 'm': case 'g':
-      if (! strncmp (name + 1, "no-", 3))
+      if (startswith (name + 1, "no-"))
 	{
 	  /* We have Xno-YYY, search for XYYY.  */
 	  for (i = switchnum + 1; i < n_switches; i++)
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index afea3602e50..e69d175a05a 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -4344,7 +4344,7 @@ write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
     write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
 		    known_true, -2, 0, 0);
 
-  if (strncmp (prefix, "return", 6))
+  if (!startswith (prefix, "return"))
     {
       write_indent (outf, indent + 2);
       fprintf (outf, "break;\n");
@@ -5377,14 +5377,12 @@ main (int argc, const char **argv)
       {
         FILE *outf;
 
-#define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
-	if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
+	if (startswith(attr->name, "*internal_dfa_insn_code"))
 	  outf = dfa_file;
-	else if (IS_ATTR_GROUP ("*insn_default_latency"))
+	else if (startswith (attr->name, "*insn_default_latency"))
 	  outf = latency_file;  
 	else
 	  outf = attr_file;
-#undef IS_ATTR_GROUP
 
 	if (! attr->is_special && ! attr->is_const)
 	  write_attr_get (outf, attr);
diff --git a/gcc/gencfn-macros.c b/gcc/gencfn-macros.c
index b620fe6aebc..fd9ae14fc04 100644
--- a/gcc/gencfn-macros.c
+++ b/gcc/gencfn-macros.c
@@ -208,7 +208,7 @@ main (int argc, char **argv)
   for (unsigned int i = 0; builtin_names[i]; ++i)
     {
       const char *name = builtin_names[i];
-      if (strncmp (name, "BUILT_IN_", 9) == 0)
+      if (startswith (name, "BUILT_IN_"))
 	{
 	  const char *root = name + 9;
 	  for (unsigned int j = 0; suffix_lists[j]; ++j)
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 98d4626f87e..b94e2f126ec 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -671,7 +671,7 @@ type_for_name (const char *s)
          extern GTY(()) gcc::some_type *some_ptr;
      where the autogenerated functions will refer to simply "some_type",
      where they can be resolved into their namespace.  */
-  if (strncmp (s, "gcc::", 5) == 0)
+  if (startswith (s, "gcc::"))
     s += 5;
 
   for (p = typedefs; p != NULL; p = p->next)
@@ -1102,7 +1102,7 @@ gen_rtx_next (void)
       int k;
 
       rtx_next_new[i] = -1;
-      if (strncmp (rtx_format[i], "uu", 2) == 0)
+      if (startswith (rtx_format[i], "uu"))
 	rtx_next_new[i] = 1;
       else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
 	rtx_next_new[i] = 1;
@@ -1828,7 +1828,7 @@ get_file_langdir (const input_file *inpf)
     return NULL;
 
   lang_index = get_prefix_langdir_index (srcdir_relative_path);
-  if (lang_index < 0 && strncmp (srcdir_relative_path, "c-family", 8) == 0)
+  if (lang_index < 0 && startswith (srcdir_relative_path, "c-family"))
     r = "c-family";
   else if (lang_index >= 0)
     r = lang_dir_names[lang_index];
@@ -4044,7 +4044,7 @@ write_local (outf_p output_header, type_p structures)
 	   || ((s)->gc_used == GC_MAYBE_POINTED_TO			\
 	       && s->u.s.line.file != NULL)				\
 	   || ((s)->gc_used == GC_USED					\
-	       && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))) \
+	       && !startswith (s->u.s.tag, "anonymous"))		\
 	   || (s->u.s.base_class && opts_have (s->u.s.opt, "tag")))))
 
 
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 8311f5d768a..332afc842b7 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -605,10 +605,10 @@ get_operator (const char *id, bool allow_null = false)
       for (unsigned int i = 0; id2[i]; ++i)
 	id2[i] = TOUPPER (id2[i]);
     }
-  else if (all_upper && strncmp (id, "IFN_", 4) == 0)
+  else if (all_upper && startswith (id, "IFN_"))
     /* Try CFN_ instead of IFN_.  */
     id2 = ACONCAT (("CFN_", id + 4, NULL));
-  else if (all_upper && strncmp (id, "BUILT_IN_", 9) == 0)
+  else if (all_upper && startswith (id, "BUILT_IN_"))
     /* Try prepending CFN_.  */
     id2 = ACONCAT (("CFN_", id, NULL));
   else
@@ -2391,7 +2391,7 @@ get_operand_type (id_base *op, unsigned pos,
   else if (*op == COND_EXPR
 	   && pos == 0)
     return "boolean_type_node";
-  else if (strncmp (op->id, "CFN_COND_", 9) == 0)
+  else if (startswith (op->id, "CFN_COND_"))
     {
       /* IFN_COND_* operands 1 and later by default have the same type
 	 as the result.  The type of operand 0 needs to be specified
@@ -2464,7 +2464,7 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
     }
   else if (*opr == COND_EXPR
 	   || *opr == VEC_COND_EXPR
-	   || strncmp (opr->id, "CFN_COND_", 9) == 0)
+	   || startswith (opr->id, "CFN_COND_"))
     {
       /* Conditions are of the same type as their first alternative.  */
       snprintf (optype, sizeof (optype), "TREE_TYPE (_o%d[1])", depth);
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 25af4375d9c..8e911cce2f5 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -841,7 +841,7 @@ validate_optab_operands (class data *d)
     return;
 
   /* Miscellaneous tests.  */
-  if (strncmp (d->name, "cstore", 6) == 0
+  if (startswith (d->name, "cstore")
       && d->name[strlen (d->name) - 1] == '4'
       && d->operand[0].mode == VOIDmode)
     {
diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc
index 3cc5ded3617..514c045a68f 100644
--- a/gcc/go/gofrontend/runtime.cc
+++ b/gcc/go/gofrontend/runtime.cc
@@ -463,7 +463,7 @@ Runtime::name_to_code(const std::string& name)
       // The names in the table have "runtime." prefix. We may be
       // called with a name without the prefix. Try matching
       // without the prefix as well.
-      if (strncmp(runtime_function_name, "runtime.", 8) == 0
+      if (startswith(runtime_function_name, "runtime.")
           && strcmp(runtime_function_name + 8, name.c_str()) == 0)
         code = static_cast<Runtime::Function>(i);
     }
diff --git a/gcc/incpath.c b/gcc/incpath.c
index 446d280321d..52dbb806b1b 100644
--- a/gcc/incpath.c
+++ b/gcc/incpath.c
@@ -330,7 +330,7 @@ add_sysroot_to_chain (const char *sysroot, int chain)
 	{
 	  if (p->name[0] == '=')
 	    p->name = concat (sysroot, p->name + 1, NULL);
-	  if (strncmp (p->name, "$SYSROOT", strlen ("$SYSROOT")) == 0)
+	  if (startswith (p->name, "$SYSROOT"))
 	    p->name = concat (sysroot, p->name + strlen ("$SYSROOT"), NULL);
 	}
     }
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 2354386f7b4..12c99888e6c 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -901,7 +901,7 @@ lhd_finalize_early_debug (void)
 bool
 lang_GNU_C (void)
 {
-  return (strncmp (lang_hooks.name, "GNU C", 5) == 0
+  return (startswith (lang_hooks.name, "GNU C")
 	  && (lang_hooks.name[5] == '\0' || ISDIGIT (lang_hooks.name[5])));
 }
 
@@ -910,7 +910,7 @@ lang_GNU_C (void)
 bool
 lang_GNU_CXX (void)
 {
-  return strncmp (lang_hooks.name, "GNU C++", 7) == 0;
+  return startswith (lang_hooks.name, "GNU C++");
 }
 
 /* Returns true if the current lang_hooks represents the GNU Fortran frontend.  */
@@ -918,7 +918,7 @@ lang_GNU_CXX (void)
 bool
 lang_GNU_Fortran (void)
 {
-  return strncmp (lang_hooks.name, "GNU Fortran", 11) == 0;
+  return startswith (lang_hooks.name, "GNU Fortran");
 }
 
 /* Returns true if the current lang_hooks represents the GNU Objective-C
@@ -927,5 +927,5 @@ lang_GNU_Fortran (void)
 bool
 lang_GNU_OBJC (void)
 {
-  return strncmp (lang_hooks.name, "GNU Objective-C", 15) == 0;
+  return startswith (lang_hooks.name, "GNU Objective-C");
 }
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 03a5922f8ea..efb6ee644f4 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -1437,8 +1437,7 @@ run_gcc (unsigned argc, char *argv[])
       int consumed;
       char *filename = argv[i];
 
-      if (strncmp (argv[i], "-foffload-objects=",
-		   sizeof ("-foffload-objects=") - 1) == 0)
+      if (startswith (argv[i], "-foffload-objects="))
 	{
 	  have_offload = true;
 	  offload_objects_file_name
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 1cbd586b8fb..796256d437e 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -10275,7 +10275,7 @@ objc_string_ref_type_p (tree strp)
   return (tmv
 	  && TREE_CODE (tmv) == IDENTIFIER_NODE
 	  && IDENTIFIER_POINTER (tmv)
-	  && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
+	  && startswith (IDENTIFIER_POINTER (tmv), "NSString"));
 }
 
 /* At present the behavior of this is undefined and it does nothing.  */
diff --git a/gcc/objc/objc-encoding.c b/gcc/objc/objc-encoding.c
index c4067b1d527..7ad920a2c35 100644
--- a/gcc/objc/objc-encoding.c
+++ b/gcc/objc/objc-encoding.c
@@ -733,7 +733,7 @@ encode_type (tree type, int curtype, int format)
 	  char *enc = (char *) obstack_base (&util_obstack) + curtype;
 
 	  /* Rewrite "in const" from "nr" to "rn".  */
-	  if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
+	  if (curtype >= 1 && startswith (enc - 1, "nr"))
 	    memcpy (enc - 1, "rn", 2);
 	}
     }
diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c
index af68c1c84a3..3cfcd0b1a57 100644
--- a/gcc/objc/objc-next-runtime-abi-02.c
+++ b/gcc/objc/objc-next-runtime-abi-02.c
@@ -2209,7 +2209,7 @@ has_load_impl (tree clsmeth)
     {
       tree id = METHOD_SEL_NAME (clsmeth);
       if (IDENTIFIER_LENGTH (id) == 4
-	  && strncmp (IDENTIFIER_POINTER (id), "load", 4) == 0)
+	  && startswith (IDENTIFIER_POINTER (id), "load"))
         return true;
       clsmeth = DECL_CHAIN (clsmeth);
     }
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index fa6de01722b..a1bb9d8d25d 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -968,7 +968,7 @@ omp_max_simt_vf (void)
   if (ENABLE_OFFLOADING)
     for (const char *c = getenv ("OFFLOAD_TARGET_NAMES"); c;)
       {
-	if (!strncmp (c, "nvptx", strlen ("nvptx")))
+	if (startswith (c, "nvptx"))
 	  return 32;
 	else if ((c = strchr (c, ':')))
 	  c++;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 7b122059c6e..e735af974ee 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3786,7 +3786,7 @@ omp_runtime_api_call (const_tree fndecl)
     return false;
 
   const char *name = IDENTIFIER_POINTER (declname);
-  if (strncmp (name, "omp_", 4) != 0)
+  if (!startswith (name, "omp_"))
     return false;
 
   static const char *omp_runtime_apis[] =
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 5e10edeb4cf..9d1914ff2ff 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -1805,7 +1805,7 @@ parse_options_from_collect_gcc_options (const char *collect_gcc_options,
 	      if (argv_storage[j] == '\0')
 		fatal_error (input_location,
 			     "malformed %<COLLECT_GCC_OPTIONS%>");
-	      else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
+	      else if (startswith (&argv_storage[j], "'\\''"))
 		{
 		  argv_storage[k++] = '\'';
 		  j += 4;
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index 2a1fb4bac9c..eaf380dd466 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -1082,7 +1082,7 @@ function_reader::read_rtx_operand_r (rtx x)
 	 "orig:%i", ORIGINAL_REGNO (rtx).
 	 Consume it, we don't set ORIGINAL_REGNO, since we can
 	 get that from the 2nd copy later.  */
-      if (strncmp (desc, "orig:", 5) == 0)
+      if (startswith (desc, "orig:"))
 	{
 	  expect_original_regno = true;
 	  desc_start += 5;
diff --git a/gcc/real.c b/gcc/real.c
index 09957a91b7c..555cf44c142 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -1972,17 +1972,17 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
   else if (*str == '+')
     str++;
 
-  if (!strncmp (str, "QNaN", 4))
+  if (startswith (str, "QNaN"))
     {
       get_canonical_qnan (r, sign);
       return 0;
     }
-  else if (!strncmp (str, "SNaN", 4))
+  else if (startswith (str, "SNaN"))
     {
       get_canonical_snan (r, sign);
       return 0;
     }
-  else if (!strncmp (str, "Inf", 3))
+  else if (startswith (str, "Inf"))
     {
       get_inf (r, sign);
       return 0;
diff --git a/gcc/selftest.c b/gcc/selftest.c
index 6e26ea553f2..8f1cde0cc19 100644
--- a/gcc/selftest.c
+++ b/gcc/selftest.c
@@ -150,8 +150,7 @@ assert_str_startswith (const location &loc,
 		    "ASSERT_STR_STARTSWITH (%s, %s) str=\"%s\" prefix=NULL",
 		    desc_str, desc_prefix, val_str);
 
-  const char *test = strstr (val_str, val_prefix);
-  if (test == val_str)
+  if (startswith (val_str, val_prefix))
     pass (loc, "ASSERT_STR_STARTSWITH");
   else
     fail_formatted
diff --git a/gcc/system.h b/gcc/system.h
index a3f5948aaee..51ccf753fd4 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1291,4 +1291,12 @@ void gcc_stablesort (void *, size_t, size_t,
 #define NULL nullptr
 #endif
 
+/* Return true if STR string starts with PREFIX.  */
+
+static inline bool
+startswith (const char *str, const char *prefix)
+{
+  return strncmp (str, prefix, strlen (prefix)) == 0;
+}
+
 #endif /* ! GCC_SYSTEM_H */
diff --git a/gcc/timevar.c b/gcc/timevar.c
index 5d4e1597f23..8fc122ba9fe 100644
--- a/gcc/timevar.c
+++ b/gcc/timevar.c
@@ -600,7 +600,7 @@ timer::validate_phases (FILE *fp) const
       if (!tv->used)
 	continue;
 
-      if (strncmp (tv->name, phase_prefix, sizeof phase_prefix - 1) == 0)
+      if (startswith (tv->name, phase_prefix))
 	{
 	  phase_user += tv->elapsed.user;
 	  phase_sys += tv->elapsed.sys;
diff --git a/gcc/tree.c b/gcc/tree.c
index e4e74ac8afc..3ed7ea349f6 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9725,7 +9725,7 @@ get_file_function_name (const char *type)
      We also assign sub_I and sub_D sufixes to constructors called from
      the global static constructors.  These are always local.  */
   else if (((type[0] == 'I' || type[0] == 'D') && targetm.have_ctors_dtors)
-	   || (strncmp (type, "sub_", 4) == 0
+	   || (startswith (type, "sub_")
 	       && (type[4] == 'I' || type[4] == 'D')))
     {
       const char *file = main_input_filename;
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 1089aef639f..7ee93436378 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -1783,7 +1783,7 @@ ubsan_use_new_style_p (location_t loc)
     return false;
 
   expanded_location xloc = expand_location (loc);
-  if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
+  if (xloc.file == NULL || startswith (xloc.file, "\1")
       || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
       || xloc.file[1] == '\xff')
     return false;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 8bb921faa26..bc2727c9303 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -792,7 +792,7 @@ default_function_rodata_section (tree decl, bool relocatable)
       /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo or
 	 .gnu.linkonce.d.rel.ro.local.foo if the jump table is relocatable.  */
       else if (DECL_COMDAT_GROUP (decl)
-	       && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
+	       && startswith (name, ".gnu.linkonce.t."))
 	{
 	  size_t len;
 	  char *rname;
@@ -817,7 +817,7 @@ default_function_rodata_section (tree decl, bool relocatable)
 	}
       /* For .text.foo we want to use .rodata.foo.  */
       else if (flag_function_sections && flag_data_sections
-	       && strncmp (name, ".text.", 6) == 0)
+	       && startswith (name, ".text."))
 	{
 	  size_t len = strlen (name) + 1;
 	  char *rname = (char *) alloca (len + strlen (sname) - 5);
@@ -2485,7 +2485,7 @@ incorporeal_function_p (tree decl)
       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
       /* Atomic or sync builtins which have survived this far will be
 	 resolved externally and therefore are not incorporeal.  */
-      if (strncmp (name, "__builtin_", 10) == 0)
+      if (startswith (name, "__builtin_"))
 	return true;
     }
   return false;
@@ -6713,22 +6713,22 @@ default_section_type_flags (tree decl, const char *name, int reloc)
     flags |= SECTION_TLS | SECTION_WRITE;
 
   if (strcmp (name, ".bss") == 0
-      || strncmp (name, ".bss.", 5) == 0
-      || strncmp (name, ".gnu.linkonce.b.", 16) == 0
+      || startswith (name, ".bss.")
+      || startswith (name, ".gnu.linkonce.b.")
       || strcmp (name, ".persistent.bss") == 0
       || strcmp (name, ".sbss") == 0
-      || strncmp (name, ".sbss.", 6) == 0
-      || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
+      || startswith (name, ".sbss.")
+      || startswith (name, ".gnu.linkonce.sb."))
     flags |= SECTION_BSS;
 
   if (strcmp (name, ".tdata") == 0
-      || strncmp (name, ".tdata.", 7) == 0
-      || strncmp (name, ".gnu.linkonce.td.", 17) == 0)
+      || startswith (name, ".tdata.")
+      || startswith (name, ".gnu.linkonce.td."))
     flags |= SECTION_TLS;
 
   if (strcmp (name, ".tbss") == 0
-      || strncmp (name, ".tbss.", 6) == 0
-      || strncmp (name, ".gnu.linkonce.tb.", 17) == 0)
+      || startswith (name, ".tbss.")
+      || startswith (name, ".gnu.linkonce.tb."))
     flags |= SECTION_TLS | SECTION_BSS;
 
   if (strcmp (name, ".noinit") == 0)


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [gcc(refs/users/marxin/heads/str_starts_with-v2)] Come up with startswith function.
@ 2021-03-26 11:36 Martin Liska
  0 siblings, 0 replies; 3+ messages in thread
From: Martin Liska @ 2021-03-26 11:36 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ad389e9de5b26b2e54e1ebdd7ab614134da12f70

commit ad389e9de5b26b2e54e1ebdd7ab614134da12f70
Author: Martin Liska <mliska@suse.cz>
Date:   Wed Mar 17 16:36:44 2021 +0100

    Come up with startswith function.
    
    gcc/ada/ChangeLog:
    
            * adadecode.c (has_prefix): Remove has_prefix and replace it
            with startswith.
            (__gnat_decode): Likewise.
            * gcc-interface/utils.c (def_builtin_1): Use startswith
            function instead of strncmp.
            * init.c (__gnat_install_handler): Likewise.
    
    gcc/analyzer/ChangeLog:
    
            * sm-file.cc (is_file_using_fn_p): Use startswith
            function instead of strncmp.
    
    gcc/ChangeLog:
    
            * builtins.c (is_builtin_name): Use startswith
            function instead of strncmp.
            * collect2.c (main): Likewise.
            (has_lto_section): Likewise.
            (scan_libraries): Likewise.
            * coverage.c (coverage_checksum_string): Likewise.
            (coverage_init): Likewise.
            * dwarf2out.c (is_cxx): Likewise.
            (gen_compile_unit_die): Likewise.
            * gcc-ar.c (main): Likewise.
            * gcc.c (init_spec): Likewise.
            (read_specs): Likewise.
            (execute): Likewise.
            (check_live_switch): Likewise.
            * genattrtab.c (write_attr_case): Likewise.
            (IS_ATTR_GROUP): Likewise.
            * gencfn-macros.c (main): Likewise.
            * gengtype.c (type_for_name): Likewise.
            (gen_rtx_next): Likewise.
            (get_file_langdir): Likewise.
            (write_local): Likewise.
            * genmatch.c (get_operator): Likewise.
            (get_operand_type): Likewise.
            (expr::gen_transform): Likewise.
            * genoutput.c (validate_optab_operands): Likewise.
            * incpath.c (add_sysroot_to_chain): Likewise.
            * langhooks.c (lang_GNU_C): Likewise.
            (lang_GNU_CXX): Likewise.
            (lang_GNU_Fortran): Likewise.
            (lang_GNU_OBJC): Likewise.
            * lto-wrapper.c (run_gcc): Likewise.
            * omp-general.c (omp_max_simt_vf): Likewise.
            * omp-low.c (omp_runtime_api_call): Likewise.
            * opts-common.c (parse_options_from_collect_gcc_options): Likewise.
            * read-rtl-function.c (function_reader::read_rtx_operand_r): Likewise.
            * real.c (real_from_string): Likewise.
            * selftest.c (assert_str_startswith): Likewise.
            * timevar.c (timer::validate_phases): Likewise.
            * tree.c (get_file_function_name): Likewise.
            * ubsan.c (ubsan_use_new_style_p): Likewise.
            * varasm.c (default_function_rodata_section): Likewise.
            (incorporeal_function_p): Likewise.
            (default_section_type_flags): Likewise.
            * system.h (startswith): Define startswith.
    
    gcc/c-family/ChangeLog:
    
            * c-ada-spec.c (print_destructor): Use startswith
            function instead of strncmp.
            (dump_ada_declaration): Likewise.
            * c-common.c (disable_builtin_function): Likewise.
            (def_builtin_1): Likewise.
            * c-format.c (check_tokens): Likewise.
            (check_plain): Likewise.
            (convert_format_name_to_system_name): Likewise.
    
    gcc/c/ChangeLog:
    
            * c-aux-info.c (affix_data_type): Use startswith
            function instead of strncmp.
            * c-typeck.c (build_function_call_vec): Likewise.
            * gimple-parser.c (c_parser_gimple_parse_bb_spec): Likewise.
    
    gcc/cp/ChangeLog:
    
            * decl.c (duplicate_decls): Use startswith
            function instead of strncmp.
            (cxx_builtin_function): Likewise.
            (omp_declare_variant_finalize_one): Likewise.
            (grokfndecl): Likewise.
            * error.c (dump_decl_name): Likewise.
            * mangle.c (find_decomp_unqualified_name): Likewise.
            (write_guarded_var_name): Likewise.
            (decl_tls_wrapper_p): Likewise.
            * parser.c (cp_parser_simple_type_specifier): Likewise.
            (cp_parser_tx_qualifier_opt): Likewise.
            * pt.c (template_parm_object_p): Likewise.
            (dguide_name_p): Likewise.
    
    gcc/d/ChangeLog:
    
            * d-builtins.cc (do_build_builtin_fn): Use startswith
            function instead of strncmp.
            * dmd/dinterpret.c (evaluateIfBuiltin): Likewise.
            * dmd/dmangle.c: Likewise.
            * dmd/hdrgen.c: Likewise.
            * dmd/identifier.c (Identifier::toHChars2): Likewise.
    
    gcc/fortran/ChangeLog:
    
            * decl.c (variable_decl): Use startswith
            function instead of strncmp.
            (gfc_match_end): Likewise.
            * gfortran.h (gfc_str_startswith): Likewise.
            * module.c (load_omp_udrs): Likewise.
            (read_module): Likewise.
            * options.c (gfc_handle_runtime_check_option): Likewise.
            * primary.c (match_arg_list_function): Likewise.
            * trans-decl.c (gfc_get_symbol_decl): Likewise.
            * trans-expr.c (gfc_conv_procedure_call): Likewise.
            * trans-intrinsic.c (gfc_conv_ieee_arithmetic_function): Likewise.
    
    gcc/go/ChangeLog:
    
            * gofrontend/runtime.cc (Runtime::name_to_code): Use startswith
            function instead of strncmp.
    
    gcc/objc/ChangeLog:
    
            * objc-act.c (objc_string_ref_type_p): Use startswith
            function instead of strncmp.
            * objc-encoding.c (encode_type): Likewise.
            * objc-next-runtime-abi-02.c (has_load_impl): Likewise.

Diff:
---
 gcc/ada/adadecode.c                 | 14 +++--------
 gcc/ada/gcc-interface/utils.c       |  3 +--
 gcc/ada/init.c                      |  8 +++----
 gcc/analyzer/sm-file.cc             |  5 ++--
 gcc/builtins.c                      | 10 +++-----
 gcc/c-family/c-ada-spec.c           |  8 +++----
 gcc/c-family/c-common.c             |  5 ++--
 gcc/c-family/c-format.c             | 20 ++++++++--------
 gcc/c/c-aux-info.c                  |  4 ++--
 gcc/c/c-typeck.c                    |  4 ++--
 gcc/c/gimple-parser.c               |  2 +-
 gcc/collect2.c                      | 48 +++++++++++++++++--------------------
 gcc/coverage.c                      |  7 +++---
 gcc/cp/decl.c                       | 15 ++++++------
 gcc/cp/error.c                      |  2 +-
 gcc/cp/mangle.c                     | 11 ++++-----
 gcc/cp/parser.c                     |  7 +++---
 gcc/cp/pt.c                         |  5 ++--
 gcc/d/d-builtins.cc                 |  3 +--
 gcc/d/dmd/dinterpret.c              |  2 +-
 gcc/d/dmd/dmangle.c                 |  2 +-
 gcc/d/dmd/hdrgen.c                  |  2 +-
 gcc/d/dmd/identifier.c              |  6 ++---
 gcc/dwarf2out.c                     | 14 +++++------
 gcc/fortran/decl.c                  |  4 ++--
 gcc/fortran/gfortran.h              |  4 ----
 gcc/fortran/module.c                | 10 ++++----
 gcc/fortran/options.c               |  2 +-
 gcc/fortran/primary.c               |  6 ++---
 gcc/fortran/trans-decl.c            |  2 +-
 gcc/fortran/trans-expr.c            |  2 +-
 gcc/fortran/trans-intrinsic.c       | 22 ++++++++---------
 gcc/gcc-ar.c                        |  2 +-
 gcc/gcc.c                           | 14 +++++------
 gcc/genattrtab.c                    |  8 +++----
 gcc/gencfn-macros.c                 |  2 +-
 gcc/gengtype.c                      |  8 +++----
 gcc/genmatch.c                      |  8 +++----
 gcc/genoutput.c                     |  2 +-
 gcc/go/gofrontend/runtime.cc        |  2 +-
 gcc/incpath.c                       |  2 +-
 gcc/langhooks.c                     |  8 +++----
 gcc/lto-wrapper.c                   |  3 +--
 gcc/objc/objc-act.c                 |  2 +-
 gcc/objc/objc-encoding.c            |  2 +-
 gcc/objc/objc-next-runtime-abi-02.c |  2 +-
 gcc/omp-general.c                   |  2 +-
 gcc/omp-low.c                       |  2 +-
 gcc/opts-common.c                   |  2 +-
 gcc/read-rtl-function.c             |  2 +-
 gcc/real.c                          |  6 ++---
 gcc/selftest.c                      |  3 +--
 gcc/system.h                        |  8 +++++++
 gcc/timevar.c                       |  2 +-
 gcc/tree.c                          |  2 +-
 gcc/ubsan.c                         |  2 +-
 gcc/varasm.c                        | 22 ++++++++---------
 57 files changed, 176 insertions(+), 201 deletions(-)

diff --git a/gcc/ada/adadecode.c b/gcc/ada/adadecode.c
index 43a378f9058..1154e628311 100644
--- a/gcc/ada/adadecode.c
+++ b/gcc/ada/adadecode.c
@@ -29,8 +29,9 @@
  *                                                                          *
  ****************************************************************************/
 
+#include "config.h"
+#include "system.h"
 #include "runtime.h"
-#include <string.h>
 #include <stdio.h>
 #include <ctype.h>
 
@@ -47,7 +48,6 @@
 #include "adadecode.h"
 
 static void add_verbose (const char *, char *);
-static int has_prefix (const char *, const char *);
 static int has_suffix (const char *, const char *);
 
 /* This is a safe version of strcpy that can be used with overlapped
@@ -68,14 +68,6 @@ static void add_verbose (const char *text, char *ada_name)
   verbose_info = 1;
 }
 
-/* Returns 1 if NAME starts with PREFIX.  */
-
-static int
-has_prefix (const char *name, const char *prefix)
-{
-  return strncmp (name, prefix, strlen (prefix)) == 0;
-}
-
 /* Returns 1 if NAME ends with SUFFIX.  */
 
 static int
@@ -167,7 +159,7 @@ __gnat_decode (const char *coded_name, char *ada_name, int verbose)
     }
 
   /* Check for library level subprogram.  */
-  else if (has_prefix (coded_name, "_ada_"))
+  else if (startswith (coded_name, "_ada_"))
     {
       strcpy (ada_name, coded_name + 5);
       lib_subprog = 1;
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 952f032072b..2d5ca4ba456 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -7016,8 +7016,7 @@ def_builtin_1 (enum built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
   decl = add_builtin_function (name, fntype, fncode, fnclass,
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 3ceb1a31b02..24eb67bbf0d 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -2111,10 +2111,10 @@ __gnat_install_handler (void)
       prefix for vxsim when running on Linux and Windows.  */
   {
     char *model = sysModel ();
-    if ((strncmp (model, "Linux", 5) == 0)
-        || (strncmp (model, "Windows", 7) == 0)
-        || (strncmp (model, "SIMLINUX", 8) == 0) /* vx7 */
-        || (strncmp (model, "SIMNT", 5) == 0)) /* ditto */
+    if ((startswith(model, "Linux")
+        || startswith (model, "Windows")
+        || startswith (model, "SIMLINUX") /* vx7 */
+	|| startswith (model, "SIMNT")) /* ditto */
       __gnat_set_is_vxsim (TRUE);
   }
 #endif
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 7a81c8ff632..1e19ddbec7a 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -312,9 +312,8 @@ is_file_using_fn_p (tree fndecl)
 
   /* Also support variants of these names prefixed with "_IO_".  */
   const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
-  if (strncmp (name, "_IO_", 4) == 0)
-    if (fs.contains_name_p (name + 4))
-      return true;
+  if (startswith (name, "_IO_") && fs.contains_name_p (name + 4))
+    return true;
 
   return false;
 }
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 196dda3fa5e..af71caf2f08 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -740,13 +740,9 @@ pointer_query::flush_cache ()
 static bool
 is_builtin_name (const char *name)
 {
-  if (strncmp (name, "__builtin_", 10) == 0)
-    return true;
-  if (strncmp (name, "__sync_", 7) == 0)
-    return true;
-  if (strncmp (name, "__atomic_", 9) == 0)
-    return true;
-  return false;
+  return (startswith (name, "__builtin_")
+	  || startswith (name, "__sync_")
+	  || startswith (name, "__atomic_"));
 }
 
 /* Return true if NODE should be considered for inline expansion regardless
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index dd8e8bbd90a..c126e822d77 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -2693,7 +2693,7 @@ print_destructor (pretty_printer *buffer, tree t, tree type)
   tree decl_name = DECL_NAME (TYPE_NAME (type));
 
   pp_string (buffer, "Delete_");
-  if (strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del", 8) == 0)
+  if (startswith (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del"))
     pp_string (buffer, "And_Free_");
   pp_ada_tree_identifier (buffer, decl_name, t, false);
 }
@@ -2977,9 +2977,9 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
 	    return 0;
 
 	  /* Only consider complete constructors and deleting destructors.  */
-	  if (strncmp (IDENTIFIER_POINTER (decl_name), "__ct_comp", 9) != 0
-	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_comp", 9) != 0
-	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_del", 8) != 0)
+	  if (!startswith (IDENTIFIER_POINTER (decl_name), "__ct_comp")
+	      && !startswith (IDENTIFIER_POINTER (decl_name), "__dt_comp")
+	      && !startswith (IDENTIFIER_POINTER (decl_name), "__dt_del"))
 	    return 0;
 	}
 
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d227686a030..7bd799d1825 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4670,7 +4670,7 @@ static bool builtin_function_disabled_p (const char *);
 void
 disable_builtin_function (const char *name)
 {
-  if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
+  if (startswith (name, "__builtin_"))
     error ("cannot disable built-in function %qs", name);
   else
     {
@@ -4718,8 +4718,7 @@ def_builtin_1 (enum built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
   decl = add_builtin_function (name, fntype, fncode, fnclass,
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 0a63cacb0d9..bda3b18fcd0 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -3097,7 +3097,7 @@ check_tokens (const token_t *tokens, unsigned ntoks,
       /* Allow this ugly warning for the time being.  */
       if (toklen == 2
 	  && format_chars - orig_format_chars > 6
-	  && !strncmp (format_chars - 7, " count >= width of ", 19))
+	  && startswith (format_chars - 7, " count >= width of "))
 	return format_chars + 10;
 
       /* The token is a type if it ends in an alphabetic character.  */
@@ -3127,7 +3127,7 @@ check_tokens (const token_t *tokens, unsigned ntoks,
   /* Diagnose unquoted __attribute__.  Consider any parenthesized
      argument to the attribute to avoid redundant warnings for
      the double parentheses that might follow.  */
-  if (!strncmp (format_chars, "__attribute", sizeof "__attribute" - 1))
+  if (startswith (format_chars, "__attribute"))
     {
       unsigned nchars = sizeof "__attribute" - 1;
       while ('_' == format_chars[nchars])
@@ -3178,9 +3178,9 @@ check_tokens (const token_t *tokens, unsigned ntoks,
   /* Diagnose unquoted built-ins.  */
   if (format_chars[0] == '_'
       && format_chars[1] == '_'
-      && (!strncmp (format_chars + 2, "atomic", sizeof "atomic" - 1)
-	  || !strncmp (format_chars + 2, "builtin", sizeof "builtin" - 1)
-	  || !strncmp (format_chars + 2, "sync", sizeof "sync" - 1)))
+      && (startswith (format_chars + 2, "atomic")
+	  || startswith (format_chars + 2, "builtin")
+	  || startswith (format_chars + 2, "sync")))
     {
       format_warning_substr (format_string_loc, format_string_cst,
 			     fmtchrpos, fmtchrpos + wlen, opt,
@@ -3267,7 +3267,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
   if (*format_chars == '%')
     {
       /* Diagnose %<%s%> and suggest using %qs instead.  */
-      if (!strncmp (format_chars, "%<%s%>", 6))
+      if (startswith (format_chars, "%<%s%>"))
 	format_warning_substr (format_string_loc, format_string_cst,
 			       fmtchrpos, fmtchrpos + 6, opt,
 			       "quoted %qs directive in format; "
@@ -3593,7 +3593,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 
       if (nchars == 1)
 	{
-	  if (!strncmp (format_chars, "\"%s\"", 4))
+	  if (startswith (format_chars, "\"%s\""))
 	    {
 	      if (format_warning_substr (format_string_loc, format_string_cst,
 					 fmtchrpos, fmtchrpos + 4, opt,
@@ -3621,7 +3621,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 	      && format_chars[0] == '(')
 	    ;   /* Text beginning in an open parenthesis.  */
 	  else if (nchars == 3
-	      && !strncmp (format_chars, "...", 3)
+	      && startswith (format_chars, "...")
 	      && format_chars[3])
 	    ;   /* Text beginning in an ellipsis.  */
 	  else
@@ -3663,7 +3663,7 @@ check_plain (location_t format_string_loc, tree format_string_cst,
 		   a period at the end of a capitalized sentence.  */
 	  else if (nchars == 3
 		   && format_chars - orig_format_chars > 0
-		   && !strncmp (format_chars, "...", 3))
+		   && startswith (format_chars, "..."))
 	    ;   /* Text ending in the ellipsis.  */
 	  else
 	    format_warning_substr (format_string_loc, format_string_cst,
@@ -5104,7 +5104,7 @@ convert_format_name_to_system_name (const char *attr_name)
   int i;
 
   if (attr_name == NULL || *attr_name == 0
-      || strncmp (attr_name, "gcc_", 4) == 0)
+      || startswith (attr_name, "gcc_"))
     return attr_name;
 #ifdef TARGET_OVERRIDES_FORMAT_INIT
   TARGET_OVERRIDES_FORMAT_INIT ();
diff --git a/gcc/c/c-aux-info.c b/gcc/c/c-aux-info.c
index bae5757ad13..81860cb48cb 100644
--- a/gcc/c/c-aux-info.c
+++ b/gcc/c/c-aux-info.c
@@ -67,12 +67,12 @@ affix_data_type (const char *param)
 
   for (;;)
     {
-      if (!strncmp (p, "volatile ", 9))
+      if (startswith (p, "volatile "))
 	{
 	  p += 9;
 	  continue;
 	}
-      if (!strncmp (p, "const ", 6))
+      if (startswith (p, "const "))
 	{
 	  p += 6;
 	  continue;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 21eab00d4b3..f70b1036cc9 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3107,7 +3107,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
 	orig_fundecl = fundecl;
       /* Atomic functions have type checking/casting already done.  They are 
 	 often rewritten and don't match the original parameter list.  */
-      if (name && !strncmp (IDENTIFIER_POINTER (name), "__atomic_", 9))
+      if (name && startswith (IDENTIFIER_POINTER (name), "__atomic_"))
         origtypes = NULL;
     }
   if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
@@ -3193,7 +3193,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
 					    nargs, argarray, &arg_loc);
 
   if (name != NULL_TREE
-      && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
+      && startswith (IDENTIFIER_POINTER (name), "__builtin_"))
     {
       if (require_constant_value)
 	result
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 58b161b7c76..3a6e72ef002 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -131,7 +131,7 @@ static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *);
 static bool
 c_parser_gimple_parse_bb_spec (tree val, int *index)
 {
-  if (strncmp (IDENTIFIER_POINTER (val), "__BB", 4) != 0)
+  if (!startswith (IDENTIFIER_POINTER (val), "__BB"))
     return false;
   for (const char *p = IDENTIFIER_POINTER (val) + 4; *p; ++p)
     if (!ISDIGIT (*p))
diff --git a/gcc/collect2.c b/gcc/collect2.c
index bd371430ab7..0ddb1693b67 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -956,7 +956,7 @@ main (int argc, char **argv)
       {
 	if (! strcmp (argv[i], "-debug"))
 	  debug = true;
-	else if (!strncmp (argv[i], "-fno-lto", 8))
+	else if (startswith (argv[i], "-fno-lto"))
 	  lto_mode = LTO_MODE_NONE;
         else if (! strcmp (argv[i], "-plugin"))
 	  {
@@ -970,7 +970,7 @@ main (int argc, char **argv)
 	  selected_linker = USE_GOLD_LD;
 	else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
 	  selected_linker = USE_LLD_LD;
-	else if (strncmp (argv[i], "-o", 2) == 0)
+	else if (startswith (argv[i], "-o"))
 	  {
 	    /* Parse the output filename if it's given so that we can make
 	       meaningful temp filenames.  */
@@ -984,19 +984,19 @@ main (int argc, char **argv)
 	/* These flags are position independent, although their order
 	   is important - subsequent flags override earlier ones. */
 	else if (strcmp (argv[i], "-b64") == 0)
-	    aix64_flag = 1;
+	  aix64_flag = 1;
 	/* -bexport:filename always needs the :filename */
-	else if (strncmp (argv[i], "-bE:", 4) == 0
-	      || strncmp (argv[i], "-bexport:", 9) == 0)
-	    export_flag = 1;
+	else if (startswith (argv[i], "-bE:")
+		 || startswith (argv[i], "-bexport:"))
+	  export_flag = 1;
 	else if (strcmp (argv[i], "-brtl") == 0
 	      || strcmp (argv[i], "-bsvr4") == 0
 	      || strcmp (argv[i], "-G") == 0)
-	    aixrtl_flag = 1;
+	  aixrtl_flag = 1;
 	else if (strcmp (argv[i], "-bnortl") == 0)
-	    aixrtl_flag = 0;
+	  aixrtl_flag = 0;
 	else if (strcmp (argv[i], "-blazy") == 0)
-	    aixlazy_flag = 1;
+	  aixlazy_flag = 1;
 #endif
       }
 
@@ -1016,11 +1016,11 @@ main (int argc, char **argv)
 	const char *q = extract_string (&p);
 	if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
 	  num_c_args++;
-	if (strncmp (q, "-flto-partition=none", 20) == 0)
+	if (startswith (q, "-flto-partition=none"))
 	  no_partition = true;
-	else if (strncmp (q, "-fno-lto", 8) == 0)
+	else if (startswith (q, "-fno-lto"))
 	  lto_mode = LTO_MODE_NONE;
-	else if (strncmp (q, "-save-temps", 11) == 0)
+	else if (startswith (q, "-save-temps"))
 	  /* FIXME: Honour =obj.  */
 	  save_temps = true;
 	else if (strcmp (q, "-dumpdir") == 0)
@@ -1254,7 +1254,7 @@ main (int argc, char **argv)
 	(void) extract_string (&p);
 #ifdef COLLECT_EXPORT_LIST
       /* Detect any invocation with -fvisibility.  */
-      if (strncmp (q, "-fvisibility", 12) == 0)
+      if (startswith (q, "-fvisibility"))
 	visibility_flag = 1;
 #endif
     }
@@ -1303,7 +1303,7 @@ main (int argc, char **argv)
 	      break;
 
             case 'f':
-	      if (strncmp (arg, "-flto", 5) == 0)
+	      if (startswith (arg, "-flto"))
 		{
 #ifdef ENABLE_LTO
 		  /* Do not pass LTO flag to the linker. */
@@ -1315,13 +1315,13 @@ main (int argc, char **argv)
 #endif
 		}
 	      else if (!use_collect_ld
-		       && strncmp (arg, "-fuse-ld=", 9) == 0)
+		       && startswith (arg, "-fuse-ld="))
 		{
 		  /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */
 		  ld1--;
 		  ld2--;
 		}
-	      else if (strncmp (arg, "-fno-lto", 8) == 0)
+	      else if (startswith (arg, "-fno-lto"))
 		{
 		  /* Do not pass -fno-lto to the linker. */
 		  ld1--;
@@ -1462,7 +1462,7 @@ main (int argc, char **argv)
 		  ld2--;
 #endif
 		}
-	      else if (strncmp (arg, "--demangle", 10) == 0)
+	      else if (startswith (arg, "--demangle"))
 		{
 #ifndef HAVE_LD_DEMANGLE
 		  no_demangle = 0;
@@ -1479,7 +1479,7 @@ main (int argc, char **argv)
 		  ld2--;
 #endif
 		}
-	      else if (strncmp (arg, "--sysroot=", 10) == 0)
+	      else if (startswith (arg, "--sysroot="))
 		target_system_root = arg + 10;
 	      else if (strcmp (arg, "--version") == 0)
 		verbose = true;
@@ -2307,13 +2307,9 @@ has_lto_section (void *data, const char *name ATTRIBUTE_UNUSED,
 {
   int *found = (int *) data;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
-	       sizeof (LTO_SECTION_NAME_PREFIX) - 1) != 0)
-    {
-      if (strncmp (name, OFFLOAD_SECTION_NAME_PREFIX,
-	           sizeof (OFFLOAD_SECTION_NAME_PREFIX) - 1) != 0)
-        return 1;
-    }
+  if (!startswith (name, LTO_SECTION_NAME_PREFIX)
+      && !startswith (name, OFFLOAD_SECTION_NAME_PREFIX))
+    return 1;
 
   *found = 1;
 
@@ -2619,7 +2615,7 @@ scan_libraries (const char *prog_name)
 	continue;
 
       name = p;
-      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
+      if (startswith (name, "not found"))
 	fatal_error (input_location, "dynamic dependency %s not found", buf);
 
       /* Find the end of the symbol name.  */
diff --git a/gcc/coverage.c b/gcc/coverage.c
index dc9ea6f3ee1..5a344cdfc17 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -488,9 +488,9 @@ coverage_checksum_string (unsigned chksum, const char *string)
   for (i = 0; string[i]; i++)
     {
       int offset = 0;
-      if (!strncmp (string + i, "_GLOBAL__N_", 11))
+      if (startswith (string + i, "_GLOBAL__N_"))
       offset = 11;
-      if (!strncmp (string + i, "_GLOBAL__", 9))
+      if (startswith (string + i, "_GLOBAL__"))
       offset = 9;
 
       /* C++ namespaces do have scheme:
@@ -1256,8 +1256,7 @@ coverage_init (const char *filename)
 	  filename = concat (getpwd (), separator, filename, NULL);
 	  if (profile_prefix_path)
 	    {
-	      if (!strncmp (filename, profile_prefix_path,
-			    strlen (profile_prefix_path)))
+	      if (startswith (filename, profile_prefix_path))
 		{
 		  filename += strlen (profile_prefix_path);
 		  while (*filename == *separator)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3483b0c0398..ba8ea72c277 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1609,8 +1609,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
 
 		  if (name[0] == '_'
 		      && name[1] == '_'
-		      && (strncmp (name + 2, "builtin_",
-				   strlen ("builtin_")) == 0
+		      && (startswith (name + 2, "builtin_")
 			  || (len = strlen (name)) <= strlen ("___chk")
 			  || memcmp (name + len - strlen ("_chk"),
 				     "_chk", strlen ("_chk") + 1) != 0))
@@ -4838,7 +4837,7 @@ cxx_builtin_function (tree decl)
     /* In the user's namespace, it must be declared before use.  */
     hiding = true;
   else if (IDENTIFIER_LENGTH (id) > strlen ("___chk")
-	   && 0 != strncmp (name + 2, "builtin_", strlen ("builtin_"))
+	   && !startswith (name + 2, "builtin_")
 	   && 0 == memcmp (name + IDENTIFIER_LENGTH (id) - strlen ("_chk"),
 			   "_chk", strlen ("_chk") + 1))
     /* Treat __*_chk fortification functions as anticipated as well,
@@ -7567,9 +7566,9 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
 	  return true;
 	}
       if (fndecl_built_in_p (variant)
-	  && (strncmp (varname, "__builtin_", strlen ("__builtin_")) == 0
-	      || strncmp (varname, "__sync_", strlen ("__sync_")) == 0
-	      || strncmp (varname, "__atomic_", strlen ("__atomic_")) == 0))
+	  && (startswith (varname, "__builtin_")
+	      || startswith (varname, "__sync_")
+	      || startswith (varname, "__atomic_")))
 	{
 	  error_at (varid_loc, "variant %qD is a built-in", variant);
 	  return true;
@@ -9825,8 +9824,8 @@ grokfndecl (tree ctype,
 	  || (IDENTIFIER_LENGTH (declarator) > 10
 	      && IDENTIFIER_POINTER (declarator)[0] == '_'
 	      && IDENTIFIER_POINTER (declarator)[1] == '_'
-	      && strncmp (IDENTIFIER_POINTER (declarator)+2,
-			  "builtin_", 8) == 0)
+	      && startswith (IDENTIFIER_POINTER (declarator) + 2,
+			     "builtin_"))
 	  || (targetcm.cxx_implicit_extern_c
 	      && (targetcm.cxx_implicit_extern_c
 		  (IDENTIFIER_POINTER (declarator))))))
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ff4ae6f4b23..a4e9b2a6ad9 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1138,7 +1138,7 @@ dump_decl_name (cxx_pretty_printer *pp, tree t, int flags)
     }
 
   const char *str = IDENTIFIER_POINTER (t);
-  if (!strncmp (str, "_ZGR", 4))
+  if (startswith (str, "_ZGR"))
     {
       pp_cxx_ws_string (pp, "<temporary>");
       return;
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 0a9e5aa79a0..529cd87cae8 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1308,10 +1308,10 @@ find_decomp_unqualified_name (tree decl, size_t *len)
   const char *p = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
   const char *end = p + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
   bool nested = false;
-  if (strncmp (p, "_Z", 2))
+  if (!startswith (p, "_Z"))
     return NULL;
   p += 2;
-  if (!strncmp (p, "St", 2))
+  if (startswith (p, "St"))
     p += 2;
   else if (*p == 'N')
     {
@@ -1327,7 +1327,7 @@ find_decomp_unqualified_name (tree decl, size_t *len)
 	    break;
 	}
     }
-  if (strncmp (p, "DC", 2))
+  if (!startswith (p, "DC"))
     return NULL;
   if (nested)
     {
@@ -4419,7 +4419,7 @@ static void
 write_guarded_var_name (const tree variable)
 {
   if (DECL_NAME (variable)
-      && strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
+      && startswith (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR"))
     /* The name of a guard variable for a reference temporary should refer
        to the reference, not the temporary.  */
     write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
@@ -4477,8 +4477,7 @@ decl_tls_wrapper_p (const tree fn)
   if (TREE_CODE (fn) != FUNCTION_DECL)
     return false;
   tree name = DECL_NAME (fn);
-  return strncmp (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX,
-		  strlen (TLS_WRAPPER_PREFIX)) == 0;
+  return startswith (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX);
 }
 
 /* Return an identifier for the name of a temporary variable used to
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d0477c42afe..aa01034cff2 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18631,9 +18631,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	  decl_specs->int_n_idx = idx;
 	  /* Check if the alternate "__intN__" form has been used instead of
 	     "__intN".  */
-	  if (strncmp (IDENTIFIER_POINTER (token->u.value)
-			+ (IDENTIFIER_LENGTH (token->u.value) - 2),
-			"__", 2) == 0)
+	  if (startswith (IDENTIFIER_POINTER (token->u.value)
+			  + (IDENTIFIER_LENGTH (token->u.value) - 2), "__"))
 	    decl_specs->int_n_alt = true;
 	}
       type = int_n_trees [idx].signed_type;
@@ -22920,7 +22919,7 @@ cp_parser_tx_qualifier_opt (cp_parser *parser)
       tree name = token->u.value;
       const char *p = IDENTIFIER_POINTER (name);
       const int len = strlen ("transaction_safe");
-      if (!strncmp (p, "transaction_safe", len))
+      if (startswith (p, "transaction_safe"))
 	{
 	  p += len;
 	  if (*p == '\0'
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2736bb43299..d8664ff7e8f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6967,7 +6967,7 @@ bool
 template_parm_object_p (const_tree t)
 {
   return (TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t) && DECL_NAME (t)
-	  && !strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA", 4));
+	  && startswith (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA"));
 }
 
 /* Subroutine of convert_nontype_argument, to check whether EXPR, as an
@@ -28425,8 +28425,7 @@ dguide_name_p (tree name)
 {
   return (TREE_CODE (name) == IDENTIFIER_NODE
 	  && TREE_TYPE (name)
-	  && !strncmp (IDENTIFIER_POINTER (name), dguide_base,
-		       strlen (dguide_base)));
+	  && startswith (IDENTIFIER_POINTER (name), dguide_base));
 }
 
 /* True if FN is a deduction guide.  */
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index c45edc2fa3f..d675f0e3ce0 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -756,8 +756,7 @@ do_build_builtin_fn (built_in_function fncode,
     return;
 
   gcc_assert ((!both_p && !fallback_p)
-	      || !strncmp (name, "__builtin_",
-			   strlen ("__builtin_")));
+	      || startswith (name, "__builtin_"));
 
   libname = name + strlen ("__builtin_");
 
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index 5e71f3b24a1..9e74a0dbf1f 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -6881,7 +6881,7 @@ Expression *evaluateIfBuiltin(UnionExp *pue, InterState *istate, Loc loc,
         const char *id = fd->ident->toChars();
         size_t idlen = strlen(id);
         if (nargs == 2 && (idlen == 10 || idlen == 11) &&
-            !strncmp(id, "_aApply", 7))
+            startswith (id, "_aApply"))
         {
             // Functions from aApply.d and aApplyR.d in the runtime
             bool rvs = (idlen == 11);   // true if foreach_reverse
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index 303ae617874..5a73b3e3a65 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -666,7 +666,7 @@ public:
                 cd == ClassDeclaration::object ||
                 cd == Type::typeinfoclass ||
                 cd == Module::moduleinfo ||
-                strncmp(cd->ident->toChars(), "TypeInfo_", 9) == 0)
+                startswith (cd->ident->toChars(), "TypeInfo_"))
             {
                 // Don't mangle parent
                 ad->parent = NULL;
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index a11c9c353d9..4959b480fe5 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -3189,7 +3189,7 @@ public:
         }
         else if (p->type->ty == Tident &&
                  strlen(((TypeIdentifier *)p->type)->ident->toChars()) > 3 &&
-                 strncmp(((TypeIdentifier *)p->type)->ident->toChars(), "__T", 3) == 0)
+                 startswith (((TypeIdentifier *)p->type)->ident->toChars(), "__T"))
         {
             // print parameter name, instead of undetermined type parameter
             buf->writestring(p->ident->toChars());
diff --git a/gcc/d/dmd/identifier.c b/gcc/d/dmd/identifier.c
index 197d288e532..dd2c58fd657 100644
--- a/gcc/d/dmd/identifier.c
+++ b/gcc/d/dmd/identifier.c
@@ -73,11 +73,11 @@ const char *Identifier::toHChars2()
     {   p = toChars();
         if (*p == '_')
         {
-            if (strncmp(p, "_staticCtor", 11) == 0)
+            if (startswith(p, "_staticCtor"))
                 p = "static this";
-            else if (strncmp(p, "_staticDtor", 11) == 0)
+            else if (startswith(p, "_staticDtor"))
                 p = "static ~this";
-            else if (strncmp(p, "__invariant", 11) == 0)
+            else if (startswith(p, "__invariant"))
                 p = "invariant";
         }
     }
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 395170a47f7..d1b2f723367 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5464,7 +5464,7 @@ is_cxx (const_tree decl)
     {
       const_tree context = get_ultimate_context (decl);
       if (context && TRANSLATION_UNIT_LANGUAGE (context))
-	return strncmp (TRANSLATION_UNIT_LANGUAGE (context), "GNU C++", 7) == 0;
+	return startswith (TRANSLATION_UNIT_LANGUAGE (context), "GNU C++");
     }
   return is_cxx ();
 }
@@ -24582,8 +24582,8 @@ gen_compile_unit_die (const char *filename)
 	    common_lang = TRANSLATION_UNIT_LANGUAGE (t);
 	  else if (strcmp (common_lang, TRANSLATION_UNIT_LANGUAGE (t)) == 0)
 	    ;
-	  else if (strncmp (common_lang, "GNU C", 5) == 0
-		    && strncmp (TRANSLATION_UNIT_LANGUAGE (t), "GNU C", 5) == 0)
+	  else if (startswith (common_lang, "GNU C")
+		    && startswith (TRANSLATION_UNIT_LANGUAGE (t), "GNU C"))
 	    /* Mixing C and C++ is ok, use C++ in that case.  */
 	    common_lang = highest_c_language (common_lang,
 					      TRANSLATION_UNIT_LANGUAGE (t));
@@ -24600,7 +24600,7 @@ gen_compile_unit_die (const char *filename)
     }
 
   language = DW_LANG_C;
-  if (strncmp (language_string, "GNU C", 5) == 0
+  if (startswith (language_string, "GNU C")
       && ISDIGIT (language_string[5]))
     {
       language = DW_LANG_C89;
@@ -24616,7 +24616,7 @@ gen_compile_unit_die (const char *filename)
 	      language = DW_LANG_C11;
 	}
     }
-  else if (strncmp (language_string, "GNU C++", 7) == 0)
+  else if (startswith (language_string, "GNU C++"))
     {
       language = DW_LANG_C_plus_plus;
       if (dwarf_version >= 5 /* || !dwarf_strict */)
@@ -24638,7 +24638,7 @@ gen_compile_unit_die (const char *filename)
     {
       if (strcmp (language_string, "GNU Ada") == 0)
 	language = DW_LANG_Ada95;
-      else if (strncmp (language_string, "GNU Fortran", 11) == 0)
+      else if (startswith (language_string, "GNU Fortran"))
 	{
 	  language = DW_LANG_Fortran95;
 	  if (dwarf_version >= 5 /* || !dwarf_strict */)
@@ -24662,7 +24662,7 @@ gen_compile_unit_die (const char *filename)
 	}
     }
   /* Use a degraded Fortran setting in strict DWARF2 so is_fortran works.  */
-  else if (strncmp (language_string, "GNU Fortran", 11) == 0)
+  else if (startswith (language_string, "GNU Fortran"))
     language = DW_LANG_Fortran90;
   /* Likewise for Ada.  */
   else if (strcmp (language_string, "GNU Ada") == 0)
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 947e4f868a1..413c7a75e0c 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -2721,7 +2721,7 @@ variable_decl (int elem)
     }
 
   /* %FILL components may not have initializers.  */
-  if (gfc_str_startswith (name, "%FILL") && gfc_match_eos () != MATCH_YES)
+  if (startswith (name, "%FILL") && gfc_match_eos () != MATCH_YES)
     {
       gfc_error ("%qs entity cannot have an initializer at %C", "%FILL");
       m = MATCH_ERROR;
@@ -8221,7 +8221,7 @@ gfc_match_end (gfc_statement *st)
     {
     case COMP_ASSOCIATE:
     case COMP_BLOCK:
-      if (gfc_str_startswith (block_name, "block@"))
+      if (startswith (block_name, "block@"))
 	block_name = NULL;
       break;
 
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 7935aca23db..b8e67bcc03e 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3514,10 +3514,6 @@ bool gfc_is_compile_time_shape (gfc_array_spec *);
 
 bool gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *, mpz_t *);
 
-
-#define gfc_str_startswith(str, pref) \
-	(strncmp ((str), (pref), strlen (pref)) == 0)
-
 /* interface.c -- FIXME: some of these should be in symbol.c */
 void gfc_free_interface (gfc_interface *);
 bool gfc_compare_derived_types (gfc_symbol *, gfc_symbol *);
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 4db0a3ac76d..a55855548b4 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -5029,7 +5029,7 @@ load_omp_udrs (void)
       mio_pool_string (&name);
       gfc_clear_ts (&ts);
       mio_typespec (&ts);
-      if (gfc_str_startswith (name, "operator "))
+      if (startswith (name, "operator "))
 	{
 	  const char *p = name + sizeof ("operator ") - 1;
 	  if (strcmp (p, "+") == 0)
@@ -5477,8 +5477,8 @@ read_module (void)
 
 	  /* Exception: Always import vtabs & vtypes.  */
 	  if (p == NULL && name[0] == '_'
-	      && (gfc_str_startswith (name, "__vtab_")
-		  || gfc_str_startswith (name, "__vtype_")))
+	      && (startswith (name, "__vtab_")
+		  || startswith (name, "__vtype_")))
 	    p = name;
 
 	  /* Skip symtree nodes not in an ONLY clause, unless there
@@ -5563,8 +5563,8 @@ read_module (void)
 		sym->attr.use_rename = 1;
 
 	      if (name[0] != '_'
-		  || (!gfc_str_startswith (name, "__vtab_")
-		      && !gfc_str_startswith (name, "__vtype_")))
+		  || (!startswith (name, "__vtab_")
+		      && !startswith (name, "__vtype_")))
 		sym->attr.use_only = only_flag;
 
 	      /* Store the symtree pointing to this symbol.  */
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 3a0b98bf1ec..1723f689a57 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -615,7 +615,7 @@ gfc_handle_runtime_check_option (const char *arg)
 	      result = 1;
 	      break;
 	    }
-	  else if (optname[n] && pos > 3 && gfc_str_startswith (arg, "no-")
+	  else if (optname[n] && pos > 3 && startswith (arg, "no-")
 		   && strncmp (optname[n], arg+3, pos-3) == 0)
 	    {
 	      gfc_option.rtcheck &= ~optmask[n];
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index a6df885c80c..9fe8d1ee20c 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1786,21 +1786,21 @@ match_arg_list_function (gfc_actual_arglist *result)
       switch (name[0])
 	{
 	case 'l':
-	  if (gfc_str_startswith (name, "loc"))
+	  if (startswith (name, "loc"))
 	    {
 	      result->name = "%LOC";
 	      break;
 	    }
 	  /* FALLTHRU */
 	case 'r':
-	  if (gfc_str_startswith (name, "ref"))
+	  if (startswith (name, "ref"))
 	    {
 	      result->name = "%REF";
 	      break;
 	    }
 	  /* FALLTHRU */
 	case 'v':
-	  if (gfc_str_startswith (name, "val"))
+	  if (startswith (name, "val"))
 	    {
 	      result->name = "%VAL";
 	      break;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 34a0d49bae7..48b987f08fc 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1940,7 +1940,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
      Marking this as artificial means that OpenMP will treat this as
      predetermined shared.  */
 
-  bool def_init = gfc_str_startswith (sym->name, "__def_init");
+  bool def_init = startswith (sym->name, "__def_init");
 
   if (sym->attr.vtab || def_init)
     {
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index bffe0808dff..82698b411dd 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6791,7 +6791,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
       /* When calling __copy for character expressions to unlimited
 	 polymorphic entities, the dst argument needs a string length.  */
       if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
-	  && gfc_str_startswith (sym->name, "__vtab_CHARACTER")
+	  && startswith (sym->name, "__vtab_CHARACTER")
 	  && arg->next && arg->next->expr
 	  && (arg->next->expr->ts.type == BT_DERIVED
 	      || arg->next->expr->ts.type == BT_CLASS)
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 5e53d1162fa..1369d2f76b9 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -10072,27 +10072,27 @@ gfc_conv_ieee_arithmetic_function (gfc_se * se, gfc_expr * expr)
 {
   const char *name = expr->value.function.name;
 
-  if (gfc_str_startswith (name, "_gfortran_ieee_is_nan"))
+  if (startswith (name, "_gfortran_ieee_is_nan"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISNAN, 1);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_finite"))
+  else if (startswith (name, "_gfortran_ieee_is_finite"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISFINITE, 1);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_unordered"))
+  else if (startswith (name, "_gfortran_ieee_unordered"))
     conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISUNORDERED, 2);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_normal"))
+  else if (startswith (name, "_gfortran_ieee_is_normal"))
     conv_intrinsic_ieee_is_normal (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_is_negative"))
+  else if (startswith (name, "_gfortran_ieee_is_negative"))
     conv_intrinsic_ieee_is_negative (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_copy_sign"))
+  else if (startswith (name, "_gfortran_ieee_copy_sign"))
     conv_intrinsic_ieee_copy_sign (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_scalb"))
+  else if (startswith (name, "_gfortran_ieee_scalb"))
     conv_intrinsic_ieee_scalb (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_next_after"))
+  else if (startswith (name, "_gfortran_ieee_next_after"))
     conv_intrinsic_ieee_next_after (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_rem"))
+  else if (startswith (name, "_gfortran_ieee_rem"))
     conv_intrinsic_ieee_rem (se, expr);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_logb"))
+  else if (startswith (name, "_gfortran_ieee_logb"))
     conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_LOGB);
-  else if (gfc_str_startswith (name, "_gfortran_ieee_rint"))
+  else if (startswith (name, "_gfortran_ieee_rint"))
     conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_RINT);
   else
     /* It is not among the functions we translate directly.  We return
diff --git a/gcc/gcc-ar.c b/gcc/gcc-ar.c
index e76d4525e0c..cbc7662e03d 100644
--- a/gcc/gcc-ar.c
+++ b/gcc/gcc-ar.c
@@ -140,7 +140,7 @@ main (int ac, char **av)
 
   /* Not using getopt for now.  */
   for (i = 0; i < ac; i++)
-      if (!strncmp (av[i], "-B", 2))
+      if (startswith (av[i], "-B"))
 	{
 	  const char *arg = av[i] + 2;
 	  const char *end;
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 7837553958b..0a17e86ccea 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1900,7 +1900,7 @@ init_spec (void)
        when given the proper command line arguments.  */
     while (*p)
       {
-	if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
+	if (in_sep && *p == '-' && startswith (p, "-lgcc"))
 	  {
 	    init_gcc_specs (&obstack,
 			    "-lgcc_s"
@@ -1923,7 +1923,7 @@ init_spec (void)
 	    p += 5;
 	    in_sep = 0;
 	  }
-	else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
+	else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
 	  {
 	    /* Ug.  We don't know shared library extensions.  Hope that
 	       systems that use this form don't do shared libraries.  */
@@ -2378,7 +2378,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 	  /* Skip '\n'.  */
 	  p++;
 
-	  if (!strncmp (p1, "%include", sizeof ("%include") - 1)
+	  if (startswith (p1, "%include")
 	      && (p1[sizeof "%include" - 1] == ' '
 		  || p1[sizeof "%include" - 1] == '\t'))
 	    {
@@ -2399,7 +2399,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 	      read_specs (new_filename ? new_filename : p1, false, user_p);
 	      continue;
 	    }
-	  else if (!strncmp (p1, "%include_noerr", sizeof "%include_noerr" - 1)
+	  else if (startswith (p1, "%include_noerr")
 		   && (p1[sizeof "%include_noerr" - 1] == ' '
 		       || p1[sizeof "%include_noerr" - 1] == '\t'))
 	    {
@@ -2423,7 +2423,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
 		fnotice (stderr, "could not find specs file %s\n", p1);
 	      continue;
 	    }
-	  else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
+	  else if (startswith (p1, "%rename")
 		   && (p1[sizeof "%rename" - 1] == ' '
 		       || p1[sizeof "%rename" - 1] == '\t'))
 	    {
@@ -3496,7 +3496,7 @@ execute (void)
 		&& WEXITSTATUS (status) == ICE_EXIT_CODE
 		&& i == 0
 		&& (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
-		&& ! strncmp (p + 1, "cc1", 3))
+		&& startswith (p + 1, "cc1"))
 	      try_generate_repro (commands[0].argv);
 	    if (WEXITSTATUS (status) > greatest_status)
 	      greatest_status = WEXITSTATUS (status);
@@ -7324,7 +7324,7 @@ check_live_switch (int switchnum, int prefix_length)
       break;
 
     case 'W':  case 'f':  case 'm': case 'g':
-      if (! strncmp (name + 1, "no-", 3))
+      if (startswith (name + 1, "no-"))
 	{
 	  /* We have Xno-YYY, search for XYYY.  */
 	  for (i = switchnum + 1; i < n_switches; i++)
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index afea3602e50..e69d175a05a 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -4344,7 +4344,7 @@ write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
     write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
 		    known_true, -2, 0, 0);
 
-  if (strncmp (prefix, "return", 6))
+  if (!startswith (prefix, "return"))
     {
       write_indent (outf, indent + 2);
       fprintf (outf, "break;\n");
@@ -5377,14 +5377,12 @@ main (int argc, const char **argv)
       {
         FILE *outf;
 
-#define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
-	if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
+	if (startswith(attr->name, "*internal_dfa_insn_code"))
 	  outf = dfa_file;
-	else if (IS_ATTR_GROUP ("*insn_default_latency"))
+	else if (startswith (attr->name, "*insn_default_latency"))
 	  outf = latency_file;  
 	else
 	  outf = attr_file;
-#undef IS_ATTR_GROUP
 
 	if (! attr->is_special && ! attr->is_const)
 	  write_attr_get (outf, attr);
diff --git a/gcc/gencfn-macros.c b/gcc/gencfn-macros.c
index b620fe6aebc..fd9ae14fc04 100644
--- a/gcc/gencfn-macros.c
+++ b/gcc/gencfn-macros.c
@@ -208,7 +208,7 @@ main (int argc, char **argv)
   for (unsigned int i = 0; builtin_names[i]; ++i)
     {
       const char *name = builtin_names[i];
-      if (strncmp (name, "BUILT_IN_", 9) == 0)
+      if (startswith (name, "BUILT_IN_"))
 	{
 	  const char *root = name + 9;
 	  for (unsigned int j = 0; suffix_lists[j]; ++j)
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 5f50242e857..7122ff763e3 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -671,7 +671,7 @@ type_for_name (const char *s)
          extern GTY(()) gcc::some_type *some_ptr;
      where the autogenerated functions will refer to simply "some_type",
      where they can be resolved into their namespace.  */
-  if (strncmp (s, "gcc::", 5) == 0)
+  if (startswith (s, "gcc::"))
     s += 5;
 
   for (p = typedefs; p != NULL; p = p->next)
@@ -1102,7 +1102,7 @@ gen_rtx_next (void)
       int k;
 
       rtx_next_new[i] = -1;
-      if (strncmp (rtx_format[i], "uu", 2) == 0)
+      if (startswith (rtx_format[i], "uu"))
 	rtx_next_new[i] = 1;
       else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
 	rtx_next_new[i] = 1;
@@ -1828,7 +1828,7 @@ get_file_langdir (const input_file *inpf)
     return NULL;
 
   lang_index = get_prefix_langdir_index (srcdir_relative_path);
-  if (lang_index < 0 && strncmp (srcdir_relative_path, "c-family", 8) == 0)
+  if (lang_index < 0 && startswith (srcdir_relative_path, "c-family"))
     r = "c-family";
   else if (lang_index >= 0)
     r = lang_dir_names[lang_index];
@@ -4044,7 +4044,7 @@ write_local (outf_p output_header, type_p structures)
 	   || ((s)->gc_used == GC_MAYBE_POINTED_TO			\
 	       && s->u.s.line.file != NULL)				\
 	   || ((s)->gc_used == GC_USED					\
-	       && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))) \
+	       && !startswith (s->u.s.tag, "anonymous"))		\
 	   || (s->u.s.base_class && opts_have (s->u.s.opt, "tag")))))
 
 
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 8311f5d768a..332afc842b7 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -605,10 +605,10 @@ get_operator (const char *id, bool allow_null = false)
       for (unsigned int i = 0; id2[i]; ++i)
 	id2[i] = TOUPPER (id2[i]);
     }
-  else if (all_upper && strncmp (id, "IFN_", 4) == 0)
+  else if (all_upper && startswith (id, "IFN_"))
     /* Try CFN_ instead of IFN_.  */
     id2 = ACONCAT (("CFN_", id + 4, NULL));
-  else if (all_upper && strncmp (id, "BUILT_IN_", 9) == 0)
+  else if (all_upper && startswith (id, "BUILT_IN_"))
     /* Try prepending CFN_.  */
     id2 = ACONCAT (("CFN_", id, NULL));
   else
@@ -2391,7 +2391,7 @@ get_operand_type (id_base *op, unsigned pos,
   else if (*op == COND_EXPR
 	   && pos == 0)
     return "boolean_type_node";
-  else if (strncmp (op->id, "CFN_COND_", 9) == 0)
+  else if (startswith (op->id, "CFN_COND_"))
     {
       /* IFN_COND_* operands 1 and later by default have the same type
 	 as the result.  The type of operand 0 needs to be specified
@@ -2464,7 +2464,7 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
     }
   else if (*opr == COND_EXPR
 	   || *opr == VEC_COND_EXPR
-	   || strncmp (opr->id, "CFN_COND_", 9) == 0)
+	   || startswith (opr->id, "CFN_COND_"))
     {
       /* Conditions are of the same type as their first alternative.  */
       snprintf (optype, sizeof (optype), "TREE_TYPE (_o%d[1])", depth);
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 25af4375d9c..8e911cce2f5 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -841,7 +841,7 @@ validate_optab_operands (class data *d)
     return;
 
   /* Miscellaneous tests.  */
-  if (strncmp (d->name, "cstore", 6) == 0
+  if (startswith (d->name, "cstore")
       && d->name[strlen (d->name) - 1] == '4'
       && d->operand[0].mode == VOIDmode)
     {
diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc
index 3cc5ded3617..514c045a68f 100644
--- a/gcc/go/gofrontend/runtime.cc
+++ b/gcc/go/gofrontend/runtime.cc
@@ -463,7 +463,7 @@ Runtime::name_to_code(const std::string& name)
       // The names in the table have "runtime." prefix. We may be
       // called with a name without the prefix. Try matching
       // without the prefix as well.
-      if (strncmp(runtime_function_name, "runtime.", 8) == 0
+      if (startswith(runtime_function_name, "runtime.")
           && strcmp(runtime_function_name + 8, name.c_str()) == 0)
         code = static_cast<Runtime::Function>(i);
     }
diff --git a/gcc/incpath.c b/gcc/incpath.c
index 446d280321d..52dbb806b1b 100644
--- a/gcc/incpath.c
+++ b/gcc/incpath.c
@@ -330,7 +330,7 @@ add_sysroot_to_chain (const char *sysroot, int chain)
 	{
 	  if (p->name[0] == '=')
 	    p->name = concat (sysroot, p->name + 1, NULL);
-	  if (strncmp (p->name, "$SYSROOT", strlen ("$SYSROOT")) == 0)
+	  if (startswith (p->name, "$SYSROOT"))
 	    p->name = concat (sysroot, p->name + strlen ("$SYSROOT"), NULL);
 	}
     }
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 2354386f7b4..12c99888e6c 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -901,7 +901,7 @@ lhd_finalize_early_debug (void)
 bool
 lang_GNU_C (void)
 {
-  return (strncmp (lang_hooks.name, "GNU C", 5) == 0
+  return (startswith (lang_hooks.name, "GNU C")
 	  && (lang_hooks.name[5] == '\0' || ISDIGIT (lang_hooks.name[5])));
 }
 
@@ -910,7 +910,7 @@ lang_GNU_C (void)
 bool
 lang_GNU_CXX (void)
 {
-  return strncmp (lang_hooks.name, "GNU C++", 7) == 0;
+  return startswith (lang_hooks.name, "GNU C++");
 }
 
 /* Returns true if the current lang_hooks represents the GNU Fortran frontend.  */
@@ -918,7 +918,7 @@ lang_GNU_CXX (void)
 bool
 lang_GNU_Fortran (void)
 {
-  return strncmp (lang_hooks.name, "GNU Fortran", 11) == 0;
+  return startswith (lang_hooks.name, "GNU Fortran");
 }
 
 /* Returns true if the current lang_hooks represents the GNU Objective-C
@@ -927,5 +927,5 @@ lang_GNU_Fortran (void)
 bool
 lang_GNU_OBJC (void)
 {
-  return strncmp (lang_hooks.name, "GNU Objective-C", 15) == 0;
+  return startswith (lang_hooks.name, "GNU Objective-C");
 }
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 03a5922f8ea..efb6ee644f4 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -1437,8 +1437,7 @@ run_gcc (unsigned argc, char *argv[])
       int consumed;
       char *filename = argv[i];
 
-      if (strncmp (argv[i], "-foffload-objects=",
-		   sizeof ("-foffload-objects=") - 1) == 0)
+      if (startswith (argv[i], "-foffload-objects="))
 	{
 	  have_offload = true;
 	  offload_objects_file_name
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 1cbd586b8fb..796256d437e 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -10275,7 +10275,7 @@ objc_string_ref_type_p (tree strp)
   return (tmv
 	  && TREE_CODE (tmv) == IDENTIFIER_NODE
 	  && IDENTIFIER_POINTER (tmv)
-	  && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
+	  && startswith (IDENTIFIER_POINTER (tmv), "NSString"));
 }
 
 /* At present the behavior of this is undefined and it does nothing.  */
diff --git a/gcc/objc/objc-encoding.c b/gcc/objc/objc-encoding.c
index c4067b1d527..7ad920a2c35 100644
--- a/gcc/objc/objc-encoding.c
+++ b/gcc/objc/objc-encoding.c
@@ -733,7 +733,7 @@ encode_type (tree type, int curtype, int format)
 	  char *enc = (char *) obstack_base (&util_obstack) + curtype;
 
 	  /* Rewrite "in const" from "nr" to "rn".  */
-	  if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
+	  if (curtype >= 1 && startswith (enc - 1, "nr"))
 	    memcpy (enc - 1, "rn", 2);
 	}
     }
diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c
index af68c1c84a3..3cfcd0b1a57 100644
--- a/gcc/objc/objc-next-runtime-abi-02.c
+++ b/gcc/objc/objc-next-runtime-abi-02.c
@@ -2209,7 +2209,7 @@ has_load_impl (tree clsmeth)
     {
       tree id = METHOD_SEL_NAME (clsmeth);
       if (IDENTIFIER_LENGTH (id) == 4
-	  && strncmp (IDENTIFIER_POINTER (id), "load", 4) == 0)
+	  && startswith (IDENTIFIER_POINTER (id), "load"))
         return true;
       clsmeth = DECL_CHAIN (clsmeth);
     }
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index fa6de01722b..a1bb9d8d25d 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -968,7 +968,7 @@ omp_max_simt_vf (void)
   if (ENABLE_OFFLOADING)
     for (const char *c = getenv ("OFFLOAD_TARGET_NAMES"); c;)
       {
-	if (!strncmp (c, "nvptx", strlen ("nvptx")))
+	if (startswith (c, "nvptx"))
 	  return 32;
 	else if ((c = strchr (c, ':')))
 	  c++;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 7b122059c6e..e735af974ee 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3786,7 +3786,7 @@ omp_runtime_api_call (const_tree fndecl)
     return false;
 
   const char *name = IDENTIFIER_POINTER (declname);
-  if (strncmp (name, "omp_", 4) != 0)
+  if (!startswith (name, "omp_"))
     return false;
 
   static const char *omp_runtime_apis[] =
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 5e10edeb4cf..9d1914ff2ff 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -1805,7 +1805,7 @@ parse_options_from_collect_gcc_options (const char *collect_gcc_options,
 	      if (argv_storage[j] == '\0')
 		fatal_error (input_location,
 			     "malformed %<COLLECT_GCC_OPTIONS%>");
-	      else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
+	      else if (startswith (&argv_storage[j], "'\\''"))
 		{
 		  argv_storage[k++] = '\'';
 		  j += 4;
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index 2a1fb4bac9c..eaf380dd466 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -1082,7 +1082,7 @@ function_reader::read_rtx_operand_r (rtx x)
 	 "orig:%i", ORIGINAL_REGNO (rtx).
 	 Consume it, we don't set ORIGINAL_REGNO, since we can
 	 get that from the 2nd copy later.  */
-      if (strncmp (desc, "orig:", 5) == 0)
+      if (startswith (desc, "orig:"))
 	{
 	  expect_original_regno = true;
 	  desc_start += 5;
diff --git a/gcc/real.c b/gcc/real.c
index 09957a91b7c..555cf44c142 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -1972,17 +1972,17 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
   else if (*str == '+')
     str++;
 
-  if (!strncmp (str, "QNaN", 4))
+  if (startswith (str, "QNaN"))
     {
       get_canonical_qnan (r, sign);
       return 0;
     }
-  else if (!strncmp (str, "SNaN", 4))
+  else if (startswith (str, "SNaN"))
     {
       get_canonical_snan (r, sign);
       return 0;
     }
-  else if (!strncmp (str, "Inf", 3))
+  else if (startswith (str, "Inf"))
     {
       get_inf (r, sign);
       return 0;
diff --git a/gcc/selftest.c b/gcc/selftest.c
index 6e26ea553f2..8f1cde0cc19 100644
--- a/gcc/selftest.c
+++ b/gcc/selftest.c
@@ -150,8 +150,7 @@ assert_str_startswith (const location &loc,
 		    "ASSERT_STR_STARTSWITH (%s, %s) str=\"%s\" prefix=NULL",
 		    desc_str, desc_prefix, val_str);
 
-  const char *test = strstr (val_str, val_prefix);
-  if (test == val_str)
+  if (startswith (val_str, val_prefix))
     pass (loc, "ASSERT_STR_STARTSWITH");
   else
     fail_formatted
diff --git a/gcc/system.h b/gcc/system.h
index a3f5948aaee..51ccf753fd4 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1291,4 +1291,12 @@ void gcc_stablesort (void *, size_t, size_t,
 #define NULL nullptr
 #endif
 
+/* Return true if STR string starts with PREFIX.  */
+
+static inline bool
+startswith (const char *str, const char *prefix)
+{
+  return strncmp (str, prefix, strlen (prefix)) == 0;
+}
+
 #endif /* ! GCC_SYSTEM_H */
diff --git a/gcc/timevar.c b/gcc/timevar.c
index 5d4e1597f23..8fc122ba9fe 100644
--- a/gcc/timevar.c
+++ b/gcc/timevar.c
@@ -600,7 +600,7 @@ timer::validate_phases (FILE *fp) const
       if (!tv->used)
 	continue;
 
-      if (strncmp (tv->name, phase_prefix, sizeof phase_prefix - 1) == 0)
+      if (startswith (tv->name, phase_prefix))
 	{
 	  phase_user += tv->elapsed.user;
 	  phase_sys += tv->elapsed.sys;
diff --git a/gcc/tree.c b/gcc/tree.c
index 7c44c226a33..0763e3337f6 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9725,7 +9725,7 @@ get_file_function_name (const char *type)
      We also assign sub_I and sub_D sufixes to constructors called from
      the global static constructors.  These are always local.  */
   else if (((type[0] == 'I' || type[0] == 'D') && targetm.have_ctors_dtors)
-	   || (strncmp (type, "sub_", 4) == 0
+	   || (startswith (type, "sub_")
 	       && (type[4] == 'I' || type[4] == 'D')))
     {
       const char *file = main_input_filename;
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 1089aef639f..7ee93436378 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -1783,7 +1783,7 @@ ubsan_use_new_style_p (location_t loc)
     return false;
 
   expanded_location xloc = expand_location (loc);
-  if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
+  if (xloc.file == NULL || startswith (xloc.file, "\1")
       || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
       || xloc.file[1] == '\xff')
     return false;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 811212244a5..4656a37dc09 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -792,7 +792,7 @@ default_function_rodata_section (tree decl, bool relocatable)
       /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo or
 	 .gnu.linkonce.d.rel.ro.local.foo if the jump table is relocatable.  */
       else if (DECL_COMDAT_GROUP (decl)
-	       && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
+	       && startswith (name, ".gnu.linkonce.t."))
 	{
 	  size_t len;
 	  char *rname;
@@ -817,7 +817,7 @@ default_function_rodata_section (tree decl, bool relocatable)
 	}
       /* For .text.foo we want to use .rodata.foo.  */
       else if (flag_function_sections && flag_data_sections
-	       && strncmp (name, ".text.", 6) == 0)
+	       && startswith (name, ".text."))
 	{
 	  size_t len = strlen (name) + 1;
 	  char *rname = (char *) alloca (len + strlen (sname) - 5);
@@ -2485,7 +2485,7 @@ incorporeal_function_p (tree decl)
       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
       /* Atomic or sync builtins which have survived this far will be
 	 resolved externally and therefore are not incorporeal.  */
-      if (strncmp (name, "__builtin_", 10) == 0)
+      if (startswith (name, "__builtin_"))
 	return true;
     }
   return false;
@@ -6713,22 +6713,22 @@ default_section_type_flags (tree decl, const char *name, int reloc)
     flags |= SECTION_TLS | SECTION_WRITE;
 
   if (strcmp (name, ".bss") == 0
-      || strncmp (name, ".bss.", 5) == 0
-      || strncmp (name, ".gnu.linkonce.b.", 16) == 0
+      || startswith (name, ".bss.")
+      || startswith (name, ".gnu.linkonce.b.")
       || strcmp (name, ".persistent.bss") == 0
       || strcmp (name, ".sbss") == 0
-      || strncmp (name, ".sbss.", 6) == 0
-      || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
+      || startswith (name, ".sbss.")
+      || startswith (name, ".gnu.linkonce.sb."))
     flags |= SECTION_BSS;
 
   if (strcmp (name, ".tdata") == 0
-      || strncmp (name, ".tdata.", 7) == 0
-      || strncmp (name, ".gnu.linkonce.td.", 17) == 0)
+      || startswith (name, ".tdata.")
+      || startswith (name, ".gnu.linkonce.td."))
     flags |= SECTION_TLS;
 
   if (strcmp (name, ".tbss") == 0
-      || strncmp (name, ".tbss.", 6) == 0
-      || strncmp (name, ".gnu.linkonce.tb.", 17) == 0)
+      || startswith (name, ".tbss.")
+      || startswith (name, ".gnu.linkonce.tb."))
     flags |= SECTION_TLS | SECTION_BSS;
 
   if (strcmp (name, ".noinit") == 0)


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-04-21  8:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-12 13:27 [gcc(refs/users/marxin/heads/str_starts_with-v2)] Come up with startswith function Martin Liska
  -- strict thread matches above, loose matches on Subject: below --
2021-04-21  8:35 Martin Liska
2021-03-26 11:36 Martin Liska

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).