"convert" is not implemented in lto1, leading to an ICE when used.
This patch implements a build_cast function for the analyzer and uses it to replace the call to "convert" when handling casts in region_model. This fixes numerous ICEs when running the analyzer from LTO. gcc/ChangeLog: * analyzer/region-model.cc: Include "convert.h" and "target.h". (build_cast): New function, adapted from jit-playback.c. (region_model::maybe_cast_1): Use it to replace the call to "convert". * doc/analyzer.texi (Limitations): Remove the reference to convert and ICEs for casts in LTO. --- gcc/analyzer/region-model.cc | 55 +++++++++++++++++++++++++++++++++++++++++++- gcc/doc/analyzer.texi | 7 +++--- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index f28661f..197f1be 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -29,6 +29,8 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "tree-dfa.h" #include "stringpool.h" +#include "convert.h" +#include "target.h" #include "selftest.h" #include "diagnostic-color.h" #include "diagnostic-metadata.h" @@ -4694,6 +4696,56 @@ region_model::get_region_for_label (tree label) return func_reg->get_or_create (this, func_rid, label, TREE_TYPE (label)); } +/* Build a cast of SRC_EXPR to DST_TYPE, or return NULL_TREE. + + Adapted from gcc::jit::playback::context::build_cast, which in turn is + adapted from + - c/c-typeck.c:build_c_cast + - c/c-convert.c: convert + - convert.h + Only some kinds of cast are currently supported here. */ + +static tree +build_cast (tree dst_type, tree src_expr) +{ + tree result = targetm.convert_to_type (dst_type, src_expr); + if (result) + return result; + enum tree_code dst_code = TREE_CODE (dst_type); + switch (dst_code) + { + case INTEGER_TYPE: + case ENUMERAL_TYPE: + result = convert_to_integer (dst_type, src_expr); + goto maybe_fold; + + case BOOLEAN_TYPE: + /* Compare with c_objc_common_truthvalue_conversion and + c_common_truthvalue_conversion. */ + /* For now, convert to: (src_expr != 0) */ + result = build2 (NE_EXPR, dst_type, + src_expr, + build_int_cst (TREE_TYPE (src_expr), 0)); + goto maybe_fold; + + case REAL_TYPE: + result = convert_to_real (dst_type, src_expr); + goto maybe_fold; + + case POINTER_TYPE: + result = build1 (NOP_EXPR, dst_type, src_expr); + goto maybe_fold; + + default: + return NULL_TREE; + + maybe_fold: + if (TREE_CODE (result) != C_MAYBE_CONST_EXPR) + result = fold (result); + return result; + } +} + /* If the type of SID's underlying value is DST_TYPE, return SID. Otherwise, attempt to create (or reuse) an svalue representing an access of SID as a DST_TYPE and return that value's svalue_id. */ @@ -4740,7 +4792,8 @@ region_model::maybe_cast_1 (tree dst_type, svalue_id sid) /* Attempt to cast constants. */ if (tree src_cst = sval->maybe_get_constant ()) { - tree dst = convert (dst_type, src_cst); + tree dst = build_cast (dst_type, src_cst); + gcc_assert (dst != NULL_TREE); if (CONSTANT_CLASS_P (dst)) return get_or_create_constant_svalue (dst); } diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi index 8e7b26f..adf375a 100644 --- a/gcc/doc/analyzer.texi +++ b/gcc/doc/analyzer.texi @@ -382,11 +382,10 @@ The checkers are currently hardcoded and don't allow for user extensibility (e.g. adding allocate/release pairs). @item Although the analyzer's test suite has a proof-of-concept test case for -LTO, it will crash on anything non-trivial. There are various +LTO, LTO support hasn't had extensive testing. There are various lang-specific things in the analyzer that assume C rather than LTO. -For example, casts are currently implemented via @code{convert}, and this -leads to an ICE on LTO. Similarly, SSA names are printed to the user in -``raw'' form, rather than printing the underlying variable name. +For example, SSA names are printed to the user in ``raw'' form, rather +than printing the underlying variable name. @end itemize Some ideas for other checkers -- 1.8.5.3