Jeff approved an older version of this (as a separate unittests/test-folding.c): https://gcc.gnu.org/ml/gcc-patches/2015-10/msg03305.html > OK if/when prereqs are approved. Minor twiddling if we end up > moving it elsewhere or standardizing/reducing header files > is pre-approved.
gcc/ChangeLog: * fold-const.c: Include "selftest.h". (assert_binop_folds_to_const): New function. (assert_binop_folds_to_nonlvalue): New function. (test_arithmetic_folding): New function. (selftest::fold_const_c_tests): New function. --- gcc/fold-const.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8a7c93e..dd8cdab 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see #include "case-cfn-macros.h" #include "stringpool.h" #include "tree-ssanames.h" +#include "selftest.h" #ifndef LOAD_EXTEND_OP #define LOAD_EXTEND_OP(M) UNKNOWN @@ -14455,3 +14456,77 @@ c_getstr (tree src) return TREE_STRING_POINTER (src) + tree_to_uhwi (offset_node); } + +#if CHECKING_P + +/* Helper functions for writing tests of folding trees. */ + +/* Verify that the binary op (LHS CODE RHS) folds to CONSTANT. */ + +static void +assert_binop_folds_to_const (tree lhs, enum tree_code code, tree rhs, + tree constant) +{ + ASSERT_EQ (constant, fold_build2 (code, TREE_TYPE (lhs), lhs, rhs)); +} + +/* Verify that the binary op (LHS CODE RHS) folds to an NON_LVALUE_EXPR + wrapping WRAPPED_EXPR. */ + +static void +assert_binop_folds_to_nonlvalue (tree lhs, enum tree_code code, tree rhs, + tree wrapped_expr) +{ + tree result = fold_build2 (code, TREE_TYPE (lhs), lhs, rhs); + ASSERT_NE (wrapped_expr, result); + ASSERT_EQ (NON_LVALUE_EXPR, TREE_CODE (result)); + ASSERT_EQ (wrapped_expr, TREE_OPERAND (result, 0)); +} + +static void +test_arithmetic_folding () +{ + tree type = integer_type_node; + tree x = create_tmp_var_raw (type, "x"); + tree zero = build_zero_cst (type); + tree one = build_int_cst (type, 1); + + /* Addition. */ + /* 1 <-- (0 + 1) */ + assert_binop_folds_to_const (zero, PLUS_EXPR, one, + one); + assert_binop_folds_to_const (one, PLUS_EXPR, zero, + one); + + /* (nonlvalue)x <-- (x + 0) */ + assert_binop_folds_to_nonlvalue (x, PLUS_EXPR, zero, + x); + + /* Subtraction. */ + /* 0 <-- (x - x) */ + assert_binop_folds_to_const (x, MINUS_EXPR, x, + zero); + assert_binop_folds_to_nonlvalue (x, MINUS_EXPR, zero, + x); + + /* Multiplication. */ + /* 0 <-- (x * 0) */ + assert_binop_folds_to_const (x, MULT_EXPR, zero, + zero); + + /* (nonlvalue)x <-- (x * 1) */ + assert_binop_folds_to_nonlvalue (x, MULT_EXPR, one, + x); +} + +namespace selftest { + +void +fold_const_c_tests () +{ + test_arithmetic_folding (); +} + +} // namespace selftest + +#endif /* CHECKING_P */ -- 1.8.5.3