diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-12-19 15:08:21 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-12-19 15:08:21 +0000 |
commit | dfd7fdca2ac17d8b823a16700525824ca312ade0 (patch) | |
tree | 2bf4bf940ff4bc674f358d0968d5560dbdb0ed76 /gcc/tree.c | |
parent | 9a0317e70007d6558e53a2ba5b104ff09b2e9642 (diff) | |
download | gcc-dfd7fdca2ac17d8b823a16700525824ca312ade0.zip gcc-dfd7fdca2ac17d8b823a16700525824ca312ade0.tar.gz gcc-dfd7fdca2ac17d8b823a16700525824ca312ade0.tar.bz2 |
C++: more location wrapper nodes (PR c++/43064, PR c++/43486)
This is v6 of the patch, as posted to:
https://gcc.gnu.org/ml/gcc-patches/2018-12/msg01331.html
The C++ frontend gained various location wrapper nodes in r256448 (GCC 8).
That patch:
https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00799.html
added wrapper nodes around all nodes with !CAN_HAVE_LOCATION_P for:
* arguments at callsites, and for
* typeid, alignof, sizeof, and offsetof.
This is a followup to that patch, adding many more location wrappers
to the C++ frontend. It adds location wrappers for nodes with
!CAN_HAVE_LOCATION_P to:
* all literal nodes (in cp_parser_primary_expression)
* all id-expression nodes (in finish_id_expression), except within a
decltype.
* all mem-initializer nodes within a mem-initializer-list
(in cp_parser_mem_initializer)
However, the patch also adds some suppressions: regions in the parser
for which wrapper nodes will not be created:
* within a template-parameter-list or template-argument-list (in
cp_parser_template_parameter_list and cp_parser_template_argument_list
respectively), to avoid encoding the spelling location of the nodes
in types. For example, "array<10>" and "array<10>" are the same type,
despite the fact that the two different "10" tokens are spelled in
different locations in the source.
* within a gnu-style attribute (none of are handlers are set up to cope
with location wrappers yet)
* within various OpenMP clauses
The patch enables various improvements to locations for bad
initializations, for -Wchar-subscripts, and enables various other
improvements in the followup patch.
For example, given the followup buggy mem-initializer:
class X {
X() : bad(42),
good(42)
{ }
void* bad;
int good;
};
previously, our diagnostic was on the final close parenthesis of the
mem-initializer-list, leaving it unclear where the problem is:
t.cc: In constructor 'X::X()':
t.cc:3:16: error: invalid conversion from 'int' to 'void*' [-fpermissive]
3 | good(42)
| ^
| |
| int
whereas with the patch we highlight which expression is bogus:
t.cc: In constructor 'X::X()':
t.cc:2:13: error: invalid conversion from 'int' to 'void*' [-fpermissive]
2 | X() : bad(42),
| ^~
| |
| int
Similarly, the diagnostic for this bogus initialization:
i.cc:1:44: error: initializer-string for array of chars is too long [-fpermissive]
1 | char test[3][4] = { "ok", "too long", "ok" };
| ^
is improved by the patch so that it indicates which string is too long:
i.cc:1:27: error: initializer-string for array of chars is too long [-fpermissive]
1 | char test[3][4] = { "ok", "too long", "ok" };
| ^~~~~~~~~~
gcc/c-family/ChangeLog:
PR c++/43064
PR c++/43486
* c-common.c (unsafe_conversion_p): Fold any location wrapper.
(verify_tree): Handle location wrappers.
(c_common_truthvalue_conversion): Strip any location wrapper.
Handle CONST_DECL.
(fold_offsetof): Strip any location wrapper.
(complete_array_type): Likewise for initial_value.
(convert_vector_to_array_for_subscript): Call fold_for_warn on the
index before checking for INTEGER_CST.
* c-pretty-print.c (c_pretty_printer::primary_expression): Don't
print parentheses around location wrappers.
* c-warn.c (warn_logical_operator): Call fold_for_warn on op_right
before checking for INTEGER_CST.
(warn_tautological_bitwise_comparison): Call
tree_strip_any_location_wrapper on lhs, rhs, and bitop's operand
before checking for INTEGER_CST.
(readonly_error): Strip any location wrapper.
(warn_array_subscript_with_type_char): Strip location wrappers
before checking for INTEGER_CST. Use the location of the index if
available.
gcc/ChangeLog:
PR c++/43064
PR c++/43486
* convert.c: Include "selftest.h".
(preserve_any_location_wrapper): New function.
(convert_to_pointer_maybe_fold): Update to handle location
wrappers.
(convert_to_real_maybe_fold): Likewise.
(convert_to_integer_1): Strip expr when using TREE_OVERFLOW.
Handle location wrappers when checking for INTEGER_CST.
(convert_to_integer_maybe_fold): Update to handle location
wrappers.
(convert_to_complex_maybe_fold): Likewise.
(selftest::test_convert_to_integer_maybe_fold): New functions.
(selftest::convert_c_tests): New function.
* convert.h (preserve_any_location_wrapper): New decl.
* fold-const.c (size_binop_loc): Strip location wrappers when
using TREE_OVERFLOW.
(operand_equal_p): Strip any location wrappers.
(integer_valued_real_p): Strip any location wrapper.
* selftest-run-tests.c (selftest::run_tests): Call
selftest::convert_c_tests.
* selftest.h (selftest::convert_c_tests): New decl.
* tree.c (build_complex): Assert that REAL and IMAG are constants.
(integer_zerop): Look through location wrappers.
(integer_onep): Likewise.
(integer_each_onep): Likewise.
(integer_all_onesp): Likewise.
(integer_minus_onep): Likewise.
(integer_pow2p): Likewise.
(integer_nonzerop): Likewise.
(integer_truep): Likewise.
(fixed_zerop): Likewise.
(real_zerop): Likewise.
(real_onep): Likewise.
(real_minus_onep): Likewise.
(tree_int_cst_equal): Likewise.
(simple_cst_equal): Treat location wrappers with non-equal source
locations as being unequal.
(uniform_integer_cst_p): Look through location wrappers.
(maybe_wrap_with_location): Don't create wrappers if any
auto_suppress_location_wrappers are active.
(suppress_location_wrappers): New variable.
(selftest::test_predicates): New test.
(selftest::tree_c_tests): Call it.
* tree.h (CONSTANT_CLASS_OR_WRAPPER_P): New macro.
(suppress_location_wrappers): New decl.
(class auto_suppress_location_wrappers): New class.
gcc/cp/ChangeLog:
PR c++/43064
PR c++/43486
* call.c (build_conditional_expr_1): Strip location wrappers when
checking for CONST_DECL.
(conversion_null_warnings): Use location of "expr" if available.
* class.c (fixed_type_or_null): Handle location wrappers.
* constexpr.c (potential_constant_expression_1): Likewise.
* cvt.c (ignore_overflows): Strip location wrappers when
checking for INTEGER_CST, and re-wrap the result if present.
(ocp_convert): Call fold_for_warn before checking for INTEGER_CST.
* decl.c (reshape_init_r): Strip any location wrapper.
(undeduced_auto_decl): Likewise.
* expr.c (mark_discarded_use): Likewise for expr.
* init.c (build_aggr_init): Likewise before checking init for
DECL_P.
(warn_placement_new_too_small): Call fold_for_warn on adj before
checking for CONSTANT_CLASS_P, and on nelts. Strip any location
wrapper from op0 and on oper before checking for VAR_P.
* parser.c (cp_parser_primary_expression): Call
maybe_add_location_wrapper on numeric and string literals.
(cp_parser_postfix_expression): Strip any location wrapper when
checking for DECL_IS_BUILTIN_CONSTANT_P.
(cp_parser_unary_expression): Ensure that folding of NEGATE_EXPR
around a constant happens in the presence of location wrappers and
returns a wrapped result.
(cp_parser_has_attribute_expression): Strip any location wrapper
from "oper".
(cp_parser_binary_expression): Strip any location wrapper when
checking for DECL_P on the lhs.
(cp_parser_decltype): Strip any location wrapper from result of
cp_parser_decltype_expr.
(cp_parser_mem_initializer): Add location wrappers to the
parenthesized expression list.
(cp_parser_template_parameter_list): Don't create wrapper nodes
within a template-parameter-list.
(cp_parser_template_argument_list): Don't create wrapper nodes
within a template-argument-list.
(cp_parser_parameter_declaration): Strip location wrappers from
default arguments.
(cp_parser_gnu_attribute_list): Don't create wrapper nodes.
(cp_parser_std_attribute_spec_seq): Likewise.
(cp_parser_omp_all_clauses): Don't create wrapper nodes within
OpenMP clauses.
(cp_parser_omp_for_loop): Likewise.
(cp_parser_omp_declare_reduction_exprs): Likewise.
* pt.c (convert_nontype_argument_function): Strip location
wrappers from fn_no_ptr before checking for FUNCTION_DECL.
(tsubst_default_argument): Move note about which callsite led to
instantiation to after the check_default_argument call.
(do_auto_deduction): Likewise from init before checking for
DECL_P.
* semantics.c (force_paren_expr): Likewise from expr before
checking for DECL_P.
(finish_parenthesized_expr): Likewise from expr before
checking for STRING_CST.
(perform_koenig_lookup): Likewise from fn.
(finish_call_expr): Likewise.
(finish_id_expression): Rename to...
(finish_id_expression_1): ...this, calling
maybe_add_location_wrapper on the result.
(capture_decltype): Use lookup_name_real rather than value_member
when looking up decl within the capture-list.
* tree.c (cp_stabilize_reference): Strip any location wrapper.
(builtin_valid_in_constant_expr_p): Likewise.
(strip_typedefs_expr): Strip any location wrapper before checking
for decls or constants.
(is_overloaded_fn): Likewise.
(maybe_get_fns): Likewise.
(selftest::test_lvalue_kind): Verify lvalue_p.
* typeck.c (cxx_sizeof_expr): Strip any location wrapper.
(cxx_alignof_expr): Likewise.
(is_bitfield_expr_with_lowered_type): Handle location wrappers.
(cp_build_array_ref): Call maybe_constant_value on "idx".
(cp_build_binary_op): Strip location wrapper from first_arg before
checking for PARM_DECL. Likewise for op1 before checking for
INTEGER_CST in two places. Likewise for orig_op0 and orig_op1
when checking for STRING_CST.
(cp_build_addr_expr_1): Likewise for arg when checking for
FUNCTION_DECL.
(cp_build_modify_expr): Likewise for newrhs when checking for
STRING_CST.
(convert_for_assignment): Don't strip location wrappers when
stripping NON_LVALUE_EXPR.
(maybe_warn_about_returning_address_of_local): Strip location
wrapper from whats_returned before checking for DECL_P.
(can_do_nrvo_p): Strip location wrapper from retval.
(treat_lvalue_as_rvalue_p): Likewise.
(check_return_expr): Likewise.
* typeck2.c (cxx_incomplete_type_diagnostic): Strip location
wrapper from value before checking for VAR_P or PARM_DECL.
(digest_init_r): Strip location wrapper from init. When
copying "init", also copy the wrapped node.
gcc/objc/ChangeLog:
PR c++/43064
PR c++/43486
* objc-act.c (objc_maybe_build_component_ref): Strip any location
wrapper before checking for UOBJC_SUPER_decl and self_decl.
(objc_finish_message_expr): Strip any location wrapper.
(gen_declaration): Strip location wrappers from "w".
gcc/testsuite/ChangeLog:
PR c++/43064
PR c++/43486
* c-c++-common/pr51712.c (valid2): Mark xfail as passing on C++.
* g++.dg/cpp0x/constexpr-47969.C: Update column of expected error.
* g++.dg/cpp0x/constexpr-ex2.C: Likewise.
* g++.dg/cpp0x/scoped_enum2.C: Likewise.
* g++.dg/cpp1z/decomp48.C: Update expected location of warning
for named local variables to use that of the local variable.
* g++.dg/ext/vla1.C: Update column.
* g++.dg/init/array43.C: Update expected column to be that of the
initializer.
* g++.dg/init/initializer-string-too-long.C: New test.
* g++.dg/init/new44.C: Add "-ftrack-macro-expansion=0".
* g++.dg/init/pr43064-1.C: New test.
* g++.dg/init/pr43064-2.C: New test.
* g++.dg/init/pr43064-3.C: New test.
* g++.dg/other/fold1.C: Update column of expected error.
* g++.dg/parse/crash36.C: Likewise.
* g++.dg/plugin/diagnostic-test-expressions-1.C: Add negative
integer and float expressions.
* g++.dg/template/defarg6.C: Move expected error to the default
argument; add expected message about where instantiated.
* g++.dg/wrappers/Wparentheses.C: New test.
* g++.old-deja/g++.bugs/900402_02.C: Update column of expected
error.
From-SVN: r267272
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 402 |
1 files changed, 389 insertions, 13 deletions
@@ -2208,6 +2208,9 @@ build_string (int len, const char *str) tree build_complex (tree type, tree real, tree imag) { + gcc_assert (CONSTANT_CLASS_P (real)); + gcc_assert (CONSTANT_CLASS_P (imag)); + tree t = make_node (COMPLEX_CST); TREE_REALPART (t) = real; @@ -2506,11 +2509,13 @@ zerop (const_tree expr) } /* Return 1 if EXPR is the integer constant zero or a complex constant - of zero. */ + of zero, or a location wrapper for such a constant. */ bool integer_zerop (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + switch (TREE_CODE (expr)) { case INTEGER_CST: @@ -2528,11 +2533,13 @@ integer_zerop (const_tree expr) } /* Return 1 if EXPR is the integer constant one or the corresponding - complex constant. */ + complex constant, or a location wrapper for such a constant. */ bool integer_onep (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + switch (TREE_CODE (expr)) { case INTEGER_CST: @@ -2550,11 +2557,14 @@ integer_onep (const_tree expr) } /* Return 1 if EXPR is the integer constant one. For complex and vector, - return 1 if every piece is the integer constant one. */ + return 1 if every piece is the integer constant one. + Also return 1 for location wrappers for such a constant. */ bool integer_each_onep (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + if (TREE_CODE (expr) == COMPLEX_CST) return (integer_onep (TREE_REALPART (expr)) && integer_onep (TREE_IMAGPART (expr))); @@ -2563,11 +2573,14 @@ integer_each_onep (const_tree expr) } /* Return 1 if EXPR is an integer containing all 1's in as much precision as - it contains, or a complex or vector whose subparts are such integers. */ + it contains, or a complex or vector whose subparts are such integers, + or a location wrapper for such a constant. */ bool integer_all_onesp (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + if (TREE_CODE (expr) == COMPLEX_CST && integer_all_onesp (TREE_REALPART (expr)) && integer_all_onesp (TREE_IMAGPART (expr))) @@ -2585,11 +2598,14 @@ integer_all_onesp (const_tree expr) == wi::to_wide (expr)); } -/* Return 1 if EXPR is the integer constant minus one. */ +/* Return 1 if EXPR is the integer constant minus one, or a location wrapper + for such a constant. */ bool integer_minus_onep (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + if (TREE_CODE (expr) == COMPLEX_CST) return (integer_all_onesp (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))); @@ -2598,11 +2614,13 @@ integer_minus_onep (const_tree expr) } /* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only - one bit on). */ + one bit on), or a location wrapper for such a constant. */ bool integer_pow2p (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + if (TREE_CODE (expr) == COMPLEX_CST && integer_pow2p (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))) @@ -2615,11 +2633,14 @@ integer_pow2p (const_tree expr) } /* Return 1 if EXPR is an integer constant other than zero or a - complex constant other than zero. */ + complex constant other than zero, or a location wrapper for such a + constant. */ bool integer_nonzerop (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + return ((TREE_CODE (expr) == INTEGER_CST && wi::to_wide (expr) != 0) || (TREE_CODE (expr) == COMPLEX_CST @@ -2629,21 +2650,27 @@ integer_nonzerop (const_tree expr) /* Return 1 if EXPR is the integer constant one. For vector, return 1 if every piece is the integer constant minus one - (representing the value TRUE). */ + (representing the value TRUE). + Also return 1 for location wrappers for such a constant. */ bool integer_truep (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + if (TREE_CODE (expr) == VECTOR_CST) return integer_all_onesp (expr); return integer_onep (expr); } -/* Return 1 if EXPR is the fixed-point constant zero. */ +/* Return 1 if EXPR is the fixed-point constant zero, or a location wrapper + for such a constant. */ bool fixed_zerop (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + return (TREE_CODE (expr) == FIXED_CST && TREE_FIXED_CST (expr).data.is_zero ()); } @@ -2784,11 +2811,14 @@ tree_ctz (const_tree expr) } /* Return 1 if EXPR is the real constant zero. Trailing zeroes matter for - decimal float constants, so don't return 1 for them. */ + decimal float constants, so don't return 1 for them. + Also return 1 for location wrappers around such a constant. */ bool real_zerop (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + switch (TREE_CODE (expr)) { case REAL_CST: @@ -2814,11 +2844,14 @@ real_zerop (const_tree expr) /* Return 1 if EXPR is the real constant one in real or complex form. Trailing zeroes matter for decimal float constants, so don't return - 1 for them. */ + 1 for them. + Also return 1 for location wrappers around such a constant. */ bool real_onep (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + switch (TREE_CODE (expr)) { case REAL_CST: @@ -2837,11 +2870,14 @@ real_onep (const_tree expr) } /* Return 1 if EXPR is the real constant minus one. Trailing zeroes - matter for decimal float constants, so don't return 1 for them. */ + matter for decimal float constants, so don't return 1 for them. + Also return 1 for location wrappers around such a constant. */ bool real_minus_onep (const_tree expr) { + STRIP_ANY_LOCATION_WRAPPER (expr); + switch (TREE_CODE (expr)) { case REAL_CST: @@ -7106,6 +7142,9 @@ tree_int_cst_equal (const_tree t1, const_tree t2) if (t1 == 0 || t2 == 0) return 0; + STRIP_ANY_LOCATION_WRAPPER (t1); + STRIP_ANY_LOCATION_WRAPPER (t2); + if (TREE_CODE (t1) == INTEGER_CST && TREE_CODE (t2) == INTEGER_CST && wi::to_widest (t1) == wi::to_widest (t2)) @@ -7266,6 +7305,15 @@ simple_cst_equal (const_tree t1, const_tree t2) if (t1 == 0 || t2 == 0) return 0; + /* For location wrappers to be the same, they must be at the same + source location (and wrap the same thing). */ + if (location_wrapper_p (t1) && location_wrapper_p (t2)) + { + if (EXPR_LOCATION (t1) != EXPR_LOCATION (t2)) + return 0; + return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); + } + code1 = TREE_CODE (t1); code2 = TREE_CODE (t2); @@ -11226,11 +11274,14 @@ uniform_vector_p (const_tree vec) /* If the argument is INTEGER_CST, return it. If the argument is vector with all elements the same INTEGER_CST, return that INTEGER_CST. Otherwise - return NULL_TREE. */ + return NULL_TREE. + Look through location wrappers. */ tree uniform_integer_cst_p (tree t) { + STRIP_ANY_LOCATION_WRAPPER (t); + if (TREE_CODE (t) == INTEGER_CST) return t; @@ -14646,6 +14697,11 @@ maybe_wrap_with_location (tree expr, location_t loc) if (EXCEPTIONAL_CLASS_P (expr)) return expr; + /* If any auto_suppress_location_wrappers are active, don't create + wrappers. */ + if (suppress_location_wrappers > 0) + return expr; + tree_code code = (((CONSTANT_CLASS_P (expr) && TREE_CODE (expr) != STRING_CST) || (TREE_CODE (expr) == CONST_DECL && !TREE_STATIC (expr))) @@ -14656,6 +14712,8 @@ maybe_wrap_with_location (tree expr, location_t loc) return wrapper; } +int suppress_location_wrappers; + /* Return the name of combined function FN, for debugging purposes. */ const char * @@ -15146,6 +15204,323 @@ test_location_wrappers () check_strip_nops (wrapped_int_var, int_var); } +/* Test various tree predicates. Verify that location wrappers don't + affect the results. */ + +static void +test_predicates () +{ + /* Build various constants and wrappers around them. */ + + location_t loc = BUILTINS_LOCATION; + + tree i_0 = build_int_cst (integer_type_node, 0); + tree wr_i_0 = maybe_wrap_with_location (i_0, loc); + + tree i_1 = build_int_cst (integer_type_node, 1); + tree wr_i_1 = maybe_wrap_with_location (i_1, loc); + + tree i_m1 = build_int_cst (integer_type_node, -1); + tree wr_i_m1 = maybe_wrap_with_location (i_m1, loc); + + tree f_0 = build_real_from_int_cst (float_type_node, i_0); + tree wr_f_0 = maybe_wrap_with_location (f_0, loc); + tree f_1 = build_real_from_int_cst (float_type_node, i_1); + tree wr_f_1 = maybe_wrap_with_location (f_1, loc); + tree f_m1 = build_real_from_int_cst (float_type_node, i_m1); + tree wr_f_m1 = maybe_wrap_with_location (f_m1, loc); + + tree c_i_0 = build_complex (NULL_TREE, i_0, i_0); + tree c_i_1 = build_complex (NULL_TREE, i_1, i_0); + tree c_i_m1 = build_complex (NULL_TREE, i_m1, i_0); + + tree c_f_0 = build_complex (NULL_TREE, f_0, f_0); + tree c_f_1 = build_complex (NULL_TREE, f_1, f_0); + tree c_f_m1 = build_complex (NULL_TREE, f_m1, f_0); + + /* TODO: vector constants. */ + + /* Test integer_onep. */ + ASSERT_FALSE (integer_onep (i_0)); + ASSERT_FALSE (integer_onep (wr_i_0)); + ASSERT_TRUE (integer_onep (i_1)); + ASSERT_TRUE (integer_onep (wr_i_1)); + ASSERT_FALSE (integer_onep (i_m1)); + ASSERT_FALSE (integer_onep (wr_i_m1)); + ASSERT_FALSE (integer_onep (f_0)); + ASSERT_FALSE (integer_onep (wr_f_0)); + ASSERT_FALSE (integer_onep (f_1)); + ASSERT_FALSE (integer_onep (wr_f_1)); + ASSERT_FALSE (integer_onep (f_m1)); + ASSERT_FALSE (integer_onep (wr_f_m1)); + ASSERT_FALSE (integer_onep (c_i_0)); + ASSERT_TRUE (integer_onep (c_i_1)); + ASSERT_FALSE (integer_onep (c_i_m1)); + ASSERT_FALSE (integer_onep (c_f_0)); + ASSERT_FALSE (integer_onep (c_f_1)); + ASSERT_FALSE (integer_onep (c_f_m1)); + + /* Test integer_zerop. */ + ASSERT_TRUE (integer_zerop (i_0)); + ASSERT_TRUE (integer_zerop (wr_i_0)); + ASSERT_FALSE (integer_zerop (i_1)); + ASSERT_FALSE (integer_zerop (wr_i_1)); + ASSERT_FALSE (integer_zerop (i_m1)); + ASSERT_FALSE (integer_zerop (wr_i_m1)); + ASSERT_FALSE (integer_zerop (f_0)); + ASSERT_FALSE (integer_zerop (wr_f_0)); + ASSERT_FALSE (integer_zerop (f_1)); + ASSERT_FALSE (integer_zerop (wr_f_1)); + ASSERT_FALSE (integer_zerop (f_m1)); + ASSERT_FALSE (integer_zerop (wr_f_m1)); + ASSERT_TRUE (integer_zerop (c_i_0)); + ASSERT_FALSE (integer_zerop (c_i_1)); + ASSERT_FALSE (integer_zerop (c_i_m1)); + ASSERT_FALSE (integer_zerop (c_f_0)); + ASSERT_FALSE (integer_zerop (c_f_1)); + ASSERT_FALSE (integer_zerop (c_f_m1)); + + /* Test integer_all_onesp. */ + ASSERT_FALSE (integer_all_onesp (i_0)); + ASSERT_FALSE (integer_all_onesp (wr_i_0)); + ASSERT_FALSE (integer_all_onesp (i_1)); + ASSERT_FALSE (integer_all_onesp (wr_i_1)); + ASSERT_TRUE (integer_all_onesp (i_m1)); + ASSERT_TRUE (integer_all_onesp (wr_i_m1)); + ASSERT_FALSE (integer_all_onesp (f_0)); + ASSERT_FALSE (integer_all_onesp (wr_f_0)); + ASSERT_FALSE (integer_all_onesp (f_1)); + ASSERT_FALSE (integer_all_onesp (wr_f_1)); + ASSERT_FALSE (integer_all_onesp (f_m1)); + ASSERT_FALSE (integer_all_onesp (wr_f_m1)); + ASSERT_FALSE (integer_all_onesp (c_i_0)); + ASSERT_FALSE (integer_all_onesp (c_i_1)); + ASSERT_FALSE (integer_all_onesp (c_i_m1)); + ASSERT_FALSE (integer_all_onesp (c_f_0)); + ASSERT_FALSE (integer_all_onesp (c_f_1)); + ASSERT_FALSE (integer_all_onesp (c_f_m1)); + + /* Test integer_minus_onep. */ + ASSERT_FALSE (integer_minus_onep (i_0)); + ASSERT_FALSE (integer_minus_onep (wr_i_0)); + ASSERT_FALSE (integer_minus_onep (i_1)); + ASSERT_FALSE (integer_minus_onep (wr_i_1)); + ASSERT_TRUE (integer_minus_onep (i_m1)); + ASSERT_TRUE (integer_minus_onep (wr_i_m1)); + ASSERT_FALSE (integer_minus_onep (f_0)); + ASSERT_FALSE (integer_minus_onep (wr_f_0)); + ASSERT_FALSE (integer_minus_onep (f_1)); + ASSERT_FALSE (integer_minus_onep (wr_f_1)); + ASSERT_FALSE (integer_minus_onep (f_m1)); + ASSERT_FALSE (integer_minus_onep (wr_f_m1)); + ASSERT_FALSE (integer_minus_onep (c_i_0)); + ASSERT_FALSE (integer_minus_onep (c_i_1)); + ASSERT_TRUE (integer_minus_onep (c_i_m1)); + ASSERT_FALSE (integer_minus_onep (c_f_0)); + ASSERT_FALSE (integer_minus_onep (c_f_1)); + ASSERT_FALSE (integer_minus_onep (c_f_m1)); + + /* Test integer_each_onep. */ + ASSERT_FALSE (integer_each_onep (i_0)); + ASSERT_FALSE (integer_each_onep (wr_i_0)); + ASSERT_TRUE (integer_each_onep (i_1)); + ASSERT_TRUE (integer_each_onep (wr_i_1)); + ASSERT_FALSE (integer_each_onep (i_m1)); + ASSERT_FALSE (integer_each_onep (wr_i_m1)); + ASSERT_FALSE (integer_each_onep (f_0)); + ASSERT_FALSE (integer_each_onep (wr_f_0)); + ASSERT_FALSE (integer_each_onep (f_1)); + ASSERT_FALSE (integer_each_onep (wr_f_1)); + ASSERT_FALSE (integer_each_onep (f_m1)); + ASSERT_FALSE (integer_each_onep (wr_f_m1)); + ASSERT_FALSE (integer_each_onep (c_i_0)); + ASSERT_FALSE (integer_each_onep (c_i_1)); + ASSERT_FALSE (integer_each_onep (c_i_m1)); + ASSERT_FALSE (integer_each_onep (c_f_0)); + ASSERT_FALSE (integer_each_onep (c_f_1)); + ASSERT_FALSE (integer_each_onep (c_f_m1)); + + /* Test integer_truep. */ + ASSERT_FALSE (integer_truep (i_0)); + ASSERT_FALSE (integer_truep (wr_i_0)); + ASSERT_TRUE (integer_truep (i_1)); + ASSERT_TRUE (integer_truep (wr_i_1)); + ASSERT_FALSE (integer_truep (i_m1)); + ASSERT_FALSE (integer_truep (wr_i_m1)); + ASSERT_FALSE (integer_truep (f_0)); + ASSERT_FALSE (integer_truep (wr_f_0)); + ASSERT_FALSE (integer_truep (f_1)); + ASSERT_FALSE (integer_truep (wr_f_1)); + ASSERT_FALSE (integer_truep (f_m1)); + ASSERT_FALSE (integer_truep (wr_f_m1)); + ASSERT_FALSE (integer_truep (c_i_0)); + ASSERT_TRUE (integer_truep (c_i_1)); + ASSERT_FALSE (integer_truep (c_i_m1)); + ASSERT_FALSE (integer_truep (c_f_0)); + ASSERT_FALSE (integer_truep (c_f_1)); + ASSERT_FALSE (integer_truep (c_f_m1)); + + /* Test integer_nonzerop. */ + ASSERT_FALSE (integer_nonzerop (i_0)); + ASSERT_FALSE (integer_nonzerop (wr_i_0)); + ASSERT_TRUE (integer_nonzerop (i_1)); + ASSERT_TRUE (integer_nonzerop (wr_i_1)); + ASSERT_TRUE (integer_nonzerop (i_m1)); + ASSERT_TRUE (integer_nonzerop (wr_i_m1)); + ASSERT_FALSE (integer_nonzerop (f_0)); + ASSERT_FALSE (integer_nonzerop (wr_f_0)); + ASSERT_FALSE (integer_nonzerop (f_1)); + ASSERT_FALSE (integer_nonzerop (wr_f_1)); + ASSERT_FALSE (integer_nonzerop (f_m1)); + ASSERT_FALSE (integer_nonzerop (wr_f_m1)); + ASSERT_FALSE (integer_nonzerop (c_i_0)); + ASSERT_TRUE (integer_nonzerop (c_i_1)); + ASSERT_TRUE (integer_nonzerop (c_i_m1)); + ASSERT_FALSE (integer_nonzerop (c_f_0)); + ASSERT_FALSE (integer_nonzerop (c_f_1)); + ASSERT_FALSE (integer_nonzerop (c_f_m1)); + + /* Test real_zerop. */ + ASSERT_FALSE (real_zerop (i_0)); + ASSERT_FALSE (real_zerop (wr_i_0)); + ASSERT_FALSE (real_zerop (i_1)); + ASSERT_FALSE (real_zerop (wr_i_1)); + ASSERT_FALSE (real_zerop (i_m1)); + ASSERT_FALSE (real_zerop (wr_i_m1)); + ASSERT_TRUE (real_zerop (f_0)); + ASSERT_TRUE (real_zerop (wr_f_0)); + ASSERT_FALSE (real_zerop (f_1)); + ASSERT_FALSE (real_zerop (wr_f_1)); + ASSERT_FALSE (real_zerop (f_m1)); + ASSERT_FALSE (real_zerop (wr_f_m1)); + ASSERT_FALSE (real_zerop (c_i_0)); + ASSERT_FALSE (real_zerop (c_i_1)); + ASSERT_FALSE (real_zerop (c_i_m1)); + ASSERT_TRUE (real_zerop (c_f_0)); + ASSERT_FALSE (real_zerop (c_f_1)); + ASSERT_FALSE (real_zerop (c_f_m1)); + + /* Test real_onep. */ + ASSERT_FALSE (real_onep (i_0)); + ASSERT_FALSE (real_onep (wr_i_0)); + ASSERT_FALSE (real_onep (i_1)); + ASSERT_FALSE (real_onep (wr_i_1)); + ASSERT_FALSE (real_onep (i_m1)); + ASSERT_FALSE (real_onep (wr_i_m1)); + ASSERT_FALSE (real_onep (f_0)); + ASSERT_FALSE (real_onep (wr_f_0)); + ASSERT_TRUE (real_onep (f_1)); + ASSERT_TRUE (real_onep (wr_f_1)); + ASSERT_FALSE (real_onep (f_m1)); + ASSERT_FALSE (real_onep (wr_f_m1)); + ASSERT_FALSE (real_onep (c_i_0)); + ASSERT_FALSE (real_onep (c_i_1)); + ASSERT_FALSE (real_onep (c_i_m1)); + ASSERT_FALSE (real_onep (c_f_0)); + ASSERT_TRUE (real_onep (c_f_1)); + ASSERT_FALSE (real_onep (c_f_m1)); + + /* Test real_minus_onep. */ + ASSERT_FALSE (real_minus_onep (i_0)); + ASSERT_FALSE (real_minus_onep (wr_i_0)); + ASSERT_FALSE (real_minus_onep (i_1)); + ASSERT_FALSE (real_minus_onep (wr_i_1)); + ASSERT_FALSE (real_minus_onep (i_m1)); + ASSERT_FALSE (real_minus_onep (wr_i_m1)); + ASSERT_FALSE (real_minus_onep (f_0)); + ASSERT_FALSE (real_minus_onep (wr_f_0)); + ASSERT_FALSE (real_minus_onep (f_1)); + ASSERT_FALSE (real_minus_onep (wr_f_1)); + ASSERT_TRUE (real_minus_onep (f_m1)); + ASSERT_TRUE (real_minus_onep (wr_f_m1)); + ASSERT_FALSE (real_minus_onep (c_i_0)); + ASSERT_FALSE (real_minus_onep (c_i_1)); + ASSERT_FALSE (real_minus_onep (c_i_m1)); + ASSERT_FALSE (real_minus_onep (c_f_0)); + ASSERT_FALSE (real_minus_onep (c_f_1)); + ASSERT_TRUE (real_minus_onep (c_f_m1)); + + /* Test zerop. */ + ASSERT_TRUE (zerop (i_0)); + ASSERT_TRUE (zerop (wr_i_0)); + ASSERT_FALSE (zerop (i_1)); + ASSERT_FALSE (zerop (wr_i_1)); + ASSERT_FALSE (zerop (i_m1)); + ASSERT_FALSE (zerop (wr_i_m1)); + ASSERT_TRUE (zerop (f_0)); + ASSERT_TRUE (zerop (wr_f_0)); + ASSERT_FALSE (zerop (f_1)); + ASSERT_FALSE (zerop (wr_f_1)); + ASSERT_FALSE (zerop (f_m1)); + ASSERT_FALSE (zerop (wr_f_m1)); + ASSERT_TRUE (zerop (c_i_0)); + ASSERT_FALSE (zerop (c_i_1)); + ASSERT_FALSE (zerop (c_i_m1)); + ASSERT_TRUE (zerop (c_f_0)); + ASSERT_FALSE (zerop (c_f_1)); + ASSERT_FALSE (zerop (c_f_m1)); + + /* Test tree_expr_nonnegative_p. */ + ASSERT_TRUE (tree_expr_nonnegative_p (i_0)); + ASSERT_TRUE (tree_expr_nonnegative_p (wr_i_0)); + ASSERT_TRUE (tree_expr_nonnegative_p (i_1)); + ASSERT_TRUE (tree_expr_nonnegative_p (wr_i_1)); + ASSERT_FALSE (tree_expr_nonnegative_p (i_m1)); + ASSERT_FALSE (tree_expr_nonnegative_p (wr_i_m1)); + ASSERT_TRUE (tree_expr_nonnegative_p (f_0)); + ASSERT_TRUE (tree_expr_nonnegative_p (wr_f_0)); + ASSERT_TRUE (tree_expr_nonnegative_p (f_1)); + ASSERT_TRUE (tree_expr_nonnegative_p (wr_f_1)); + ASSERT_FALSE (tree_expr_nonnegative_p (f_m1)); + ASSERT_FALSE (tree_expr_nonnegative_p (wr_f_m1)); + ASSERT_FALSE (tree_expr_nonnegative_p (c_i_0)); + ASSERT_FALSE (tree_expr_nonnegative_p (c_i_1)); + ASSERT_FALSE (tree_expr_nonnegative_p (c_i_m1)); + ASSERT_FALSE (tree_expr_nonnegative_p (c_f_0)); + ASSERT_FALSE (tree_expr_nonnegative_p (c_f_1)); + ASSERT_FALSE (tree_expr_nonnegative_p (c_f_m1)); + + /* Test tree_expr_nonzero_p. */ + ASSERT_FALSE (tree_expr_nonzero_p (i_0)); + ASSERT_FALSE (tree_expr_nonzero_p (wr_i_0)); + ASSERT_TRUE (tree_expr_nonzero_p (i_1)); + ASSERT_TRUE (tree_expr_nonzero_p (wr_i_1)); + ASSERT_TRUE (tree_expr_nonzero_p (i_m1)); + ASSERT_TRUE (tree_expr_nonzero_p (wr_i_m1)); + + /* Test integer_valued_real_p. */ + ASSERT_FALSE (integer_valued_real_p (i_0)); + ASSERT_TRUE (integer_valued_real_p (f_0)); + ASSERT_TRUE (integer_valued_real_p (wr_f_0)); + ASSERT_TRUE (integer_valued_real_p (f_1)); + ASSERT_TRUE (integer_valued_real_p (wr_f_1)); + + /* Test integer_pow2p. */ + ASSERT_FALSE (integer_pow2p (i_0)); + ASSERT_TRUE (integer_pow2p (i_1)); + ASSERT_TRUE (integer_pow2p (wr_i_1)); + + /* Test uniform_integer_cst_p. */ + ASSERT_TRUE (uniform_integer_cst_p (i_0)); + ASSERT_TRUE (uniform_integer_cst_p (wr_i_0)); + ASSERT_TRUE (uniform_integer_cst_p (i_1)); + ASSERT_TRUE (uniform_integer_cst_p (wr_i_1)); + ASSERT_TRUE (uniform_integer_cst_p (i_m1)); + ASSERT_TRUE (uniform_integer_cst_p (wr_i_m1)); + ASSERT_FALSE (uniform_integer_cst_p (f_0)); + ASSERT_FALSE (uniform_integer_cst_p (wr_f_0)); + ASSERT_FALSE (uniform_integer_cst_p (f_1)); + ASSERT_FALSE (uniform_integer_cst_p (wr_f_1)); + ASSERT_FALSE (uniform_integer_cst_p (f_m1)); + ASSERT_FALSE (uniform_integer_cst_p (wr_f_m1)); + ASSERT_FALSE (uniform_integer_cst_p (c_i_0)); + ASSERT_FALSE (uniform_integer_cst_p (c_i_1)); + ASSERT_FALSE (uniform_integer_cst_p (c_i_m1)); + ASSERT_FALSE (uniform_integer_cst_p (c_f_0)); + ASSERT_FALSE (uniform_integer_cst_p (c_f_1)); + ASSERT_FALSE (uniform_integer_cst_p (c_f_m1)); +} + /* Check that string escaping works correctly. */ static void @@ -15199,6 +15574,7 @@ tree_c_tests () test_labels (); test_vector_cst_patterns (); test_location_wrappers (); + test_predicates (); test_escaped_strings (); } |