https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128361

            Bug ID: 128361
           Summary: analyzer: check_function_attrs
                    (null_terminated_string_arg and access) skipped for
                    const/pure callees and same-TU functions
           Product: gcc
           Version: 16.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: 220245569 at seu dot edu.cn
                CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
  Target Milestone: ---
            Target: *-*-*

Reproducer
----------
$ cat trigger.c
extern int ext_unannotated_pure (const char *p)
  __attribute__((null_terminated_string_arg (1), pure));

extern int ext_normal (const char *p)
  __attribute__((null_terminated_string_arg (1)));

int __attribute__((null_terminated_string_arg (1)))
defined_in_tu (const char *p)
{
  return (unsigned char) p[0];
}

int test_normal (void)
{
  char buf[3] = "abc"; /* not NUL-terminated */
  return ext_normal (buf); /* warns */
}

int test_pure (void)
{
  char buf[3] = "abc"; /* not NUL-terminated */
  return ext_unannotated_pure (buf); /* no warning */
}

int test_same_tu (void)
{
  char buf[3] = "abc"; /* not NUL-terminated */
  return defined_in_tu (buf); /* no warning */
}

Compile flag: x86_64-linux-gnu-gcc -O0 -fanalyzer -S trigger.c

trigger.c: In function 'test_normal':
trigger.c:16:10: warning: stack-based buffer over-read [CWE-126]
[-Wanalyzer-out-of-bounds]
   16 |   return ext_normal (buf); /* warns */
      |          ^~~~~~~~~~~~~~~~
# test_pure and test_same_tu emit no diagnostic

Root cause
----------
region_model::check_function_attrs (gcc/analyzer/region-model.cc:2685-2707),
which checks null_terminated_string_arg and access attributes, is only called
from region_model::handle_unrecognized_call (region-model.cc:2725), which in
turn only runs when unknown_side_effects is true (region-model.cc:2428-2430).
region_model::on_call_pre (region-model.cc:2380-2394) returns false
(unknown_side_effects = false) when the callee is const/pure (ECF_CONST |
ECF_PURE,
line 2381) or has a GIMPLE body in the same translation unit (line 2387),
skipping check_function_attrs in both cases.

Suggested Fix
-------------
Call check_function_attrs (call, callee_fndecl, ctxt) directly in
region_model::on_call_pre (or unconditionally in on_call_post when
callee_fndecl && ctxt) instead of gating it on unknown_side_effects.

Reply via email to