[Bug analyzer/104434] Analyzer doesn't know about "pure" and "const" functions

2022-02-28 Thread dmalcolm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104434

--- Comment #6 from David Malcolm  ---
OpenBLAS commit adding __attribute__((const)) to the decl:
https://github.com/xianyi/OpenBLAS/commit/1c1ffb0591186e50311670369dee2cb450980d9a

[Bug analyzer/104434] Analyzer doesn't know about "pure" and "const" functions

2022-02-23 Thread dmalcolm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104434

David Malcolm  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|UNCONFIRMED |RESOLVED

--- Comment #5 from David Malcolm  ---
Should be fixed by the above commit for GCC 12.

[Bug analyzer/104434] Analyzer doesn't know about "pure" and "const" functions

2022-02-23 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104434

--- Comment #4 from CVS Commits  ---
The master branch has been updated by David Malcolm :

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

commit r12-7364-gaee1adf2cdc1cf4e116e5c05b6e7c92b0fbb264b
Author: David Malcolm 
Date:   Wed Feb 23 09:14:58 2022 -0500

analyzer: handle __attribute__((const)) [PR104434]

When testing -fanalyzer on openblas-0.3, I noticed slightly over 2000
false positives from -Wanalyzer-malloc-leak on code like this:

if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) {
pt_t = (lapack_complex_float*)
LAPACKE_malloc( sizeof(lapack_complex_float) *
ldpt_t * MAX(1,n) );
[...snip...]
}

[...snip lots of code...]

if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) {
LAPACKE_free( pt_t );
}

where LAPACKE_lsame is a char-comparison function implemented in a
different TU.
The analyzer naively considers the execution path where:
  LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' )
is true at the malloc guard, but then false at the free guard, which
is thus a memory leak.

This patch makes -fanalyer respect __attribute__((const)), so that the
analyzer treats such functions as returning the same value when given
the same inputs.

I've filed https://github.com/xianyi/OpenBLAS/issues/3543 suggesting that
LAPACKE_lsame be annotated with __attribute__((const)); with that, and
with this patch, the false positives seem to be fixed.

gcc/analyzer/ChangeLog:
PR analyzer/104434
* analyzer.h (class const_fn_result_svalue): New decl.
* region-model-impl-calls.cc (call_details::get_manager): New.
* region-model-manager.cc
(region_model_manager::get_or_create_const_fn_result_svalue): New.
(region_model_manager::log_stats): Log
m_const_fn_result_values_map.
* region-model.cc (const_fn_p): New.
(maybe_get_const_fn_result): New.
(region_model::on_call_pre): Handle fndecls with
__attribute__((const)) by calling the above rather than making
a conjured_svalue.
* region-model.h (visitor::visit_const_fn_result_svalue): New.
(region_model_manager::get_or_create_const_fn_result_svalue): New
decl.
(region_model_manager::const_fn_result_values_map_t): New typedef.
(region_model_manager::m_const_fn_result_values_map): New field.
(call_details::get_manager): New decl.
* svalue.cc (svalue::cmp_ptr): Handle SK_CONST_FN_RESULT.
(const_fn_result_svalue::dump_to_pp): New.
(const_fn_result_svalue::dump_input): New.
(const_fn_result_svalue::accept): New.
* svalue.h (enum svalue_kind): Add SK_CONST_FN_RESULT.
(svalue::dyn_cast_const_fn_result_svalue): New.
(class const_fn_result_svalue): New.
(is_a_helper ::test): New.
(template <> struct
default_hash_traits):
New.

gcc/testsuite/ChangeLog:
PR analyzer/104434
* gcc.dg/analyzer/attr-const-1.c: New test.
* gcc.dg/analyzer/attr-const-2.c: New test.
* gcc.dg/analyzer/attr-const-3.c: New test.
* gcc.dg/analyzer/pr104434-const.c: New test.
* gcc.dg/analyzer/pr104434-nonconst.c: New test.
* gcc.dg/analyzer/pr104434.h: New test.

Signed-off-by: David Malcolm 

[Bug analyzer/104434] Analyzer doesn't know about "pure" and "const" functions

2022-02-23 Thread dmalcolm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104434

--- Comment #3 from David Malcolm  ---
OpenBLAS issue filed as https://github.com/xianyi/OpenBLAS/issues/3543
suggesting the use of __attribute__((const)) on LAPACKE_lsame.

[Bug analyzer/104434] Analyzer doesn't know about "pure" and "const" functions

2022-02-23 Thread dmalcolm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104434

--- Comment #2 from David Malcolm  ---
On rereading
  https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
I think that "pure" isn't strong enough for the above example: the result of a
pure function is allowed to change between invocations with the same inputs.  I
think the function needs to be "const".

[Bug analyzer/104434] Analyzer doesn't know about "pure" and "const" functions

2022-02-07 Thread dmalcolm at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104434

--- Comment #1 from David Malcolm  ---
Seen on
https://github.com/xianyi/OpenBLAS/blob/c5f280a7f0e875d83833d895b2b8b0e341efabf4/lapack-netlib/LAPACKE/src/lapacke_cgbbrd_work.c
where the code has:

   if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) {
pt_t = (lapack_complex_float*)
LAPACKE_malloc( sizeof(lapack_complex_float) *
ldpt_t * MAX(1,n) );
  ...snip...
   }

   [...snip lots of code...]

   if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) {
LAPACKE_free( pt_t );
   }

where the analyzer considers the execution path where the conditions
guarding the malloc and the free are first true, and then false.

LAPACKE_lsame is a case-insensitive comparison, implemented in its own
source file.  I think if it were marked as "pure", the analyzer could
fix this without needing LTO.