[committed] analyzer: move stdio known fns to sm-file.cc

Message ID 20221130010751.3663828-1-dmalcolm@redhat.com
State Committed
Commit 84046b192e568e1a0619b72a12c7263553d9610a
Headers
Series [committed] analyzer: move stdio known fns to sm-file.cc |

Commit Message

David Malcolm Nov. 30, 2022, 1:07 a.m. UTC
  Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-4400-g84046b192e568e.

gcc/analyzer/ChangeLog:
	* region-model-impl-calls.cc (class kf_fgets): Move to sm-file.cc.
	(kf_fgets::impl_call_pre): Likewise.
	(class kf_fread): Likewise.
	(kf_fread::impl_call_pre): Likewise.
	(class kf_getchar): Likewise.
	(class kf_stdio_output_fn): Likewise.
	(register_known_functions): Move registration of
	BUILT_IN_FPRINTF, BUILT_IN_FPRINTF_UNLOCKED, BUILT_IN_FPUTC,
	BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS, BUILT_IN_FPUTS_UNLOCKED,
	BUILT_IN_FWRITE, BUILT_IN_FWRITE_UNLOCKED, BUILT_IN_PRINTF,
	BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_PUTC, BUILT_IN_PUTCHAR,
	BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTC_UNLOCKED, BUILT_IN_PUTS,
	BUILT_IN_PUTS_UNLOCKED, BUILT_IN_VFPRINTF, BUILT_IN_VPRINTF,
	"getchar", "fgets", "fgets_unlocked", and "fread" to
	register_known_file_functions.
	* sm-file.cc (class kf_stdio_output_fn): Move here from
	region-model-impl-calls.cc.
	(class kf_fgets): Likewise.
	(class kf_fread): Likewise.
	(class kf_getchar): Likewise.
	(register_known_file_functions): Move registration of
	BUILT_IN_FPRINTF, BUILT_IN_FPRINTF_UNLOCKED, BUILT_IN_FPUTC,
	BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS, BUILT_IN_FPUTS_UNLOCKED,
	BUILT_IN_FWRITE, BUILT_IN_FWRITE_UNLOCKED, BUILT_IN_PRINTF,
	BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_PUTC, BUILT_IN_PUTCHAR,
	BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTC_UNLOCKED, BUILT_IN_PUTS,
	BUILT_IN_PUTS_UNLOCKED, BUILT_IN_VFPRINTF, BUILT_IN_VPRINTF,
	"fgets", "fgets_unlocked", "fread", and "getchar" to here from
	register_known_functions.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 gcc/analyzer/region-model-impl-calls.cc | 111 ------------------------
 gcc/analyzer/sm-file.cc                 | 106 ++++++++++++++++++++++
 2 files changed, 106 insertions(+), 111 deletions(-)
  

Patch

diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc
index 6d8c9f94138..8ba644c33cd 100644
--- a/gcc/analyzer/region-model-impl-calls.cc
+++ b/gcc/analyzer/region-model-impl-calls.cc
@@ -704,66 +704,6 @@  kf_error::impl_call_pre (const call_details &cd) const
       ctxt->terminate_path ();
 }
 
-/* Handler for "fgets" and "fgets_unlocked".  */
-
-class kf_fgets : public known_function
-{
-public:
-  bool matches_call_types_p (const call_details &cd) const final override
-  {
-    return (cd.num_args () == 3
-	    && cd.arg_is_pointer_p (0)
-	    && cd.arg_is_pointer_p (2));
-  }
-
-  void impl_call_pre (const call_details &cd) const final override;
-};
-
-void
-kf_fgets::impl_call_pre (const call_details &cd) const
-{
-  /* Ideally we would bifurcate state here between the
-     error vs no error cases.  */
-  region_model *model = cd.get_model ();
-  const svalue *ptr_sval = cd.get_arg_svalue (0);
-  if (const region *reg = ptr_sval->maybe_get_region ())
-    {
-      const region *base_reg = reg->get_base_region ();
-      const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
-      model->set_value (base_reg, new_sval, cd.get_ctxt ());
-    }
-}
-
-/* Handler for "fread"".  */
-
-class kf_fread : public known_function
-{
-public:
-  bool matches_call_types_p (const call_details &cd) const final override
-  {
-    return (cd.num_args () == 4
-	    && cd.arg_is_pointer_p (0)
-	    && cd.arg_is_size_p (1)
-	    && cd.arg_is_size_p (2)
-	    && cd.arg_is_pointer_p (3));
-  }
-
-  void impl_call_pre (const call_details &cd) const final override;
-};
-
-void
-kf_fread::impl_call_pre (const call_details &cd) const
-{
-  region_model *model = cd.get_model ();
-  const svalue *ptr_sval = cd.get_arg_svalue (0);
-  if (const region *reg = ptr_sval->maybe_get_region ())
-    {
-      const region *base_reg = reg->get_base_region ();
-      const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
-      model->set_value (base_reg, new_sval, cd.get_ctxt ());
-    }
-}
-
 /* Handler for "free", after sm-handling.
 
    If the ptr points to an underlying heap region, delete the region,
@@ -803,20 +743,6 @@  kf_free::impl_call_post (const call_details &cd) const
     }
 }
 
-/* Handler for "getchar"".  */
-
-class kf_getchar : public known_function
-{
-public:
-  bool matches_call_types_p (const call_details &cd) const final override
-  {
-    return cd.num_args () == 0;
-  }
-
-  /* Empty.  No side-effects (tracking stream state is out-of-scope
-     for the analyzer).  */
-};
-
 /* Handle the on_call_pre part of "malloc".  */
 
 class kf_malloc : public known_function
