diff options
author | David Malcolm <dmalcolm@redhat.com> | 2022-01-18 11:41:19 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2022-01-18 15:56:23 -0500 |
commit | 2aefe248aa4160205c44808166393a42031d2dea (patch) | |
tree | c1ea9883541d783710f786487dcabe1370bf18ef /gcc | |
parent | 79e746bb05e432dcd1c18161469272d67c33d79d (diff) | |
download | gcc-2aefe248aa4160205c44808166393a42031d2dea.zip gcc-2aefe248aa4160205c44808166393a42031d2dea.tar.gz gcc-2aefe248aa4160205c44808166393a42031d2dea.tar.bz2 |
analyzer: fix ICE on unary ops folding to casts of constants [PR104089]
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 <dmalcolm@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/analyzer/region-model-manager.cc | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/pr104089.c | 9 |
2 files changed, 27 insertions, 1 deletions
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index 9d4f595..bb93526 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 0000000..c517704 --- /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); +} |