Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r12-6700-g2aefe248aa4160205c44808166393a42031d2dea.
gcc/analyzer/ChangeLog: PR analyzer/104089 * region-model-manager.cc (region_model_manager::get_or_create_constant_svalue): Assert that we have a CONSTANT_CLASS_P. (region_model_manager::maybe_fold_unaryop): Only fold a constant when fold_unary's result is a constant or a cast of a constant. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/pr104089.c: New test. PR analyzer/104089 Signed-off-by: David Malcolm <dmalc...@redhat.com> --- gcc/analyzer/region-model-manager.cc | 19 ++++++++++++++++++- gcc/testsuite/gcc.dg/analyzer/pr104089.c | 9 +++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr104089.c diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 9d4f5952ef3..bb93526807f 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -209,6 +209,7 @@ const svalue * region_model_manager::get_or_create_constant_svalue (tree cst_expr) { gcc_assert (cst_expr); + gcc_assert (CONSTANT_CLASS_P (cst_expr)); constant_svalue **slot = m_constants_map.get (cst_expr); if (slot) @@ -426,7 +427,23 @@ region_model_manager::maybe_fold_unaryop (tree type, enum tree_code op, /* Constants. */ if (tree cst = arg->maybe_get_constant ()) if (tree result = fold_unary (op, type, cst)) - return get_or_create_constant_svalue (result); + { + if (CONSTANT_CLASS_P (result)) + return get_or_create_constant_svalue (result); + + /* fold_unary can return casts of constants; try to handle them. */ + if (op != NOP_EXPR + && type + && TREE_CODE (result) == NOP_EXPR + && CONSTANT_CLASS_P (TREE_OPERAND (result, 0))) + { + const svalue *inner_cst + = get_or_create_constant_svalue (TREE_OPERAND (result, 0)); + return get_or_create_cast (type, + get_or_create_cast (TREE_TYPE (result), + inner_cst)); + } + } return NULL; } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104089.c b/gcc/testsuite/gcc.dg/analyzer/pr104089.c new file mode 100644 index 00000000000..c51770411f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr104089.c @@ -0,0 +1,9 @@ +/* { dg-additional-options "-frounding-math" } */ + +volatile _Float16 true_min = 5.96046447753906250000000000000000000e-8F16; + +int +main (void) +{ + return __builtin_fpclassify (0, 1, 4, 3, 2, true_min); +} -- 2.26.3