@@ -1455,21 +1381,6 @@  public:
   /* Currently a no-op.  */
 };
 
-/* Handler for various stdio-related builtins that merely have external
-   effects that are out of scope for the analyzer: we only want to model
-   the effects on the return value.  */
-
-class kf_stdio_output_fn : public known_function
-{
-public:
-  bool matches_call_types_p (const call_details &) const final override
-  {
-    return true;
-  }
-
-  /* A no-op; we just want the conjured return value.  */
-};
-
 /* Handler for "strcpy" and "__builtin_strcpy_chk".  */
 
 class kf_strcpy : public known_function
@@ -1592,28 +1503,12 @@  register_known_functions (known_function_manager &kfm)
     kfm.add (BUILT_IN_CALLOC, make_unique<kf_calloc> ());
     kfm.add (BUILT_IN_EXPECT, make_unique<kf_expect> ());
     kfm.add (BUILT_IN_EXPECT_WITH_PROBABILITY, make_unique<kf_expect> ());
-    kfm.add (BUILT_IN_FPRINTF, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_FPRINTF_UNLOCKED, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_FPUTC, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_FPUTC_UNLOCKED, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_FPUTS, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_FPUTS_UNLOCKED, make_unique<kf_stdio_output_fn> ());
     kfm.add (BUILT_IN_FREE, make_unique<kf_free> ());
-    kfm.add (BUILT_IN_FWRITE, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_FWRITE_UNLOCKED, make_unique<kf_stdio_output_fn> ());
     kfm.add (BUILT_IN_MALLOC, make_unique<kf_malloc> ());
     kfm.add (BUILT_IN_MEMCPY, make_unique<kf_memcpy> ());
     kfm.add (BUILT_IN_MEMCPY_CHK, make_unique<kf_memcpy> ());
     kfm.add (BUILT_IN_MEMSET, make_unique<kf_memset> ());
     kfm.add (BUILT_IN_MEMSET_CHK, make_unique<kf_memset> ());
-    kfm.add (BUILT_IN_PRINTF, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_PRINTF_UNLOCKED, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_PUTC, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_PUTCHAR, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_PUTCHAR_UNLOCKED, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_PUTC_UNLOCKED, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_PUTS, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_PUTS_UNLOCKED, make_unique<kf_stdio_output_fn> ());
     kfm.add (BUILT_IN_REALLOC, make_unique<kf_realloc> ());
     kfm.add (BUILT_IN_STACK_RESTORE, make_unique<kf_stack_restore> ());
     kfm.add (BUILT_IN_STACK_SAVE, make_unique<kf_stack_save> ());
@@ -1621,8 +1516,6 @@  register_known_functions (known_function_manager &kfm)
     kfm.add (BUILT_IN_STRCPY, make_unique<kf_strcpy> (2));
     kfm.add (BUILT_IN_STRCPY_CHK, make_unique<kf_strcpy> (3));
     kfm.add (BUILT_IN_STRLEN, make_unique<kf_strlen> ());
-    kfm.add (BUILT_IN_VFPRINTF, make_unique<kf_stdio_output_fn> ());
-    kfm.add (BUILT_IN_VPRINTF, make_unique<kf_stdio_output_fn> ());
 
     register_varargs_builtins (kfm);
   }
@@ -1650,15 +1543,11 @@  register_known_functions (known_function_manager &kfm)
 
   /* Known builtins and C standard library functions.  */
   {
-    kfm.add ("getchar", make_unique<kf_getchar> ());
     kfm.add ("memset", make_unique<kf_memset> ());
   }
 
   /* Known POSIX functions, and some non-standard extensions.  */
   {
-    kfm.add ("fgets", make_unique<kf_fgets> ());
-    kfm.add ("fgets_unlocked", make_unique<kf_fgets> ()); // non-standard
-    kfm.add ("fread", make_unique<kf_fread> ());
     kfm.add ("putenv", make_unique<kf_putenv> ());
 
     register_known_fd_functions (kfm);
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 083c0ecbe41..d2dcb4312a2 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -489,6 +489,21 @@  make_fileptr_state_machine (logger *logger)
   return new fileptr_state_machine (logger);
 }
 
+/* Handler for various stdio-related builtins that merely have external
+   effects that are out of scope for the analyzer: we only want to model
+   the effects on the return value.  */
+
+class kf_stdio_output_fn : public known_function
+{
+public:
+  bool matches_call_types_p (const call_details &) const final override
+  {
+    return true;
+  }
+
+  /* A no-op; we just want the conjured return value.  */
+};
+
 /* Handler for "ferror"".  */
 
 class kf_ferror : public known_function
@@ -517,6 +532,60 @@  public:
   /* No side effects.  */
 };
 
+/* Handler for "fgets" and "fgets_unlocked".  */
+
+class kf_fgets : public known_function
+{
+public:
+  bool matches_call_types_p (const call_details &cd) const final override
+  {
+    return (cd.num_args () == 3
+	    && cd.arg_is_pointer_p (0)
+	    && cd.arg_is_pointer_p (2));
+  }
+
+  void impl_call_pre (const call_details &cd) const final override
+  {
+    /* Ideally we would bifurcate state here between the
+       error vs no error cases.  */
+    region_model *model = cd.get_model ();
+    const svalue *ptr_sval = cd.get_arg_svalue (0);
+    if (const region *reg = ptr_sval->maybe_get_region ())
+      {
+	const region *base_reg = reg->get_base_region ();
+	const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
+	model->set_value (base_reg, new_sval, cd.get_ctxt ());
+      }
+  }
+};
+
+/* Handler for "fread"".  */
+
+class kf_fread : public known_function
+{
+public:
+  bool matches_call_types_p (const call_details &cd) const final override
+  {
+    return (cd.num_args () == 4
+	    && cd.arg_is_pointer_p (0)
+	    && cd.arg_is_size_p (1)
+	    && cd.arg_is_size_p (2)
+	    && cd.arg_is_pointer_p (3));
+  }
+
+  void impl_call_pre (const call_details &cd) const final override
+  {
+    region_model *model = cd.get_model ();
+    const svalue *ptr_sval = cd.get_arg_svalue (0);
+    if (const region *reg = ptr_sval->maybe_get_region ())
+      {
+	const region *base_reg = reg->get_base_region ();
+	const svalue *new_sval = cd.get_or_create_conjured_svalue (base_reg);
+	model->set_value (base_reg, new_sval, cd.get_ctxt ());
+      }
+  }
+};
+
 /* Handler for "getc"".  */
 
 class kf_getc : public known_function
@@ -531,15 +600,52 @@  public:
   /* No side effects.  */
 };
 
+/* Handler for "getchar"".  */
+
+class kf_getchar : public known_function
+{
+public:
+  bool matches_call_types_p (const call_details &cd) const final override
+  {
+    return cd.num_args () == 0;
+  }
+
+  /* Empty.  No side-effects (tracking stream state is out-of-scope
+     for the analyzer).  */
+};
+
 /* Populate KFM with instances of known functions relating to
    stdio streams.  */
 
 void
 register_known_file_functions (known_function_manager &kfm)
 {
+  kfm.add (BUILT_IN_FPRINTF, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_FPRINTF_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_FPUTC, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_FPUTC_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_FPUTS, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_FPUTS_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_FWRITE, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_FWRITE_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PRINTF, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PRINTF_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PUTC, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PUTCHAR, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PUTCHAR_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PUTC_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PUTS, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_PUTS_UNLOCKED, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_VFPRINTF, make_unique<kf_stdio_output_fn> ());
+  kfm.add (BUILT_IN_VPRINTF, make_unique<kf_stdio_output_fn> ());
+
   kfm.add ("ferror", make_unique<kf_ferror> ());
+  kfm.add ("fgets", make_unique<kf_fgets> ());
+  kfm.add ("fgets_unlocked", make_unique<kf_fgets> ()); // non-standard
   kfm.add ("fileno", make_unique<kf_fileno> ());
+  kfm.add ("fread", make_unique<kf_fread> ());
   kfm.add ("getc", make_unique<kf_getc> ());
+  kfm.add ("getchar", make_unique<kf_getchar> ());
 }
 
 #if CHECKING_P