138fd1498Szrj /* Perform -*- C++ -*- constant expression evaluation, including calls to
238fd1498Szrj constexpr functions. These routines are used both during actual parsing
338fd1498Szrj and during the instantiation of template functions.
438fd1498Szrj
538fd1498Szrj Copyright (C) 1998-2018 Free Software Foundation, Inc.
638fd1498Szrj
738fd1498Szrj This file is part of GCC.
838fd1498Szrj
938fd1498Szrj GCC is free software; you can redistribute it and/or modify it
1038fd1498Szrj under the terms of the GNU General Public License as published by
1138fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
1238fd1498Szrj any later version.
1338fd1498Szrj
1438fd1498Szrj GCC is distributed in the hope that it will be useful, but
1538fd1498Szrj WITHOUT ANY WARRANTY; without even the implied warranty of
1638fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1738fd1498Szrj General Public License for more details.
1838fd1498Szrj
1938fd1498Szrj You should have received a copy of the GNU General Public License
2038fd1498Szrj along with GCC; see the file COPYING3. If not see
2138fd1498Szrj <http://www.gnu.org/licenses/>. */
2238fd1498Szrj
2338fd1498Szrj #include "config.h"
2438fd1498Szrj #include "system.h"
2538fd1498Szrj #include "coretypes.h"
2638fd1498Szrj #include "cp-tree.h"
2738fd1498Szrj #include "varasm.h"
2838fd1498Szrj #include "c-family/c-objc.h"
2938fd1498Szrj #include "tree-iterator.h"
3038fd1498Szrj #include "gimplify.h"
3138fd1498Szrj #include "builtins.h"
3238fd1498Szrj #include "tree-inline.h"
3338fd1498Szrj #include "ubsan.h"
3438fd1498Szrj #include "gimple-fold.h"
3538fd1498Szrj #include "timevar.h"
3638fd1498Szrj
3738fd1498Szrj static bool verify_constant (tree, bool, bool *, bool *);
3838fd1498Szrj #define VERIFY_CONSTANT(X) \
3938fd1498Szrj do { \
4038fd1498Szrj if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \
4138fd1498Szrj return t; \
4238fd1498Szrj } while (0)
4338fd1498Szrj
4438fd1498Szrj /* Returns true iff FUN is an instantiation of a constexpr function
4538fd1498Szrj template or a defaulted constexpr function. */
4638fd1498Szrj
4738fd1498Szrj bool
is_instantiation_of_constexpr(tree fun)4838fd1498Szrj is_instantiation_of_constexpr (tree fun)
4938fd1498Szrj {
5038fd1498Szrj return ((DECL_TEMPLOID_INSTANTIATION (fun)
5138fd1498Szrj && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)))
5238fd1498Szrj || (DECL_DEFAULTED_FN (fun)
5338fd1498Szrj && DECL_DECLARED_CONSTEXPR_P (fun)));
5438fd1498Szrj }
5538fd1498Szrj
5638fd1498Szrj /* Return true if T is a literal type. */
5738fd1498Szrj
5838fd1498Szrj bool
literal_type_p(tree t)5938fd1498Szrj literal_type_p (tree t)
6038fd1498Szrj {
6138fd1498Szrj if (SCALAR_TYPE_P (t)
6238fd1498Szrj || VECTOR_TYPE_P (t)
6338fd1498Szrj || TREE_CODE (t) == REFERENCE_TYPE
6438fd1498Szrj || (VOID_TYPE_P (t) && cxx_dialect >= cxx14))
6538fd1498Szrj return true;
6638fd1498Szrj if (CLASS_TYPE_P (t))
6738fd1498Szrj {
6838fd1498Szrj t = complete_type (t);
6938fd1498Szrj gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
7038fd1498Szrj return CLASSTYPE_LITERAL_P (t);
7138fd1498Szrj }
7238fd1498Szrj if (TREE_CODE (t) == ARRAY_TYPE)
7338fd1498Szrj return literal_type_p (strip_array_types (t));
7438fd1498Szrj return false;
7538fd1498Szrj }
7638fd1498Szrj
7738fd1498Szrj /* If DECL is a variable declared `constexpr', require its type
7838fd1498Szrj be literal. Return error_mark_node if we give an error, the
7938fd1498Szrj DECL otherwise. */
8038fd1498Szrj
8138fd1498Szrj tree
ensure_literal_type_for_constexpr_object(tree decl)8238fd1498Szrj ensure_literal_type_for_constexpr_object (tree decl)
8338fd1498Szrj {
8438fd1498Szrj tree type = TREE_TYPE (decl);
8538fd1498Szrj if (VAR_P (decl)
8638fd1498Szrj && (DECL_DECLARED_CONSTEXPR_P (decl)
8738fd1498Szrj || var_in_constexpr_fn (decl))
8838fd1498Szrj && !processing_template_decl)
8938fd1498Szrj {
9038fd1498Szrj tree stype = strip_array_types (type);
9138fd1498Szrj if (CLASS_TYPE_P (stype) && !COMPLETE_TYPE_P (complete_type (stype)))
9238fd1498Szrj /* Don't complain here, we'll complain about incompleteness
9338fd1498Szrj when we try to initialize the variable. */;
9438fd1498Szrj else if (!literal_type_p (type))
9538fd1498Szrj {
9638fd1498Szrj if (DECL_DECLARED_CONSTEXPR_P (decl))
9738fd1498Szrj {
9838fd1498Szrj error ("the type %qT of %<constexpr%> variable %qD "
9938fd1498Szrj "is not literal", type, decl);
10038fd1498Szrj explain_non_literal_class (type);
10138fd1498Szrj decl = error_mark_node;
10238fd1498Szrj }
10338fd1498Szrj else
10438fd1498Szrj {
10538fd1498Szrj if (!is_instantiation_of_constexpr (current_function_decl))
10638fd1498Szrj {
10738fd1498Szrj error ("variable %qD of non-literal type %qT in %<constexpr%> "
10838fd1498Szrj "function", decl, type);
10938fd1498Szrj explain_non_literal_class (type);
11038fd1498Szrj decl = error_mark_node;
11138fd1498Szrj }
11238fd1498Szrj cp_function_chain->invalid_constexpr = true;
11338fd1498Szrj }
11438fd1498Szrj }
11538fd1498Szrj else if (DECL_DECLARED_CONSTEXPR_P (decl)
11638fd1498Szrj && variably_modified_type_p (type, NULL_TREE))
11738fd1498Szrj {
11838fd1498Szrj error ("%<constexpr%> variable %qD has variably-modified type %qT",
11938fd1498Szrj decl, type);
12038fd1498Szrj decl = error_mark_node;
12138fd1498Szrj }
12238fd1498Szrj }
12338fd1498Szrj return decl;
12438fd1498Szrj }
12538fd1498Szrj
12638fd1498Szrj /* Representation of entries in the constexpr function definition table. */
12738fd1498Szrj
12838fd1498Szrj struct GTY((for_user)) constexpr_fundef {
12938fd1498Szrj tree decl;
13038fd1498Szrj tree body;
13138fd1498Szrj };
13238fd1498Szrj
13338fd1498Szrj struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
13438fd1498Szrj {
13538fd1498Szrj static hashval_t hash (constexpr_fundef *);
13638fd1498Szrj static bool equal (constexpr_fundef *, constexpr_fundef *);
13738fd1498Szrj };
13838fd1498Szrj
13938fd1498Szrj /* This table holds all constexpr function definitions seen in
14038fd1498Szrj the current translation unit. */
14138fd1498Szrj
14238fd1498Szrj static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table;
14338fd1498Szrj
14438fd1498Szrj /* Utility function used for managing the constexpr function table.
14538fd1498Szrj Return true if the entries pointed to by P and Q are for the
14638fd1498Szrj same constexpr function. */
14738fd1498Szrj
14838fd1498Szrj inline bool
equal(constexpr_fundef * lhs,constexpr_fundef * rhs)14938fd1498Szrj constexpr_fundef_hasher::equal (constexpr_fundef *lhs, constexpr_fundef *rhs)
15038fd1498Szrj {
15138fd1498Szrj return lhs->decl == rhs->decl;
15238fd1498Szrj }
15338fd1498Szrj
15438fd1498Szrj /* Utility function used for managing the constexpr function table.
15538fd1498Szrj Return a hash value for the entry pointed to by Q. */
15638fd1498Szrj
15738fd1498Szrj inline hashval_t
hash(constexpr_fundef * fundef)15838fd1498Szrj constexpr_fundef_hasher::hash (constexpr_fundef *fundef)
15938fd1498Szrj {
16038fd1498Szrj return DECL_UID (fundef->decl);
16138fd1498Szrj }
16238fd1498Szrj
16338fd1498Szrj /* Return a previously saved definition of function FUN. */
16438fd1498Szrj
16538fd1498Szrj static constexpr_fundef *
retrieve_constexpr_fundef(tree fun)16638fd1498Szrj retrieve_constexpr_fundef (tree fun)
16738fd1498Szrj {
16838fd1498Szrj constexpr_fundef fundef = { NULL, NULL };
16938fd1498Szrj if (constexpr_fundef_table == NULL)
17038fd1498Szrj return NULL;
17138fd1498Szrj
17238fd1498Szrj fundef.decl = fun;
17338fd1498Szrj return constexpr_fundef_table->find (&fundef);
17438fd1498Szrj }
17538fd1498Szrj
17638fd1498Szrj /* Check whether the parameter and return types of FUN are valid for a
17738fd1498Szrj constexpr function, and complain if COMPLAIN. */
17838fd1498Szrj
17938fd1498Szrj bool
is_valid_constexpr_fn(tree fun,bool complain)18038fd1498Szrj is_valid_constexpr_fn (tree fun, bool complain)
18138fd1498Szrj {
18238fd1498Szrj bool ret = true;
18338fd1498Szrj
18438fd1498Szrj if (DECL_INHERITED_CTOR (fun)
18538fd1498Szrj && TREE_CODE (fun) == TEMPLATE_DECL)
18638fd1498Szrj {
18738fd1498Szrj ret = false;
18838fd1498Szrj if (complain)
18938fd1498Szrj error ("inherited constructor %qD is not %<constexpr%>",
19038fd1498Szrj DECL_INHERITED_CTOR (fun));
19138fd1498Szrj }
19238fd1498Szrj else
19338fd1498Szrj {
19438fd1498Szrj for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
19538fd1498Szrj parm != NULL_TREE; parm = TREE_CHAIN (parm))
19638fd1498Szrj if (!literal_type_p (TREE_TYPE (parm)))
19738fd1498Szrj {
19838fd1498Szrj ret = false;
19938fd1498Szrj if (complain)
20038fd1498Szrj {
20138fd1498Szrj error ("invalid type for parameter %d of %<constexpr%> "
20238fd1498Szrj "function %q+#D", DECL_PARM_INDEX (parm), fun);
20338fd1498Szrj explain_non_literal_class (TREE_TYPE (parm));
20438fd1498Szrj }
20538fd1498Szrj }
20638fd1498Szrj }
20738fd1498Szrj
20838fd1498Szrj if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun)) && cxx_dialect < cxx17)
20938fd1498Szrj {
21038fd1498Szrj ret = false;
21138fd1498Szrj if (complain)
21238fd1498Szrj inform (DECL_SOURCE_LOCATION (fun),
21338fd1498Szrj "lambdas are implicitly %<constexpr%> only in C++17 and later");
21438fd1498Szrj }
21538fd1498Szrj else if (!DECL_CONSTRUCTOR_P (fun))
21638fd1498Szrj {
21738fd1498Szrj tree rettype = TREE_TYPE (TREE_TYPE (fun));
21838fd1498Szrj if (!literal_type_p (rettype))
21938fd1498Szrj {
22038fd1498Szrj ret = false;
22138fd1498Szrj if (complain)
22238fd1498Szrj {
22338fd1498Szrj error ("invalid return type %qT of %<constexpr%> function %q+D",
22438fd1498Szrj rettype, fun);
22538fd1498Szrj explain_non_literal_class (rettype);
22638fd1498Szrj }
22738fd1498Szrj }
22838fd1498Szrj
22938fd1498Szrj /* C++14 DR 1684 removed this restriction. */
23038fd1498Szrj if (cxx_dialect < cxx14
23138fd1498Szrj && DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
23238fd1498Szrj && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun)))
23338fd1498Szrj {
23438fd1498Szrj ret = false;
23538fd1498Szrj if (complain
23638fd1498Szrj && pedwarn (DECL_SOURCE_LOCATION (fun), OPT_Wpedantic,
23738fd1498Szrj "enclosing class of %<constexpr%> non-static member "
23838fd1498Szrj "function %q+#D is not a literal type", fun))
23938fd1498Szrj explain_non_literal_class (DECL_CONTEXT (fun));
24038fd1498Szrj }
24138fd1498Szrj }
24238fd1498Szrj else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)))
24338fd1498Szrj {
24438fd1498Szrj ret = false;
24538fd1498Szrj if (complain)
24638fd1498Szrj error ("%q#T has virtual base classes", DECL_CONTEXT (fun));
24738fd1498Szrj }
24838fd1498Szrj
24938fd1498Szrj return ret;
25038fd1498Szrj }
25138fd1498Szrj
25238fd1498Szrj /* Subroutine of build_data_member_initialization. MEMBER is a COMPONENT_REF
25338fd1498Szrj for a member of an anonymous aggregate, INIT is the initializer for that
25438fd1498Szrj member, and VEC_OUTER is the vector of constructor elements for the class
25538fd1498Szrj whose constructor we are processing. Add the initializer to the vector
25638fd1498Szrj and return true to indicate success. */
25738fd1498Szrj
25838fd1498Szrj static bool
build_anon_member_initialization(tree member,tree init,vec<constructor_elt,va_gc> ** vec_outer)25938fd1498Szrj build_anon_member_initialization (tree member, tree init,
26038fd1498Szrj vec<constructor_elt, va_gc> **vec_outer)
26138fd1498Szrj {
26238fd1498Szrj /* MEMBER presents the relevant fields from the inside out, but we need
26338fd1498Szrj to build up the initializer from the outside in so that we can reuse
26438fd1498Szrj previously built CONSTRUCTORs if this is, say, the second field in an
26538fd1498Szrj anonymous struct. So we use a vec as a stack. */
26638fd1498Szrj auto_vec<tree, 2> fields;
26738fd1498Szrj do
26838fd1498Szrj {
26938fd1498Szrj fields.safe_push (TREE_OPERAND (member, 1));
27038fd1498Szrj member = TREE_OPERAND (member, 0);
27138fd1498Szrj }
27238fd1498Szrj while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
27338fd1498Szrj && TREE_CODE (member) == COMPONENT_REF);
27438fd1498Szrj
27538fd1498Szrj /* VEC has the constructor elements vector for the context of FIELD.
27638fd1498Szrj If FIELD is an anonymous aggregate, we will push inside it. */
27738fd1498Szrj vec<constructor_elt, va_gc> **vec = vec_outer;
27838fd1498Szrj tree field;
27938fd1498Szrj while (field = fields.pop(),
28038fd1498Szrj ANON_AGGR_TYPE_P (TREE_TYPE (field)))
28138fd1498Szrj {
28238fd1498Szrj tree ctor;
28338fd1498Szrj /* If there is already an outer constructor entry for the anonymous
28438fd1498Szrj aggregate FIELD, use it; otherwise, insert one. */
28538fd1498Szrj if (vec_safe_is_empty (*vec)
28638fd1498Szrj || (*vec)->last().index != field)
28738fd1498Szrj {
28838fd1498Szrj ctor = build_constructor (TREE_TYPE (field), NULL);
28938fd1498Szrj CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
29038fd1498Szrj }
29138fd1498Szrj else
29238fd1498Szrj ctor = (*vec)->last().value;
29338fd1498Szrj vec = &CONSTRUCTOR_ELTS (ctor);
29438fd1498Szrj }
29538fd1498Szrj
29638fd1498Szrj /* Now we're at the innermost field, the one that isn't an anonymous
29738fd1498Szrj aggregate. Add its initializer to the CONSTRUCTOR and we're done. */
29838fd1498Szrj gcc_assert (fields.is_empty());
29938fd1498Szrj CONSTRUCTOR_APPEND_ELT (*vec, field, init);
30038fd1498Szrj
30138fd1498Szrj return true;
30238fd1498Szrj }
30338fd1498Szrj
30438fd1498Szrj /* Subroutine of build_constexpr_constructor_member_initializers.
30538fd1498Szrj The expression tree T represents a data member initialization
30638fd1498Szrj in a (constexpr) constructor definition. Build a pairing of
30738fd1498Szrj the data member with its initializer, and prepend that pair
30838fd1498Szrj to the existing initialization pair INITS. */
30938fd1498Szrj
31038fd1498Szrj static bool
build_data_member_initialization(tree t,vec<constructor_elt,va_gc> ** vec)31138fd1498Szrj build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
31238fd1498Szrj {
31338fd1498Szrj tree member, init;
31438fd1498Szrj if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
31538fd1498Szrj t = TREE_OPERAND (t, 0);
31638fd1498Szrj if (TREE_CODE (t) == EXPR_STMT)
31738fd1498Szrj t = TREE_OPERAND (t, 0);
31838fd1498Szrj if (t == error_mark_node)
31938fd1498Szrj return false;
32038fd1498Szrj if (TREE_CODE (t) == STATEMENT_LIST)
32138fd1498Szrj {
32238fd1498Szrj tree_stmt_iterator i;
32338fd1498Szrj for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
32438fd1498Szrj {
32538fd1498Szrj if (! build_data_member_initialization (tsi_stmt (i), vec))
32638fd1498Szrj return false;
32738fd1498Szrj }
32838fd1498Szrj return true;
32938fd1498Szrj }
33038fd1498Szrj if (TREE_CODE (t) == CLEANUP_STMT)
33138fd1498Szrj {
33238fd1498Szrj /* We can't see a CLEANUP_STMT in a constructor for a literal class,
33338fd1498Szrj but we can in a constexpr constructor for a non-literal class. Just
33438fd1498Szrj ignore it; either all the initialization will be constant, in which
33538fd1498Szrj case the cleanup can't run, or it can't be constexpr.
33638fd1498Szrj Still recurse into CLEANUP_BODY. */
33738fd1498Szrj return build_data_member_initialization (CLEANUP_BODY (t), vec);
33838fd1498Szrj }
33938fd1498Szrj if (TREE_CODE (t) == CONVERT_EXPR)
34038fd1498Szrj t = TREE_OPERAND (t, 0);
34138fd1498Szrj if (TREE_CODE (t) == INIT_EXPR
34238fd1498Szrj /* vptr initialization shows up as a MODIFY_EXPR. In C++14 we only
34338fd1498Szrj use what this function builds for cx_check_missing_mem_inits, and
34438fd1498Szrj assignment in the ctor body doesn't count. */
34538fd1498Szrj || (cxx_dialect < cxx14 && TREE_CODE (t) == MODIFY_EXPR))
34638fd1498Szrj {
34738fd1498Szrj member = TREE_OPERAND (t, 0);
34838fd1498Szrj init = break_out_target_exprs (TREE_OPERAND (t, 1));
34938fd1498Szrj }
35038fd1498Szrj else if (TREE_CODE (t) == CALL_EXPR)
35138fd1498Szrj {
35238fd1498Szrj tree fn = get_callee_fndecl (t);
35338fd1498Szrj if (!fn || !DECL_CONSTRUCTOR_P (fn))
35438fd1498Szrj /* We're only interested in calls to subobject constructors. */
35538fd1498Szrj return true;
35638fd1498Szrj member = CALL_EXPR_ARG (t, 0);
35738fd1498Szrj /* We don't use build_cplus_new here because it complains about
35838fd1498Szrj abstract bases. Leaving the call unwrapped means that it has the
35938fd1498Szrj wrong type, but cxx_eval_constant_expression doesn't care. */
36038fd1498Szrj init = break_out_target_exprs (t);
36138fd1498Szrj }
36238fd1498Szrj else if (TREE_CODE (t) == BIND_EXPR)
36338fd1498Szrj return build_data_member_initialization (BIND_EXPR_BODY (t), vec);
36438fd1498Szrj else
36538fd1498Szrj /* Don't add anything else to the CONSTRUCTOR. */
36638fd1498Szrj return true;
36738fd1498Szrj if (INDIRECT_REF_P (member))
36838fd1498Szrj member = TREE_OPERAND (member, 0);
36938fd1498Szrj if (TREE_CODE (member) == NOP_EXPR)
37038fd1498Szrj {
37138fd1498Szrj tree op = member;
37238fd1498Szrj STRIP_NOPS (op);
37338fd1498Szrj if (TREE_CODE (op) == ADDR_EXPR)
37438fd1498Szrj {
37538fd1498Szrj gcc_assert (same_type_ignoring_top_level_qualifiers_p
37638fd1498Szrj (TREE_TYPE (TREE_TYPE (op)),
37738fd1498Szrj TREE_TYPE (TREE_TYPE (member))));
37838fd1498Szrj /* Initializing a cv-qualified member; we need to look through
37938fd1498Szrj the const_cast. */
38038fd1498Szrj member = op;
38138fd1498Szrj }
38238fd1498Szrj else if (op == current_class_ptr
38338fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
38438fd1498Szrj (TREE_TYPE (TREE_TYPE (member)),
38538fd1498Szrj current_class_type)))
38638fd1498Szrj /* Delegating constructor. */
38738fd1498Szrj member = op;
38838fd1498Szrj else
38938fd1498Szrj {
39038fd1498Szrj /* This is an initializer for an empty base; keep it for now so
39138fd1498Szrj we can check it in cxx_eval_bare_aggregate. */
39238fd1498Szrj gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
39338fd1498Szrj }
39438fd1498Szrj }
39538fd1498Szrj if (TREE_CODE (member) == ADDR_EXPR)
39638fd1498Szrj member = TREE_OPERAND (member, 0);
39738fd1498Szrj if (TREE_CODE (member) == COMPONENT_REF)
39838fd1498Szrj {
39938fd1498Szrj tree aggr = TREE_OPERAND (member, 0);
40038fd1498Szrj if (TREE_CODE (aggr) == VAR_DECL)
40138fd1498Szrj /* Initializing a local variable, don't add anything. */
40238fd1498Szrj return true;
40338fd1498Szrj if (TREE_CODE (aggr) != COMPONENT_REF)
40438fd1498Szrj /* Normal member initialization. */
40538fd1498Szrj member = TREE_OPERAND (member, 1);
40638fd1498Szrj else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
40738fd1498Szrj /* Initializing a member of an anonymous union. */
40838fd1498Szrj return build_anon_member_initialization (member, init, vec);
40938fd1498Szrj else
41038fd1498Szrj /* We're initializing a vtable pointer in a base. Leave it as
41138fd1498Szrj COMPONENT_REF so we remember the path to get to the vfield. */
41238fd1498Szrj gcc_assert (TREE_TYPE (member) == vtbl_ptr_type_node);
41338fd1498Szrj }
41438fd1498Szrj
41538fd1498Szrj /* Value-initialization can produce multiple initializers for the
41638fd1498Szrj same field; use the last one. */
41738fd1498Szrj if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member)
41838fd1498Szrj (*vec)->last().value = init;
41938fd1498Szrj else
42038fd1498Szrj CONSTRUCTOR_APPEND_ELT (*vec, member, init);
42138fd1498Szrj return true;
42238fd1498Szrj }
42338fd1498Szrj
42438fd1498Szrj /* Subroutine of check_constexpr_ctor_body_1 and constexpr_fn_retval.
42538fd1498Szrj In C++11 mode checks that the TYPE_DECLs in the BIND_EXPR_VARS of a
42638fd1498Szrj BIND_EXPR conform to 7.1.5/3/4 on typedef and alias declarations. */
42738fd1498Szrj
42838fd1498Szrj static bool
check_constexpr_bind_expr_vars(tree t)42938fd1498Szrj check_constexpr_bind_expr_vars (tree t)
43038fd1498Szrj {
43138fd1498Szrj gcc_assert (TREE_CODE (t) == BIND_EXPR);
43238fd1498Szrj
43338fd1498Szrj for (tree var = BIND_EXPR_VARS (t); var; var = DECL_CHAIN (var))
43438fd1498Szrj if (TREE_CODE (var) == TYPE_DECL
43538fd1498Szrj && DECL_IMPLICIT_TYPEDEF_P (var)
43638fd1498Szrj && !LAMBDA_TYPE_P (TREE_TYPE (var)))
43738fd1498Szrj return false;
43838fd1498Szrj return true;
43938fd1498Szrj }
44038fd1498Szrj
44138fd1498Szrj /* Subroutine of check_constexpr_ctor_body. */
44238fd1498Szrj
44338fd1498Szrj static bool
check_constexpr_ctor_body_1(tree last,tree list)44438fd1498Szrj check_constexpr_ctor_body_1 (tree last, tree list)
44538fd1498Szrj {
44638fd1498Szrj switch (TREE_CODE (list))
44738fd1498Szrj {
44838fd1498Szrj case DECL_EXPR:
44938fd1498Szrj if (TREE_CODE (DECL_EXPR_DECL (list)) == USING_DECL
45038fd1498Szrj || TREE_CODE (DECL_EXPR_DECL (list)) == TYPE_DECL)
45138fd1498Szrj return true;
45238fd1498Szrj return false;
45338fd1498Szrj
45438fd1498Szrj case CLEANUP_POINT_EXPR:
45538fd1498Szrj return check_constexpr_ctor_body (last, TREE_OPERAND (list, 0),
45638fd1498Szrj /*complain=*/false);
45738fd1498Szrj
45838fd1498Szrj case BIND_EXPR:
45938fd1498Szrj if (!check_constexpr_bind_expr_vars (list)
46038fd1498Szrj || !check_constexpr_ctor_body (last, BIND_EXPR_BODY (list),
46138fd1498Szrj /*complain=*/false))
46238fd1498Szrj return false;
46338fd1498Szrj return true;
46438fd1498Szrj
46538fd1498Szrj case USING_STMT:
46638fd1498Szrj case STATIC_ASSERT:
46738fd1498Szrj case DEBUG_BEGIN_STMT:
46838fd1498Szrj return true;
46938fd1498Szrj
47038fd1498Szrj default:
47138fd1498Szrj return false;
47238fd1498Szrj }
47338fd1498Szrj }
47438fd1498Szrj
47538fd1498Szrj /* Make sure that there are no statements after LAST in the constructor
47638fd1498Szrj body represented by LIST. */
47738fd1498Szrj
47838fd1498Szrj bool
check_constexpr_ctor_body(tree last,tree list,bool complain)47938fd1498Szrj check_constexpr_ctor_body (tree last, tree list, bool complain)
48038fd1498Szrj {
48138fd1498Szrj /* C++14 doesn't require a constexpr ctor to have an empty body. */
48238fd1498Szrj if (cxx_dialect >= cxx14)
48338fd1498Szrj return true;
48438fd1498Szrj
48538fd1498Szrj bool ok = true;
48638fd1498Szrj if (TREE_CODE (list) == STATEMENT_LIST)
48738fd1498Szrj {
48838fd1498Szrj tree_stmt_iterator i = tsi_last (list);
48938fd1498Szrj for (; !tsi_end_p (i); tsi_prev (&i))
49038fd1498Szrj {
49138fd1498Szrj tree t = tsi_stmt (i);
49238fd1498Szrj if (t == last)
49338fd1498Szrj break;
49438fd1498Szrj if (!check_constexpr_ctor_body_1 (last, t))
49538fd1498Szrj {
49638fd1498Szrj ok = false;
49738fd1498Szrj break;
49838fd1498Szrj }
49938fd1498Szrj }
50038fd1498Szrj }
50138fd1498Szrj else if (list != last
50238fd1498Szrj && !check_constexpr_ctor_body_1 (last, list))
50338fd1498Szrj ok = false;
50438fd1498Szrj if (!ok)
50538fd1498Szrj {
50638fd1498Szrj if (complain)
50738fd1498Szrj error ("%<constexpr%> constructor does not have empty body");
50838fd1498Szrj DECL_DECLARED_CONSTEXPR_P (current_function_decl) = false;
50938fd1498Szrj }
51038fd1498Szrj return ok;
51138fd1498Szrj }
51238fd1498Szrj
51338fd1498Szrj /* V is a vector of constructor elements built up for the base and member
51438fd1498Szrj initializers of a constructor for TYPE. They need to be in increasing
51538fd1498Szrj offset order, which they might not be yet if TYPE has a primary base
51638fd1498Szrj which is not first in the base-clause or a vptr and at least one base
51738fd1498Szrj all of which are non-primary. */
51838fd1498Szrj
51938fd1498Szrj static vec<constructor_elt, va_gc> *
sort_constexpr_mem_initializers(tree type,vec<constructor_elt,va_gc> * v)52038fd1498Szrj sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v)
52138fd1498Szrj {
52238fd1498Szrj tree pri = CLASSTYPE_PRIMARY_BINFO (type);
52338fd1498Szrj tree field_type;
52438fd1498Szrj unsigned i;
52538fd1498Szrj constructor_elt *ce;
52638fd1498Szrj
52738fd1498Szrj if (pri)
52838fd1498Szrj field_type = BINFO_TYPE (pri);
52938fd1498Szrj else if (TYPE_CONTAINS_VPTR_P (type))
53038fd1498Szrj field_type = vtbl_ptr_type_node;
53138fd1498Szrj else
53238fd1498Szrj return v;
53338fd1498Szrj
53438fd1498Szrj /* Find the element for the primary base or vptr and move it to the
53538fd1498Szrj beginning of the vec. */
53638fd1498Szrj for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
53738fd1498Szrj if (TREE_TYPE (ce->index) == field_type)
53838fd1498Szrj break;
53938fd1498Szrj
54038fd1498Szrj if (i > 0 && i < vec_safe_length (v))
54138fd1498Szrj {
54238fd1498Szrj vec<constructor_elt, va_gc> &vref = *v;
54338fd1498Szrj constructor_elt elt = vref[i];
54438fd1498Szrj for (; i > 0; --i)
54538fd1498Szrj vref[i] = vref[i-1];
54638fd1498Szrj vref[0] = elt;
54738fd1498Szrj }
54838fd1498Szrj
54938fd1498Szrj return v;
55038fd1498Szrj }
55138fd1498Szrj
55238fd1498Szrj /* Build compile-time evalable representations of member-initializer list
55338fd1498Szrj for a constexpr constructor. */
55438fd1498Szrj
55538fd1498Szrj static tree
build_constexpr_constructor_member_initializers(tree type,tree body)55638fd1498Szrj build_constexpr_constructor_member_initializers (tree type, tree body)
55738fd1498Szrj {
55838fd1498Szrj vec<constructor_elt, va_gc> *vec = NULL;
55938fd1498Szrj bool ok = true;
56038fd1498Szrj while (true)
56138fd1498Szrj switch (TREE_CODE (body))
56238fd1498Szrj {
56338fd1498Szrj case MUST_NOT_THROW_EXPR:
56438fd1498Szrj case EH_SPEC_BLOCK:
56538fd1498Szrj body = TREE_OPERAND (body, 0);
56638fd1498Szrj break;
56738fd1498Szrj
56838fd1498Szrj case STATEMENT_LIST:
56938fd1498Szrj for (tree_stmt_iterator i = tsi_start (body);
57038fd1498Szrj !tsi_end_p (i); tsi_next (&i))
57138fd1498Szrj {
57238fd1498Szrj body = tsi_stmt (i);
57338fd1498Szrj if (TREE_CODE (body) == BIND_EXPR)
57438fd1498Szrj break;
57538fd1498Szrj }
57638fd1498Szrj break;
57738fd1498Szrj
57838fd1498Szrj case BIND_EXPR:
57938fd1498Szrj body = BIND_EXPR_BODY (body);
58038fd1498Szrj goto found;
58138fd1498Szrj
58238fd1498Szrj default:
58338fd1498Szrj gcc_unreachable ();
58438fd1498Szrj }
58538fd1498Szrj found:
58638fd1498Szrj if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
58738fd1498Szrj {
58838fd1498Szrj body = TREE_OPERAND (body, 0);
58938fd1498Szrj if (TREE_CODE (body) == EXPR_STMT)
59038fd1498Szrj body = TREE_OPERAND (body, 0);
59138fd1498Szrj if (TREE_CODE (body) == INIT_EXPR
59238fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
59338fd1498Szrj (TREE_TYPE (TREE_OPERAND (body, 0)),
59438fd1498Szrj current_class_type)))
59538fd1498Szrj {
59638fd1498Szrj /* Trivial copy. */
59738fd1498Szrj return TREE_OPERAND (body, 1);
59838fd1498Szrj }
59938fd1498Szrj ok = build_data_member_initialization (body, &vec);
60038fd1498Szrj }
60138fd1498Szrj else if (TREE_CODE (body) == STATEMENT_LIST)
60238fd1498Szrj {
60338fd1498Szrj tree_stmt_iterator i;
60438fd1498Szrj for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
60538fd1498Szrj {
60638fd1498Szrj ok = build_data_member_initialization (tsi_stmt (i), &vec);
60738fd1498Szrj if (!ok)
60838fd1498Szrj break;
60938fd1498Szrj }
61038fd1498Szrj }
61138fd1498Szrj else if (TREE_CODE (body) == TRY_BLOCK)
61238fd1498Szrj {
61338fd1498Szrj error ("body of %<constexpr%> constructor cannot be "
61438fd1498Szrj "a function-try-block");
61538fd1498Szrj return error_mark_node;
61638fd1498Szrj }
61738fd1498Szrj else if (EXPR_P (body))
61838fd1498Szrj ok = build_data_member_initialization (body, &vec);
61938fd1498Szrj else
62038fd1498Szrj gcc_assert (errorcount > 0);
62138fd1498Szrj if (ok)
62238fd1498Szrj {
62338fd1498Szrj if (vec_safe_length (vec) > 0)
62438fd1498Szrj {
62538fd1498Szrj /* In a delegating constructor, return the target. */
62638fd1498Szrj constructor_elt *ce = &(*vec)[0];
62738fd1498Szrj if (ce->index == current_class_ptr)
62838fd1498Szrj {
62938fd1498Szrj body = ce->value;
63038fd1498Szrj vec_free (vec);
63138fd1498Szrj return body;
63238fd1498Szrj }
63338fd1498Szrj }
63438fd1498Szrj vec = sort_constexpr_mem_initializers (type, vec);
63538fd1498Szrj return build_constructor (type, vec);
63638fd1498Szrj }
63738fd1498Szrj else
63838fd1498Szrj return error_mark_node;
63938fd1498Szrj }
64038fd1498Szrj
64138fd1498Szrj /* We have an expression tree T that represents a call, either CALL_EXPR
64238fd1498Szrj or AGGR_INIT_EXPR. If the call is lexically to a named function,
64338fd1498Szrj retrun the _DECL for that function. */
64438fd1498Szrj
64538fd1498Szrj static tree
get_function_named_in_call(tree t)64638fd1498Szrj get_function_named_in_call (tree t)
64738fd1498Szrj {
64838fd1498Szrj tree fun = cp_get_callee (t);
64938fd1498Szrj if (fun && TREE_CODE (fun) == ADDR_EXPR
65038fd1498Szrj && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL)
65138fd1498Szrj fun = TREE_OPERAND (fun, 0);
65238fd1498Szrj return fun;
65338fd1498Szrj }
65438fd1498Szrj
65538fd1498Szrj /* Subroutine of register_constexpr_fundef. BODY is the body of a function
65638fd1498Szrj declared to be constexpr, or a sub-statement thereof. Returns the
65738fd1498Szrj return value if suitable, error_mark_node for a statement not allowed in
65838fd1498Szrj a constexpr function, or NULL_TREE if no return value was found. */
65938fd1498Szrj
66038fd1498Szrj tree
constexpr_fn_retval(tree body)66138fd1498Szrj constexpr_fn_retval (tree body)
66238fd1498Szrj {
66338fd1498Szrj switch (TREE_CODE (body))
66438fd1498Szrj {
66538fd1498Szrj case STATEMENT_LIST:
66638fd1498Szrj {
66738fd1498Szrj tree_stmt_iterator i;
66838fd1498Szrj tree expr = NULL_TREE;
66938fd1498Szrj for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
67038fd1498Szrj {
67138fd1498Szrj tree s = constexpr_fn_retval (tsi_stmt (i));
67238fd1498Szrj if (s == error_mark_node)
67338fd1498Szrj return error_mark_node;
67438fd1498Szrj else if (s == NULL_TREE)
67538fd1498Szrj /* Keep iterating. */;
67638fd1498Szrj else if (expr)
67738fd1498Szrj /* Multiple return statements. */
67838fd1498Szrj return error_mark_node;
67938fd1498Szrj else
68038fd1498Szrj expr = s;
68138fd1498Szrj }
68238fd1498Szrj return expr;
68338fd1498Szrj }
68438fd1498Szrj
68538fd1498Szrj case RETURN_EXPR:
68638fd1498Szrj return break_out_target_exprs (TREE_OPERAND (body, 0));
68738fd1498Szrj
68838fd1498Szrj case DECL_EXPR:
68938fd1498Szrj {
69038fd1498Szrj tree decl = DECL_EXPR_DECL (body);
69138fd1498Szrj if (TREE_CODE (decl) == USING_DECL
69238fd1498Szrj /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */
69338fd1498Szrj || DECL_ARTIFICIAL (decl))
69438fd1498Szrj return NULL_TREE;
69538fd1498Szrj return error_mark_node;
69638fd1498Szrj }
69738fd1498Szrj
69838fd1498Szrj case CLEANUP_POINT_EXPR:
69938fd1498Szrj return constexpr_fn_retval (TREE_OPERAND (body, 0));
70038fd1498Szrj
70138fd1498Szrj case BIND_EXPR:
70238fd1498Szrj if (!check_constexpr_bind_expr_vars (body))
70338fd1498Szrj return error_mark_node;
70438fd1498Szrj return constexpr_fn_retval (BIND_EXPR_BODY (body));
70538fd1498Szrj
70638fd1498Szrj case USING_STMT:
70738fd1498Szrj case DEBUG_BEGIN_STMT:
70838fd1498Szrj return NULL_TREE;
70938fd1498Szrj
71038fd1498Szrj case CALL_EXPR:
71138fd1498Szrj {
71238fd1498Szrj tree fun = get_function_named_in_call (body);
71338fd1498Szrj if (fun != NULL_TREE
71438fd1498Szrj && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
71538fd1498Szrj return NULL_TREE;
71638fd1498Szrj }
71738fd1498Szrj /* Fallthru. */
71838fd1498Szrj
71938fd1498Szrj default:
72038fd1498Szrj return error_mark_node;
72138fd1498Szrj }
72238fd1498Szrj }
72338fd1498Szrj
72438fd1498Szrj /* Subroutine of register_constexpr_fundef. BODY is the DECL_SAVED_TREE of
72538fd1498Szrj FUN; do the necessary transformations to turn it into a single expression
72638fd1498Szrj that we can store in the hash table. */
72738fd1498Szrj
72838fd1498Szrj static tree
massage_constexpr_body(tree fun,tree body)72938fd1498Szrj massage_constexpr_body (tree fun, tree body)
73038fd1498Szrj {
73138fd1498Szrj if (DECL_CONSTRUCTOR_P (fun))
73238fd1498Szrj body = build_constexpr_constructor_member_initializers
73338fd1498Szrj (DECL_CONTEXT (fun), body);
73438fd1498Szrj else if (cxx_dialect < cxx14)
73538fd1498Szrj {
73638fd1498Szrj if (TREE_CODE (body) == EH_SPEC_BLOCK)
73738fd1498Szrj body = EH_SPEC_STMTS (body);
73838fd1498Szrj if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
73938fd1498Szrj body = TREE_OPERAND (body, 0);
74038fd1498Szrj body = constexpr_fn_retval (body);
74138fd1498Szrj }
74238fd1498Szrj return body;
74338fd1498Szrj }
74438fd1498Szrj
74538fd1498Szrj /* CTYPE is a type constructed from BODY. Return true if some
74638fd1498Szrj bases/fields are uninitialized, and complain if COMPLAIN. */
74738fd1498Szrj
74838fd1498Szrj static bool
cx_check_missing_mem_inits(tree ctype,tree body,bool complain)74938fd1498Szrj cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
75038fd1498Szrj {
75138fd1498Szrj unsigned nelts = 0;
75238fd1498Szrj
75338fd1498Szrj if (body)
75438fd1498Szrj {
75538fd1498Szrj if (TREE_CODE (body) != CONSTRUCTOR)
75638fd1498Szrj return false;
75738fd1498Szrj nelts = CONSTRUCTOR_NELTS (body);
75838fd1498Szrj }
75938fd1498Szrj tree field = TYPE_FIELDS (ctype);
76038fd1498Szrj
76138fd1498Szrj if (TREE_CODE (ctype) == UNION_TYPE)
76238fd1498Szrj {
76338fd1498Szrj if (nelts == 0 && next_initializable_field (field))
76438fd1498Szrj {
76538fd1498Szrj if (complain)
76638fd1498Szrj error ("%<constexpr%> constructor for union %qT must "
76738fd1498Szrj "initialize exactly one non-static data member", ctype);
76838fd1498Szrj return true;
76938fd1498Szrj }
77038fd1498Szrj return false;
77138fd1498Szrj }
77238fd1498Szrj
77338fd1498Szrj /* Iterate over the CONSTRUCTOR, checking any missing fields don't
77438fd1498Szrj need an explicit initialization. */
77538fd1498Szrj bool bad = false;
77638fd1498Szrj for (unsigned i = 0; i <= nelts; ++i)
77738fd1498Szrj {
77838fd1498Szrj tree index = NULL_TREE;
77938fd1498Szrj if (i < nelts)
78038fd1498Szrj {
78138fd1498Szrj index = CONSTRUCTOR_ELT (body, i)->index;
78238fd1498Szrj /* Skip base and vtable inits. */
78338fd1498Szrj if (TREE_CODE (index) != FIELD_DECL
78438fd1498Szrj || DECL_ARTIFICIAL (index))
78538fd1498Szrj continue;
78638fd1498Szrj }
78738fd1498Szrj
78838fd1498Szrj for (; field != index; field = DECL_CHAIN (field))
78938fd1498Szrj {
79038fd1498Szrj tree ftype;
79138fd1498Szrj if (TREE_CODE (field) != FIELD_DECL)
79238fd1498Szrj continue;
79338fd1498Szrj if (DECL_UNNAMED_BIT_FIELD (field))
79438fd1498Szrj continue;
79538fd1498Szrj if (DECL_ARTIFICIAL (field))
79638fd1498Szrj continue;
79738fd1498Szrj if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
79838fd1498Szrj {
79938fd1498Szrj /* Recurse to check the anonummous aggregate member. */
80038fd1498Szrj bad |= cx_check_missing_mem_inits
80138fd1498Szrj (TREE_TYPE (field), NULL_TREE, complain);
80238fd1498Szrj if (bad && !complain)
80338fd1498Szrj return true;
80438fd1498Szrj continue;
80538fd1498Szrj }
80638fd1498Szrj ftype = strip_array_types (TREE_TYPE (field));
80738fd1498Szrj if (type_has_constexpr_default_constructor (ftype))
80838fd1498Szrj {
80938fd1498Szrj /* It's OK to skip a member with a trivial constexpr ctor.
81038fd1498Szrj A constexpr ctor that isn't trivial should have been
81138fd1498Szrj added in by now. */
81238fd1498Szrj gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype)
81338fd1498Szrj || errorcount != 0);
81438fd1498Szrj continue;
81538fd1498Szrj }
81638fd1498Szrj if (!complain)
81738fd1498Szrj return true;
81838fd1498Szrj error ("member %qD must be initialized by mem-initializer "
81938fd1498Szrj "in %<constexpr%> constructor", field);
82038fd1498Szrj inform (DECL_SOURCE_LOCATION (field), "declared here");
82138fd1498Szrj bad = true;
82238fd1498Szrj }
82338fd1498Szrj if (field == NULL_TREE)
82438fd1498Szrj break;
82538fd1498Szrj
82638fd1498Szrj if (ANON_AGGR_TYPE_P (TREE_TYPE (index)))
82738fd1498Szrj {
82838fd1498Szrj /* Check the anonymous aggregate initializer is valid. */
82938fd1498Szrj bad |= cx_check_missing_mem_inits
83038fd1498Szrj (TREE_TYPE (index), CONSTRUCTOR_ELT (body, i)->value, complain);
83138fd1498Szrj if (bad && !complain)
83238fd1498Szrj return true;
83338fd1498Szrj }
83438fd1498Szrj field = DECL_CHAIN (field);
83538fd1498Szrj }
83638fd1498Szrj
83738fd1498Szrj return bad;
83838fd1498Szrj }
83938fd1498Szrj
84038fd1498Szrj /* We are processing the definition of the constexpr function FUN.
84138fd1498Szrj Check that its BODY fulfills the propriate requirements and
84238fd1498Szrj enter it in the constexpr function definition table.
84338fd1498Szrj For constructor BODY is actually the TREE_LIST of the
84438fd1498Szrj member-initializer list. */
84538fd1498Szrj
84638fd1498Szrj tree
register_constexpr_fundef(tree fun,tree body)84738fd1498Szrj register_constexpr_fundef (tree fun, tree body)
84838fd1498Szrj {
84938fd1498Szrj constexpr_fundef entry;
85038fd1498Szrj constexpr_fundef **slot;
85138fd1498Szrj
85238fd1498Szrj if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun)))
85338fd1498Szrj return NULL;
85438fd1498Szrj
85538fd1498Szrj tree massaged = massage_constexpr_body (fun, body);
85638fd1498Szrj if (massaged == NULL_TREE || massaged == error_mark_node)
85738fd1498Szrj {
85838fd1498Szrj if (!DECL_CONSTRUCTOR_P (fun))
85938fd1498Szrj error ("body of %<constexpr%> function %qD not a return-statement",
86038fd1498Szrj fun);
86138fd1498Szrj return NULL;
86238fd1498Szrj }
86338fd1498Szrj
86438fd1498Szrj if (!potential_rvalue_constant_expression (massaged))
86538fd1498Szrj {
86638fd1498Szrj if (!DECL_GENERATED_P (fun))
86738fd1498Szrj require_potential_rvalue_constant_expression (massaged);
86838fd1498Szrj return NULL;
86938fd1498Szrj }
87038fd1498Szrj
87138fd1498Szrj if (DECL_CONSTRUCTOR_P (fun)
87238fd1498Szrj && cx_check_missing_mem_inits (DECL_CONTEXT (fun),
87338fd1498Szrj massaged, !DECL_GENERATED_P (fun)))
87438fd1498Szrj return NULL;
87538fd1498Szrj
87638fd1498Szrj /* Create the constexpr function table if necessary. */
87738fd1498Szrj if (constexpr_fundef_table == NULL)
87838fd1498Szrj constexpr_fundef_table
87938fd1498Szrj = hash_table<constexpr_fundef_hasher>::create_ggc (101);
88038fd1498Szrj
88138fd1498Szrj entry.decl = fun;
88238fd1498Szrj entry.body = body;
88338fd1498Szrj slot = constexpr_fundef_table->find_slot (&entry, INSERT);
88438fd1498Szrj
88538fd1498Szrj gcc_assert (*slot == NULL);
88638fd1498Szrj *slot = ggc_alloc<constexpr_fundef> ();
88738fd1498Szrj **slot = entry;
88838fd1498Szrj
88938fd1498Szrj return fun;
89038fd1498Szrj }
89138fd1498Szrj
89238fd1498Szrj /* FUN is a non-constexpr function called in a context that requires a
89338fd1498Szrj constant expression. If it comes from a constexpr template, explain why
89438fd1498Szrj the instantiation isn't constexpr. */
89538fd1498Szrj
89638fd1498Szrj void
explain_invalid_constexpr_fn(tree fun)89738fd1498Szrj explain_invalid_constexpr_fn (tree fun)
89838fd1498Szrj {
89938fd1498Szrj static hash_set<tree> *diagnosed;
90038fd1498Szrj tree body;
90138fd1498Szrj location_t save_loc;
90238fd1498Szrj /* Only diagnose defaulted functions, lambdas, or instantiations. */
90338fd1498Szrj if (!DECL_DEFAULTED_FN (fun)
90438fd1498Szrj && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))
90538fd1498Szrj && !is_instantiation_of_constexpr (fun))
90638fd1498Szrj return;
90738fd1498Szrj if (diagnosed == NULL)
90838fd1498Szrj diagnosed = new hash_set<tree>;
90938fd1498Szrj if (diagnosed->add (fun))
91038fd1498Szrj /* Already explained. */
91138fd1498Szrj return;
91238fd1498Szrj
91338fd1498Szrj save_loc = input_location;
91438fd1498Szrj if (!lambda_static_thunk_p (fun))
91538fd1498Szrj {
91638fd1498Szrj /* Diagnostics should completely ignore the static thunk, so leave
91738fd1498Szrj input_location set to our caller's location. */
91838fd1498Szrj input_location = DECL_SOURCE_LOCATION (fun);
91938fd1498Szrj inform (input_location,
92038fd1498Szrj "%qD is not usable as a %<constexpr%> function because:", fun);
92138fd1498Szrj }
92238fd1498Szrj /* First check the declaration. */
92338fd1498Szrj if (is_valid_constexpr_fn (fun, true))
92438fd1498Szrj {
92538fd1498Szrj /* Then if it's OK, the body. */
92638fd1498Szrj if (!DECL_DECLARED_CONSTEXPR_P (fun)
92738fd1498Szrj && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun)))
92838fd1498Szrj explain_implicit_non_constexpr (fun);
92938fd1498Szrj else
93038fd1498Szrj {
93138fd1498Szrj body = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
93238fd1498Szrj require_potential_rvalue_constant_expression (body);
93338fd1498Szrj if (DECL_CONSTRUCTOR_P (fun))
93438fd1498Szrj cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
93538fd1498Szrj }
93638fd1498Szrj }
93738fd1498Szrj input_location = save_loc;
93838fd1498Szrj }
93938fd1498Szrj
94038fd1498Szrj /* Objects of this type represent calls to constexpr functions
94138fd1498Szrj along with the bindings of parameters to their arguments, for
94238fd1498Szrj the purpose of compile time evaluation. */
94338fd1498Szrj
94438fd1498Szrj struct GTY((for_user)) constexpr_call {
94538fd1498Szrj /* Description of the constexpr function definition. */
94638fd1498Szrj constexpr_fundef *fundef;
94738fd1498Szrj /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
94838fd1498Szrj is a parameter _DECL and the TREE_VALUE is the value of the parameter.
94938fd1498Szrj Note: This arrangement is made to accommodate the use of
95038fd1498Szrj iterative_hash_template_arg (see pt.c). If you change this
95138fd1498Szrj representation, also change the hash calculation in
95238fd1498Szrj cxx_eval_call_expression. */
95338fd1498Szrj tree bindings;
95438fd1498Szrj /* Result of the call.
95538fd1498Szrj NULL means the call is being evaluated.
95638fd1498Szrj error_mark_node means that the evaluation was erroneous;
95738fd1498Szrj otherwise, the actuall value of the call. */
95838fd1498Szrj tree result;
95938fd1498Szrj /* The hash of this call; we remember it here to avoid having to
96038fd1498Szrj recalculate it when expanding the hash table. */
96138fd1498Szrj hashval_t hash;
96238fd1498Szrj };
96338fd1498Szrj
96438fd1498Szrj struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call>
96538fd1498Szrj {
96638fd1498Szrj static hashval_t hash (constexpr_call *);
96738fd1498Szrj static bool equal (constexpr_call *, constexpr_call *);
96838fd1498Szrj };
96938fd1498Szrj
97038fd1498Szrj enum constexpr_switch_state {
97138fd1498Szrj /* Used when processing a switch for the first time by cxx_eval_switch_expr
97238fd1498Szrj and default: label for that switch has not been seen yet. */
97338fd1498Szrj css_default_not_seen,
97438fd1498Szrj /* Used when processing a switch for the first time by cxx_eval_switch_expr
97538fd1498Szrj and default: label for that switch has been seen already. */
97638fd1498Szrj css_default_seen,
97738fd1498Szrj /* Used when processing a switch for the second time by
97838fd1498Szrj cxx_eval_switch_expr, where default: label should match. */
97938fd1498Szrj css_default_processing
98038fd1498Szrj };
98138fd1498Szrj
98238fd1498Szrj /* The constexpr expansion context. CALL is the current function
98338fd1498Szrj expansion, CTOR is the current aggregate initializer, OBJECT is the
98438fd1498Szrj object being initialized by CTOR, either a VAR_DECL or a _REF. VALUES
98538fd1498Szrj is a map of values of variables initialized within the expression. */
98638fd1498Szrj
98738fd1498Szrj struct constexpr_ctx {
98838fd1498Szrj /* The innermost call we're evaluating. */
98938fd1498Szrj constexpr_call *call;
99038fd1498Szrj /* Values for any temporaries or local variables within the
99138fd1498Szrj constant-expression. */
99238fd1498Szrj hash_map<tree,tree> *values;
99338fd1498Szrj /* SAVE_EXPRs that we've seen within the current LOOP_EXPR. NULL if we
99438fd1498Szrj aren't inside a loop. */
99538fd1498Szrj hash_set<tree> *save_exprs;
99638fd1498Szrj /* The CONSTRUCTOR we're currently building up for an aggregate
99738fd1498Szrj initializer. */
99838fd1498Szrj tree ctor;
99938fd1498Szrj /* The object we're building the CONSTRUCTOR for. */
100038fd1498Szrj tree object;
100138fd1498Szrj /* If inside SWITCH_EXPR. */
100238fd1498Szrj constexpr_switch_state *css_state;
100338fd1498Szrj /* Whether we should error on a non-constant expression or fail quietly. */
100438fd1498Szrj bool quiet;
100538fd1498Szrj /* Whether we are strictly conforming to constant expression rules or
100638fd1498Szrj trying harder to get a constant value. */
100738fd1498Szrj bool strict;
100838fd1498Szrj };
100938fd1498Szrj
101038fd1498Szrj /* A table of all constexpr calls that have been evaluated by the
101138fd1498Szrj compiler in this translation unit. */
101238fd1498Szrj
101338fd1498Szrj static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
101438fd1498Szrj
101538fd1498Szrj static tree cxx_eval_constant_expression (const constexpr_ctx *, tree,
101638fd1498Szrj bool, bool *, bool *, tree * = NULL);
101738fd1498Szrj
101838fd1498Szrj /* Compute a hash value for a constexpr call representation. */
101938fd1498Szrj
102038fd1498Szrj inline hashval_t
hash(constexpr_call * info)102138fd1498Szrj constexpr_call_hasher::hash (constexpr_call *info)
102238fd1498Szrj {
102338fd1498Szrj return info->hash;
102438fd1498Szrj }
102538fd1498Szrj
102638fd1498Szrj /* Return true if the objects pointed to by P and Q represent calls
102738fd1498Szrj to the same constexpr function with the same arguments.
102838fd1498Szrj Otherwise, return false. */
102938fd1498Szrj
103038fd1498Szrj bool
equal(constexpr_call * lhs,constexpr_call * rhs)103138fd1498Szrj constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
103238fd1498Szrj {
103338fd1498Szrj tree lhs_bindings;
103438fd1498Szrj tree rhs_bindings;
103538fd1498Szrj if (lhs == rhs)
103638fd1498Szrj return true;
103738fd1498Szrj if (lhs->hash != rhs->hash)
103838fd1498Szrj return false;
103938fd1498Szrj if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
104038fd1498Szrj return false;
104138fd1498Szrj lhs_bindings = lhs->bindings;
104238fd1498Szrj rhs_bindings = rhs->bindings;
104338fd1498Szrj while (lhs_bindings != NULL && rhs_bindings != NULL)
104438fd1498Szrj {
104538fd1498Szrj tree lhs_arg = TREE_VALUE (lhs_bindings);
104638fd1498Szrj tree rhs_arg = TREE_VALUE (rhs_bindings);
104738fd1498Szrj gcc_assert (TREE_TYPE (lhs_arg) == TREE_TYPE (rhs_arg));
104838fd1498Szrj if (!cp_tree_equal (lhs_arg, rhs_arg))
104938fd1498Szrj return false;
105038fd1498Szrj lhs_bindings = TREE_CHAIN (lhs_bindings);
105138fd1498Szrj rhs_bindings = TREE_CHAIN (rhs_bindings);
105238fd1498Szrj }
105338fd1498Szrj return lhs_bindings == rhs_bindings;
105438fd1498Szrj }
105538fd1498Szrj
105638fd1498Szrj /* Initialize the constexpr call table, if needed. */
105738fd1498Szrj
105838fd1498Szrj static void
maybe_initialize_constexpr_call_table(void)105938fd1498Szrj maybe_initialize_constexpr_call_table (void)
106038fd1498Szrj {
106138fd1498Szrj if (constexpr_call_table == NULL)
106238fd1498Szrj constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
106338fd1498Szrj }
106438fd1498Szrj
106538fd1498Szrj /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when
106638fd1498Szrj a function happens to get called recursively, we unshare the callee
106738fd1498Szrj function's body and evaluate this unshared copy instead of evaluating the
106838fd1498Szrj original body.
106938fd1498Szrj
107038fd1498Szrj FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function
107138fd1498Szrj copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map
107238fd1498Szrj that's keyed off of the original FUNCTION_DECL and whose value is a
107338fd1498Szrj TREE_LIST of this function's unused copies awaiting reuse.
107438fd1498Szrj
107538fd1498Szrj This is not GC-deletable to avoid GC affecting UID generation. */
107638fd1498Szrj
107738fd1498Szrj static GTY(()) hash_map<tree, tree> *fundef_copies_table;
107838fd1498Szrj
107938fd1498Szrj /* Initialize FUNDEF_COPIES_TABLE if it's not initialized. */
108038fd1498Szrj
108138fd1498Szrj static void
maybe_initialize_fundef_copies_table()108238fd1498Szrj maybe_initialize_fundef_copies_table ()
108338fd1498Szrj {
108438fd1498Szrj if (fundef_copies_table == NULL)
108538fd1498Szrj fundef_copies_table = hash_map<tree,tree>::create_ggc (101);
108638fd1498Szrj }
108738fd1498Szrj
108838fd1498Szrj /* Reuse a copy or create a new unshared copy of the function FUN.
108938fd1498Szrj Return this copy. We use a TREE_LIST whose PURPOSE is body, VALUE
109038fd1498Szrj is parms, TYPE is result. */
109138fd1498Szrj
109238fd1498Szrj static tree
get_fundef_copy(tree fun)109338fd1498Szrj get_fundef_copy (tree fun)
109438fd1498Szrj {
109538fd1498Szrj maybe_initialize_fundef_copies_table ();
109638fd1498Szrj
109738fd1498Szrj tree copy;
109838fd1498Szrj bool existed;
109938fd1498Szrj tree *slot = &fundef_copies_table->get_or_insert (fun, &existed);
110038fd1498Szrj
110138fd1498Szrj if (!existed)
110238fd1498Szrj {
110338fd1498Szrj /* There is no cached function available, or in use. We can use
110438fd1498Szrj the function directly. That the slot is now created records
110538fd1498Szrj that this function is now in use. */
110638fd1498Szrj copy = build_tree_list (DECL_SAVED_TREE (fun), DECL_ARGUMENTS (fun));
110738fd1498Szrj TREE_TYPE (copy) = DECL_RESULT (fun);
110838fd1498Szrj }
110938fd1498Szrj else if (*slot == NULL_TREE)
111038fd1498Szrj {
111138fd1498Szrj /* We've already used the function itself, so make a copy. */
111238fd1498Szrj copy = build_tree_list (NULL, NULL);
111338fd1498Szrj TREE_PURPOSE (copy) = copy_fn (fun, TREE_VALUE (copy), TREE_TYPE (copy));
111438fd1498Szrj }
111538fd1498Szrj else
111638fd1498Szrj {
111738fd1498Szrj /* We have a cached function available. */
111838fd1498Szrj copy = *slot;
111938fd1498Szrj *slot = TREE_CHAIN (copy);
112038fd1498Szrj }
112138fd1498Szrj
112238fd1498Szrj return copy;
112338fd1498Szrj }
112438fd1498Szrj
112538fd1498Szrj /* Save the copy COPY of function FUN for later reuse by
112638fd1498Szrj get_fundef_copy(). By construction, there will always be an entry
112738fd1498Szrj to find. */
112838fd1498Szrj
112938fd1498Szrj static void
save_fundef_copy(tree fun,tree copy)113038fd1498Szrj save_fundef_copy (tree fun, tree copy)
113138fd1498Szrj {
113238fd1498Szrj tree *slot = fundef_copies_table->get (fun);
113338fd1498Szrj TREE_CHAIN (copy) = *slot;
113438fd1498Szrj *slot = copy;
113538fd1498Szrj }
113638fd1498Szrj
113738fd1498Szrj /* We have an expression tree T that represents a call, either CALL_EXPR
113838fd1498Szrj or AGGR_INIT_EXPR. Return the Nth argument. */
113938fd1498Szrj
114038fd1498Szrj static inline tree
get_nth_callarg(tree t,int n)114138fd1498Szrj get_nth_callarg (tree t, int n)
114238fd1498Szrj {
114338fd1498Szrj switch (TREE_CODE (t))
114438fd1498Szrj {
114538fd1498Szrj case CALL_EXPR:
114638fd1498Szrj return CALL_EXPR_ARG (t, n);
114738fd1498Szrj
114838fd1498Szrj case AGGR_INIT_EXPR:
114938fd1498Szrj return AGGR_INIT_EXPR_ARG (t, n);
115038fd1498Szrj
115138fd1498Szrj default:
115238fd1498Szrj gcc_unreachable ();
115338fd1498Szrj return NULL;
115438fd1498Szrj }
115538fd1498Szrj }
115638fd1498Szrj
115738fd1498Szrj /* Attempt to evaluate T which represents a call to a builtin function.
115838fd1498Szrj We assume here that all builtin functions evaluate to scalar types
115938fd1498Szrj represented by _CST nodes. */
116038fd1498Szrj
116138fd1498Szrj static tree
cxx_eval_builtin_function_call(const constexpr_ctx * ctx,tree t,tree fun,bool lval,bool * non_constant_p,bool * overflow_p)116238fd1498Szrj cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
116338fd1498Szrj bool lval,
116438fd1498Szrj bool *non_constant_p, bool *overflow_p)
116538fd1498Szrj {
116638fd1498Szrj const int nargs = call_expr_nargs (t);
116738fd1498Szrj tree *args = (tree *) alloca (nargs * sizeof (tree));
116838fd1498Szrj tree new_call;
116938fd1498Szrj int i;
117038fd1498Szrj
117138fd1498Szrj /* Don't fold __builtin_constant_p within a constexpr function. */
117238fd1498Szrj bool bi_const_p = (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P);
117338fd1498Szrj
117438fd1498Szrj /* If we aren't requiring a constant expression, defer __builtin_constant_p
117538fd1498Szrj in a constexpr function until we have values for the parameters. */
117638fd1498Szrj if (bi_const_p
117738fd1498Szrj && ctx->quiet
117838fd1498Szrj && current_function_decl
117938fd1498Szrj && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
118038fd1498Szrj {
118138fd1498Szrj *non_constant_p = true;
118238fd1498Szrj return t;
118338fd1498Szrj }
118438fd1498Szrj
118538fd1498Szrj /* Be permissive for arguments to built-ins; __builtin_constant_p should
118638fd1498Szrj return constant false for a non-constant argument. */
118738fd1498Szrj constexpr_ctx new_ctx = *ctx;
118838fd1498Szrj new_ctx.quiet = true;
118938fd1498Szrj bool dummy1 = false, dummy2 = false;
119038fd1498Szrj for (i = 0; i < nargs; ++i)
119138fd1498Szrj {
119238fd1498Szrj args[i] = CALL_EXPR_ARG (t, i);
119338fd1498Szrj /* If builtin_valid_in_constant_expr_p is true,
119438fd1498Szrj potential_constant_expression_1 has not recursed into the arguments
119538fd1498Szrj of the builtin, verify it here. */
119638fd1498Szrj if (!builtin_valid_in_constant_expr_p (fun)
119738fd1498Szrj || potential_constant_expression (args[i]))
119838fd1498Szrj args[i] = cxx_eval_constant_expression (&new_ctx, args[i], false,
119938fd1498Szrj &dummy1, &dummy2);
120038fd1498Szrj if (bi_const_p)
120138fd1498Szrj /* For __built_in_constant_p, fold all expressions with constant values
120238fd1498Szrj even if they aren't C++ constant-expressions. */
120338fd1498Szrj args[i] = cp_fully_fold (args[i]);
120438fd1498Szrj }
120538fd1498Szrj
120638fd1498Szrj bool save_ffbcp = force_folding_builtin_constant_p;
120738fd1498Szrj force_folding_builtin_constant_p = true;
120838fd1498Szrj new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
120938fd1498Szrj CALL_EXPR_FN (t), nargs, args);
121038fd1498Szrj force_folding_builtin_constant_p = save_ffbcp;
121138fd1498Szrj if (new_call == NULL)
121238fd1498Szrj {
121338fd1498Szrj if (!*non_constant_p && !ctx->quiet)
121438fd1498Szrj {
121538fd1498Szrj /* Do not allow__builtin_unreachable in constexpr function.
121638fd1498Szrj The __builtin_unreachable call with BUILTINS_LOCATION
121738fd1498Szrj comes from cp_maybe_instrument_return. */
121838fd1498Szrj if (DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
121938fd1498Szrj && EXPR_LOCATION (t) == BUILTINS_LOCATION)
122038fd1498Szrj error ("%<constexpr%> call flows off the end of the function");
122138fd1498Szrj else
122238fd1498Szrj {
122338fd1498Szrj new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
122438fd1498Szrj CALL_EXPR_FN (t), nargs, args);
122538fd1498Szrj error ("%q+E is not a constant expression", new_call);
122638fd1498Szrj }
122738fd1498Szrj }
122838fd1498Szrj *non_constant_p = true;
122938fd1498Szrj return t;
123038fd1498Szrj }
123138fd1498Szrj
123238fd1498Szrj if (!is_constant_expression (new_call))
123338fd1498Szrj {
123438fd1498Szrj if (!*non_constant_p && !ctx->quiet)
123538fd1498Szrj error ("%q+E is not a constant expression", new_call);
123638fd1498Szrj *non_constant_p = true;
123738fd1498Szrj return t;
123838fd1498Szrj }
123938fd1498Szrj
124038fd1498Szrj return cxx_eval_constant_expression (&new_ctx, new_call, lval,
124138fd1498Szrj non_constant_p, overflow_p);
124238fd1498Szrj }
124338fd1498Szrj
124438fd1498Szrj /* TEMP is the constant value of a temporary object of type TYPE. Adjust
124538fd1498Szrj the type of the value to match. */
124638fd1498Szrj
124738fd1498Szrj static tree
adjust_temp_type(tree type,tree temp)124838fd1498Szrj adjust_temp_type (tree type, tree temp)
124938fd1498Szrj {
125038fd1498Szrj if (TREE_TYPE (temp) == type)
125138fd1498Szrj return temp;
125238fd1498Szrj /* Avoid wrapping an aggregate value in a NOP_EXPR. */
125338fd1498Szrj if (TREE_CODE (temp) == CONSTRUCTOR)
125438fd1498Szrj return build_constructor (type, CONSTRUCTOR_ELTS (temp));
1255*58e805e6Szrj if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
1256*58e805e6Szrj return build0 (EMPTY_CLASS_EXPR, type);
125738fd1498Szrj gcc_assert (scalarish_type_p (type));
125838fd1498Szrj return cp_fold_convert (type, temp);
125938fd1498Szrj }
126038fd1498Szrj
126138fd1498Szrj /* Callback for walk_tree used by unshare_constructor. */
126238fd1498Szrj
126338fd1498Szrj static tree
find_constructor(tree * tp,int * walk_subtrees,void *)126438fd1498Szrj find_constructor (tree *tp, int *walk_subtrees, void *)
126538fd1498Szrj {
126638fd1498Szrj if (TYPE_P (*tp))
126738fd1498Szrj *walk_subtrees = 0;
126838fd1498Szrj if (TREE_CODE (*tp) == CONSTRUCTOR)
126938fd1498Szrj return *tp;
127038fd1498Szrj return NULL_TREE;
127138fd1498Szrj }
127238fd1498Szrj
127338fd1498Szrj /* If T is a CONSTRUCTOR or an expression that has a CONSTRUCTOR node as a
127438fd1498Szrj subexpression, return an unshared copy of T. Otherwise return T. */
127538fd1498Szrj
127638fd1498Szrj static tree
unshare_constructor(tree t)127738fd1498Szrj unshare_constructor (tree t)
127838fd1498Szrj {
127938fd1498Szrj tree ctor = walk_tree (&t, find_constructor, NULL, NULL);
128038fd1498Szrj if (ctor != NULL_TREE)
128138fd1498Szrj return unshare_expr (t);
128238fd1498Szrj return t;
128338fd1498Szrj }
128438fd1498Szrj
128538fd1498Szrj /* Subroutine of cxx_eval_call_expression.
128638fd1498Szrj We are processing a call expression (either CALL_EXPR or
128738fd1498Szrj AGGR_INIT_EXPR) in the context of CTX. Evaluate
128838fd1498Szrj all arguments and bind their values to correspondings
128938fd1498Szrj parameters, making up the NEW_CALL context. */
129038fd1498Szrj
129138fd1498Szrj static void
cxx_bind_parameters_in_call(const constexpr_ctx * ctx,tree t,constexpr_call * new_call,bool * non_constant_p,bool * overflow_p,bool * non_constant_args)129238fd1498Szrj cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
129338fd1498Szrj constexpr_call *new_call,
129438fd1498Szrj bool *non_constant_p, bool *overflow_p,
129538fd1498Szrj bool *non_constant_args)
129638fd1498Szrj {
129738fd1498Szrj const int nargs = call_expr_nargs (t);
129838fd1498Szrj tree fun = new_call->fundef->decl;
129938fd1498Szrj tree parms = DECL_ARGUMENTS (fun);
130038fd1498Szrj int i;
130138fd1498Szrj tree *p = &new_call->bindings;
130238fd1498Szrj for (i = 0; i < nargs; ++i)
130338fd1498Szrj {
130438fd1498Szrj tree x, arg;
130538fd1498Szrj tree type = parms ? TREE_TYPE (parms) : void_type_node;
130638fd1498Szrj x = get_nth_callarg (t, i);
130738fd1498Szrj /* For member function, the first argument is a pointer to the implied
130838fd1498Szrj object. For a constructor, it might still be a dummy object, in
130938fd1498Szrj which case we get the real argument from ctx. */
131038fd1498Szrj if (i == 0 && DECL_CONSTRUCTOR_P (fun)
131138fd1498Szrj && is_dummy_object (x))
131238fd1498Szrj {
131338fd1498Szrj x = ctx->object;
131438fd1498Szrj x = build_address (x);
131538fd1498Szrj }
131638fd1498Szrj arg = cxx_eval_constant_expression (ctx, x, /*lval=*/false,
131738fd1498Szrj non_constant_p, overflow_p);
131838fd1498Szrj /* Don't VERIFY_CONSTANT here. */
131938fd1498Szrj if (*non_constant_p && ctx->quiet)
132038fd1498Szrj return;
132138fd1498Szrj /* Just discard ellipsis args after checking their constantitude. */
132238fd1498Szrj if (!parms)
132338fd1498Szrj continue;
132438fd1498Szrj
132538fd1498Szrj if (!*non_constant_p)
132638fd1498Szrj {
132738fd1498Szrj /* Don't share a CONSTRUCTOR that might be changed. */
132838fd1498Szrj arg = unshare_constructor (arg);
132938fd1498Szrj /* Make sure the binding has the same type as the parm. But
133038fd1498Szrj only for constant args. */
133138fd1498Szrj if (TREE_CODE (type) != REFERENCE_TYPE)
133238fd1498Szrj arg = adjust_temp_type (type, arg);
133338fd1498Szrj if (!TREE_CONSTANT (arg))
133438fd1498Szrj *non_constant_args = true;
133538fd1498Szrj *p = build_tree_list (parms, arg);
133638fd1498Szrj p = &TREE_CHAIN (*p);
133738fd1498Szrj }
133838fd1498Szrj parms = TREE_CHAIN (parms);
133938fd1498Szrj }
134038fd1498Szrj }
134138fd1498Szrj
134238fd1498Szrj /* Variables and functions to manage constexpr call expansion context.
134338fd1498Szrj These do not need to be marked for PCH or GC. */
134438fd1498Szrj
134538fd1498Szrj /* FIXME remember and print actual constant arguments. */
134638fd1498Szrj static vec<tree> call_stack;
134738fd1498Szrj static int call_stack_tick;
134838fd1498Szrj static int last_cx_error_tick;
134938fd1498Szrj
135038fd1498Szrj static bool
push_cx_call_context(tree call)135138fd1498Szrj push_cx_call_context (tree call)
135238fd1498Szrj {
135338fd1498Szrj ++call_stack_tick;
135438fd1498Szrj if (!EXPR_HAS_LOCATION (call))
135538fd1498Szrj SET_EXPR_LOCATION (call, input_location);
135638fd1498Szrj call_stack.safe_push (call);
135738fd1498Szrj if (call_stack.length () > (unsigned) max_constexpr_depth)
135838fd1498Szrj return false;
135938fd1498Szrj return true;
136038fd1498Szrj }
136138fd1498Szrj
136238fd1498Szrj static void
pop_cx_call_context(void)136338fd1498Szrj pop_cx_call_context (void)
136438fd1498Szrj {
136538fd1498Szrj ++call_stack_tick;
136638fd1498Szrj call_stack.pop ();
136738fd1498Szrj }
136838fd1498Szrj
136938fd1498Szrj vec<tree>
cx_error_context(void)137038fd1498Szrj cx_error_context (void)
137138fd1498Szrj {
137238fd1498Szrj vec<tree> r = vNULL;
137338fd1498Szrj if (call_stack_tick != last_cx_error_tick
137438fd1498Szrj && !call_stack.is_empty ())
137538fd1498Szrj r = call_stack;
137638fd1498Szrj last_cx_error_tick = call_stack_tick;
137738fd1498Szrj return r;
137838fd1498Szrj }
137938fd1498Szrj
138038fd1498Szrj /* Evaluate a call T to a GCC internal function when possible and return
138138fd1498Szrj the evaluated result or, under the control of CTX, give an error, set
138238fd1498Szrj NON_CONSTANT_P, and return the unevaluated call T otherwise. */
138338fd1498Szrj
138438fd1498Szrj static tree
cxx_eval_internal_function(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)138538fd1498Szrj cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
138638fd1498Szrj bool lval,
138738fd1498Szrj bool *non_constant_p, bool *overflow_p)
138838fd1498Szrj {
138938fd1498Szrj enum tree_code opcode = ERROR_MARK;
139038fd1498Szrj
139138fd1498Szrj switch (CALL_EXPR_IFN (t))
139238fd1498Szrj {
139338fd1498Szrj case IFN_UBSAN_NULL:
139438fd1498Szrj case IFN_UBSAN_BOUNDS:
139538fd1498Szrj case IFN_UBSAN_VPTR:
139638fd1498Szrj case IFN_FALLTHROUGH:
139738fd1498Szrj return void_node;
139838fd1498Szrj
139938fd1498Szrj case IFN_ADD_OVERFLOW:
140038fd1498Szrj opcode = PLUS_EXPR;
140138fd1498Szrj break;
140238fd1498Szrj case IFN_SUB_OVERFLOW:
140338fd1498Szrj opcode = MINUS_EXPR;
140438fd1498Szrj break;
140538fd1498Szrj case IFN_MUL_OVERFLOW:
140638fd1498Szrj opcode = MULT_EXPR;
140738fd1498Szrj break;
140838fd1498Szrj
140938fd1498Szrj case IFN_LAUNDER:
141038fd1498Szrj return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
141138fd1498Szrj false, non_constant_p, overflow_p);
141238fd1498Szrj
141338fd1498Szrj default:
141438fd1498Szrj if (!ctx->quiet)
141538fd1498Szrj error_at (EXPR_LOC_OR_LOC (t, input_location),
141638fd1498Szrj "call to internal function %qE", t);
141738fd1498Szrj *non_constant_p = true;
141838fd1498Szrj return t;
141938fd1498Szrj }
142038fd1498Szrj
142138fd1498Szrj /* Evaluate constant arguments using OPCODE and return a complex
142238fd1498Szrj number containing the result and the overflow bit. */
142338fd1498Szrj tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval,
142438fd1498Szrj non_constant_p, overflow_p);
142538fd1498Szrj tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval,
142638fd1498Szrj non_constant_p, overflow_p);
142738fd1498Szrj
142838fd1498Szrj if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
142938fd1498Szrj {
143038fd1498Szrj location_t loc = EXPR_LOC_OR_LOC (t, input_location);
143138fd1498Szrj tree type = TREE_TYPE (TREE_TYPE (t));
143238fd1498Szrj tree result = fold_binary_loc (loc, opcode, type,
143338fd1498Szrj fold_convert_loc (loc, type, arg0),
143438fd1498Szrj fold_convert_loc (loc, type, arg1));
143538fd1498Szrj tree ovf
143638fd1498Szrj = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1));
143738fd1498Szrj /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */
143838fd1498Szrj if (TREE_OVERFLOW (result))
143938fd1498Szrj TREE_OVERFLOW (result) = 0;
144038fd1498Szrj
144138fd1498Szrj return build_complex (TREE_TYPE (t), result, ovf);
144238fd1498Szrj }
144338fd1498Szrj
144438fd1498Szrj *non_constant_p = true;
144538fd1498Szrj return t;
144638fd1498Szrj }
144738fd1498Szrj
144838fd1498Szrj /* Clean CONSTRUCTOR_NO_IMPLICIT_ZERO from CTOR and its sub-aggregates. */
144938fd1498Szrj
145038fd1498Szrj static void
clear_no_implicit_zero(tree ctor)145138fd1498Szrj clear_no_implicit_zero (tree ctor)
145238fd1498Szrj {
145338fd1498Szrj if (CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor))
145438fd1498Szrj {
145538fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor) = false;
145638fd1498Szrj tree elt; unsigned HOST_WIDE_INT idx;
145738fd1498Szrj FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), idx, elt)
145838fd1498Szrj if (TREE_CODE (elt) == CONSTRUCTOR)
145938fd1498Szrj clear_no_implicit_zero (elt);
146038fd1498Szrj }
146138fd1498Szrj }
146238fd1498Szrj
146338fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
146438fd1498Szrj Evaluate the call expression tree T in the context of OLD_CALL expression
146538fd1498Szrj evaluation. */
146638fd1498Szrj
146738fd1498Szrj static tree
cxx_eval_call_expression(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)146838fd1498Szrj cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
146938fd1498Szrj bool lval,
147038fd1498Szrj bool *non_constant_p, bool *overflow_p)
147138fd1498Szrj {
147238fd1498Szrj location_t loc = EXPR_LOC_OR_LOC (t, input_location);
147338fd1498Szrj tree fun = get_function_named_in_call (t);
147438fd1498Szrj constexpr_call new_call = { NULL, NULL, NULL, 0 };
147538fd1498Szrj bool depth_ok;
147638fd1498Szrj
147738fd1498Szrj if (fun == NULL_TREE)
147838fd1498Szrj return cxx_eval_internal_function (ctx, t, lval,
147938fd1498Szrj non_constant_p, overflow_p);
148038fd1498Szrj
148138fd1498Szrj if (TREE_CODE (fun) != FUNCTION_DECL)
148238fd1498Szrj {
148338fd1498Szrj /* Might be a constexpr function pointer. */
148438fd1498Szrj fun = cxx_eval_constant_expression (ctx, fun,
148538fd1498Szrj /*lval*/false, non_constant_p,
148638fd1498Szrj overflow_p);
148738fd1498Szrj STRIP_NOPS (fun);
148838fd1498Szrj if (TREE_CODE (fun) == ADDR_EXPR)
148938fd1498Szrj fun = TREE_OPERAND (fun, 0);
149038fd1498Szrj }
149138fd1498Szrj if (TREE_CODE (fun) != FUNCTION_DECL)
149238fd1498Szrj {
149338fd1498Szrj if (!ctx->quiet && !*non_constant_p)
149438fd1498Szrj error_at (loc, "expression %qE does not designate a %<constexpr%> "
149538fd1498Szrj "function", fun);
149638fd1498Szrj *non_constant_p = true;
149738fd1498Szrj return t;
149838fd1498Szrj }
149938fd1498Szrj if (DECL_CLONED_FUNCTION_P (fun))
150038fd1498Szrj fun = DECL_CLONED_FUNCTION (fun);
150138fd1498Szrj
150238fd1498Szrj if (is_ubsan_builtin_p (fun))
150338fd1498Szrj return void_node;
150438fd1498Szrj
150538fd1498Szrj if (is_builtin_fn (fun))
150638fd1498Szrj return cxx_eval_builtin_function_call (ctx, t, fun,
150738fd1498Szrj lval, non_constant_p, overflow_p);
150838fd1498Szrj if (!DECL_DECLARED_CONSTEXPR_P (fun))
150938fd1498Szrj {
151038fd1498Szrj if (!ctx->quiet)
151138fd1498Szrj {
151238fd1498Szrj if (!lambda_static_thunk_p (fun))
151338fd1498Szrj error_at (loc, "call to non-%<constexpr%> function %qD", fun);
151438fd1498Szrj explain_invalid_constexpr_fn (fun);
151538fd1498Szrj }
151638fd1498Szrj *non_constant_p = true;
151738fd1498Szrj return t;
151838fd1498Szrj }
151938fd1498Szrj
152038fd1498Szrj constexpr_ctx new_ctx = *ctx;
152138fd1498Szrj if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
152238fd1498Szrj && TREE_CODE (t) == AGGR_INIT_EXPR)
152338fd1498Szrj {
152438fd1498Szrj /* We want to have an initialization target for an AGGR_INIT_EXPR.
152538fd1498Szrj If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */
152638fd1498Szrj new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
152738fd1498Szrj tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
152838fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor) = true;
152938fd1498Szrj ctx->values->put (new_ctx.object, ctor);
153038fd1498Szrj ctx = &new_ctx;
153138fd1498Szrj }
153238fd1498Szrj
153338fd1498Szrj /* Shortcut trivial constructor/op=. */
153438fd1498Szrj if (trivial_fn_p (fun))
153538fd1498Szrj {
153638fd1498Szrj tree init = NULL_TREE;
153738fd1498Szrj if (call_expr_nargs (t) == 2)
153838fd1498Szrj init = convert_from_reference (get_nth_callarg (t, 1));
153938fd1498Szrj else if (TREE_CODE (t) == AGGR_INIT_EXPR
154038fd1498Szrj && AGGR_INIT_ZERO_FIRST (t))
154138fd1498Szrj init = build_zero_init (DECL_CONTEXT (fun), NULL_TREE, false);
154238fd1498Szrj if (init)
154338fd1498Szrj {
154438fd1498Szrj tree op = get_nth_callarg (t, 0);
154538fd1498Szrj if (is_dummy_object (op))
154638fd1498Szrj op = ctx->object;
154738fd1498Szrj else
154838fd1498Szrj op = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (op)), op);
154938fd1498Szrj tree set = build2 (MODIFY_EXPR, TREE_TYPE (op), op, init);
155038fd1498Szrj new_ctx.call = &new_call;
155138fd1498Szrj return cxx_eval_constant_expression (&new_ctx, set, lval,
155238fd1498Szrj non_constant_p, overflow_p);
155338fd1498Szrj }
155438fd1498Szrj }
155538fd1498Szrj
155638fd1498Szrj /* We can't defer instantiating the function any longer. */
155738fd1498Szrj if (!DECL_INITIAL (fun)
155838fd1498Szrj && DECL_TEMPLOID_INSTANTIATION (fun))
155938fd1498Szrj {
156038fd1498Szrj location_t save_loc = input_location;
156138fd1498Szrj input_location = loc;
156238fd1498Szrj ++function_depth;
156338fd1498Szrj instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
156438fd1498Szrj --function_depth;
156538fd1498Szrj input_location = save_loc;
156638fd1498Szrj }
156738fd1498Szrj
156838fd1498Szrj /* If in direct recursive call, optimize definition search. */
156938fd1498Szrj if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun)
157038fd1498Szrj new_call.fundef = ctx->call->fundef;
157138fd1498Szrj else
157238fd1498Szrj {
157338fd1498Szrj new_call.fundef = retrieve_constexpr_fundef (fun);
157438fd1498Szrj if (new_call.fundef == NULL || new_call.fundef->body == NULL
157538fd1498Szrj || fun == current_function_decl)
157638fd1498Szrj {
157738fd1498Szrj if (!ctx->quiet)
157838fd1498Szrj {
157938fd1498Szrj /* We need to check for current_function_decl here in case we're
158038fd1498Szrj being called during cp_fold_function, because at that point
158138fd1498Szrj DECL_INITIAL is set properly and we have a fundef but we
158238fd1498Szrj haven't lowered invisirefs yet (c++/70344). */
158338fd1498Szrj if (DECL_INITIAL (fun) == error_mark_node
158438fd1498Szrj || fun == current_function_decl)
158538fd1498Szrj error_at (loc, "%qD called in a constant expression before its "
158638fd1498Szrj "definition is complete", fun);
158738fd1498Szrj else if (DECL_INITIAL (fun))
158838fd1498Szrj {
158938fd1498Szrj /* The definition of fun was somehow unsuitable. But pretend
159038fd1498Szrj that lambda static thunks don't exist. */
159138fd1498Szrj if (!lambda_static_thunk_p (fun))
159238fd1498Szrj error_at (loc, "%qD called in a constant expression", fun);
159338fd1498Szrj explain_invalid_constexpr_fn (fun);
159438fd1498Szrj }
159538fd1498Szrj else
159638fd1498Szrj error_at (loc, "%qD used before its definition", fun);
159738fd1498Szrj }
159838fd1498Szrj *non_constant_p = true;
159938fd1498Szrj return t;
160038fd1498Szrj }
160138fd1498Szrj }
160238fd1498Szrj
160338fd1498Szrj bool non_constant_args = false;
160438fd1498Szrj cxx_bind_parameters_in_call (ctx, t, &new_call,
160538fd1498Szrj non_constant_p, overflow_p, &non_constant_args);
160638fd1498Szrj if (*non_constant_p)
160738fd1498Szrj return t;
160838fd1498Szrj
160938fd1498Szrj depth_ok = push_cx_call_context (t);
161038fd1498Szrj
161138fd1498Szrj tree result = NULL_TREE;
161238fd1498Szrj
161338fd1498Szrj constexpr_call *entry = NULL;
161438fd1498Szrj if (depth_ok && !non_constant_args && ctx->strict)
161538fd1498Szrj {
161638fd1498Szrj new_call.hash = iterative_hash_template_arg
161738fd1498Szrj (new_call.bindings, constexpr_fundef_hasher::hash (new_call.fundef));
161838fd1498Szrj
161938fd1498Szrj /* If we have seen this call before, we are done. */
162038fd1498Szrj maybe_initialize_constexpr_call_table ();
162138fd1498Szrj constexpr_call **slot
162238fd1498Szrj = constexpr_call_table->find_slot (&new_call, INSERT);
162338fd1498Szrj entry = *slot;
162438fd1498Szrj if (entry == NULL)
162538fd1498Szrj {
162638fd1498Szrj /* We need to keep a pointer to the entry, not just the slot, as the
162738fd1498Szrj slot can move in the call to cxx_eval_builtin_function_call. */
162838fd1498Szrj *slot = entry = ggc_alloc<constexpr_call> ();
162938fd1498Szrj *entry = new_call;
163038fd1498Szrj }
163138fd1498Szrj /* Calls that are in progress have their result set to NULL,
163238fd1498Szrj so that we can detect circular dependencies. */
163338fd1498Szrj else if (entry->result == NULL)
163438fd1498Szrj {
163538fd1498Szrj if (!ctx->quiet)
163638fd1498Szrj error ("call has circular dependency");
163738fd1498Szrj *non_constant_p = true;
163838fd1498Szrj entry->result = result = error_mark_node;
163938fd1498Szrj }
164038fd1498Szrj else
164138fd1498Szrj result = entry->result;
164238fd1498Szrj }
164338fd1498Szrj
164438fd1498Szrj if (!depth_ok)
164538fd1498Szrj {
164638fd1498Szrj if (!ctx->quiet)
164738fd1498Szrj error ("%<constexpr%> evaluation depth exceeds maximum of %d (use "
164838fd1498Szrj "-fconstexpr-depth= to increase the maximum)",
164938fd1498Szrj max_constexpr_depth);
165038fd1498Szrj *non_constant_p = true;
165138fd1498Szrj result = error_mark_node;
165238fd1498Szrj }
165338fd1498Szrj else
165438fd1498Szrj {
165538fd1498Szrj if (result && result != error_mark_node)
165638fd1498Szrj /* OK */;
165738fd1498Szrj else if (!DECL_SAVED_TREE (fun))
165838fd1498Szrj {
165938fd1498Szrj /* When at_eof >= 2, cgraph has started throwing away
166038fd1498Szrj DECL_SAVED_TREE, so fail quietly. FIXME we get here because of
166138fd1498Szrj late code generation for VEC_INIT_EXPR, which needs to be
166238fd1498Szrj completely reconsidered. */
166338fd1498Szrj gcc_assert (at_eof >= 2 && ctx->quiet);
166438fd1498Szrj *non_constant_p = true;
166538fd1498Szrj }
166638fd1498Szrj else
166738fd1498Szrj {
166838fd1498Szrj tree body, parms, res;
166938fd1498Szrj
167038fd1498Szrj /* Reuse or create a new unshared copy of this function's body. */
167138fd1498Szrj tree copy = get_fundef_copy (fun);
167238fd1498Szrj body = TREE_PURPOSE (copy);
167338fd1498Szrj parms = TREE_VALUE (copy);
167438fd1498Szrj res = TREE_TYPE (copy);
167538fd1498Szrj
167638fd1498Szrj /* Associate the bindings with the remapped parms. */
167738fd1498Szrj tree bound = new_call.bindings;
167838fd1498Szrj tree remapped = parms;
167938fd1498Szrj while (bound)
168038fd1498Szrj {
168138fd1498Szrj tree oparm = TREE_PURPOSE (bound);
168238fd1498Szrj tree arg = TREE_VALUE (bound);
168338fd1498Szrj gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm));
168438fd1498Szrj /* Don't share a CONSTRUCTOR that might be changed. */
168538fd1498Szrj arg = unshare_constructor (arg);
168638fd1498Szrj ctx->values->put (remapped, arg);
168738fd1498Szrj bound = TREE_CHAIN (bound);
168838fd1498Szrj remapped = DECL_CHAIN (remapped);
168938fd1498Szrj }
169038fd1498Szrj /* Add the RESULT_DECL to the values map, too. */
169138fd1498Szrj tree slot = NULL_TREE;
169238fd1498Szrj if (DECL_BY_REFERENCE (res))
169338fd1498Szrj {
169438fd1498Szrj slot = AGGR_INIT_EXPR_SLOT (t);
169538fd1498Szrj tree addr = build_address (slot);
169638fd1498Szrj addr = build_nop (TREE_TYPE (res), addr);
169738fd1498Szrj ctx->values->put (res, addr);
169838fd1498Szrj ctx->values->put (slot, NULL_TREE);
169938fd1498Szrj }
170038fd1498Szrj else
170138fd1498Szrj ctx->values->put (res, NULL_TREE);
170238fd1498Szrj
170338fd1498Szrj /* Track the callee's evaluated SAVE_EXPRs so that we can forget
170438fd1498Szrj their values after the call. */
170538fd1498Szrj constexpr_ctx ctx_with_save_exprs = *ctx;
170638fd1498Szrj hash_set<tree> save_exprs;
170738fd1498Szrj ctx_with_save_exprs.save_exprs = &save_exprs;
170838fd1498Szrj ctx_with_save_exprs.call = &new_call;
170938fd1498Szrj
171038fd1498Szrj tree jump_target = NULL_TREE;
171138fd1498Szrj cxx_eval_constant_expression (&ctx_with_save_exprs, body,
171238fd1498Szrj lval, non_constant_p, overflow_p,
171338fd1498Szrj &jump_target);
171438fd1498Szrj
171538fd1498Szrj if (DECL_CONSTRUCTOR_P (fun))
171638fd1498Szrj /* This can be null for a subobject constructor call, in
171738fd1498Szrj which case what we care about is the initialization
171838fd1498Szrj side-effects rather than the value. We could get at the
171938fd1498Szrj value by evaluating *this, but we don't bother; there's
172038fd1498Szrj no need to put such a call in the hash table. */
172138fd1498Szrj result = lval ? ctx->object : ctx->ctor;
172238fd1498Szrj else if (VOID_TYPE_P (TREE_TYPE (res)))
172338fd1498Szrj result = void_node;
172438fd1498Szrj else
172538fd1498Szrj {
172638fd1498Szrj result = *ctx->values->get (slot ? slot : res);
172738fd1498Szrj if (result == NULL_TREE && !*non_constant_p)
172838fd1498Szrj {
172938fd1498Szrj if (!ctx->quiet)
173038fd1498Szrj error ("%<constexpr%> call flows off the end "
173138fd1498Szrj "of the function");
173238fd1498Szrj *non_constant_p = true;
173338fd1498Szrj }
173438fd1498Szrj }
173538fd1498Szrj
173638fd1498Szrj /* Forget the saved values of the callee's SAVE_EXPRs. */
173738fd1498Szrj for (hash_set<tree>::iterator iter = save_exprs.begin();
173838fd1498Szrj iter != save_exprs.end(); ++iter)
173938fd1498Szrj ctx_with_save_exprs.values->remove (*iter);
174038fd1498Szrj
174138fd1498Szrj /* Remove the parms/result from the values map. Is it worth
174238fd1498Szrj bothering to do this when the map itself is only live for
174338fd1498Szrj one constexpr evaluation? If so, maybe also clear out
174438fd1498Szrj other vars from call, maybe in BIND_EXPR handling? */
174538fd1498Szrj ctx->values->remove (res);
174638fd1498Szrj if (slot)
174738fd1498Szrj ctx->values->remove (slot);
174838fd1498Szrj for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
174938fd1498Szrj ctx->values->remove (parm);
175038fd1498Szrj
175138fd1498Szrj /* Make the unshared function copy we used available for re-use. */
175238fd1498Szrj save_fundef_copy (fun, copy);
175338fd1498Szrj }
175438fd1498Szrj
175538fd1498Szrj if (result == error_mark_node)
175638fd1498Szrj *non_constant_p = true;
175738fd1498Szrj if (*non_constant_p || *overflow_p)
175838fd1498Szrj result = error_mark_node;
175938fd1498Szrj else if (!result)
176038fd1498Szrj result = void_node;
176138fd1498Szrj if (entry)
176238fd1498Szrj entry->result = result;
176338fd1498Szrj }
176438fd1498Szrj
176538fd1498Szrj /* The result of a constexpr function must be completely initialized. */
176638fd1498Szrj if (TREE_CODE (result) == CONSTRUCTOR)
176738fd1498Szrj clear_no_implicit_zero (result);
176838fd1498Szrj
176938fd1498Szrj pop_cx_call_context ();
177038fd1498Szrj return unshare_constructor (result);
177138fd1498Szrj }
177238fd1498Szrj
177338fd1498Szrj /* FIXME speed this up, it's taking 16% of compile time on sieve testcase. */
177438fd1498Szrj
177538fd1498Szrj bool
reduced_constant_expression_p(tree t)177638fd1498Szrj reduced_constant_expression_p (tree t)
177738fd1498Szrj {
177838fd1498Szrj if (t == NULL_TREE)
177938fd1498Szrj return false;
178038fd1498Szrj
178138fd1498Szrj switch (TREE_CODE (t))
178238fd1498Szrj {
178338fd1498Szrj case PTRMEM_CST:
178438fd1498Szrj /* Even if we can't lower this yet, it's constant. */
178538fd1498Szrj return true;
178638fd1498Szrj
178738fd1498Szrj case CONSTRUCTOR:
178838fd1498Szrj /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
178938fd1498Szrj tree idx, val, field; unsigned HOST_WIDE_INT i;
179038fd1498Szrj if (CONSTRUCTOR_NO_IMPLICIT_ZERO (t))
179138fd1498Szrj {
179238fd1498Szrj if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
179338fd1498Szrj /* An initialized vector would have a VECTOR_CST. */
179438fd1498Szrj return false;
179538fd1498Szrj else
179638fd1498Szrj field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t)));
179738fd1498Szrj }
179838fd1498Szrj else
179938fd1498Szrj field = NULL_TREE;
180038fd1498Szrj FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, idx, val)
180138fd1498Szrj {
180238fd1498Szrj /* If VAL is null, we're in the middle of initializing this
180338fd1498Szrj element. */
180438fd1498Szrj if (!reduced_constant_expression_p (val))
180538fd1498Szrj return false;
180638fd1498Szrj if (field)
180738fd1498Szrj {
180838fd1498Szrj if (idx != field)
180938fd1498Szrj return false;
181038fd1498Szrj field = next_initializable_field (DECL_CHAIN (field));
181138fd1498Szrj }
181238fd1498Szrj }
181338fd1498Szrj if (field)
181438fd1498Szrj return false;
181538fd1498Szrj else if (CONSTRUCTOR_NO_IMPLICIT_ZERO (t))
181638fd1498Szrj /* All the fields are initialized. */
181738fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (t) = false;
181838fd1498Szrj return true;
181938fd1498Szrj
182038fd1498Szrj default:
182138fd1498Szrj /* FIXME are we calling this too much? */
182238fd1498Szrj return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
182338fd1498Szrj }
182438fd1498Szrj }
182538fd1498Szrj
182638fd1498Szrj /* Some expressions may have constant operands but are not constant
182738fd1498Szrj themselves, such as 1/0. Call this function to check for that
182838fd1498Szrj condition.
182938fd1498Szrj
183038fd1498Szrj We only call this in places that require an arithmetic constant, not in
183138fd1498Szrj places where we might have a non-constant expression that can be a
183238fd1498Szrj component of a constant expression, such as the address of a constexpr
183338fd1498Szrj variable that might be dereferenced later. */
183438fd1498Szrj
183538fd1498Szrj static bool
verify_constant(tree t,bool allow_non_constant,bool * non_constant_p,bool * overflow_p)183638fd1498Szrj verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
183738fd1498Szrj bool *overflow_p)
183838fd1498Szrj {
183938fd1498Szrj if (!*non_constant_p && !reduced_constant_expression_p (t))
184038fd1498Szrj {
184138fd1498Szrj if (!allow_non_constant)
184238fd1498Szrj error ("%q+E is not a constant expression", t);
184338fd1498Szrj *non_constant_p = true;
184438fd1498Szrj }
184538fd1498Szrj if (TREE_OVERFLOW_P (t))
184638fd1498Szrj {
184738fd1498Szrj if (!allow_non_constant)
184838fd1498Szrj {
184938fd1498Szrj permerror (input_location, "overflow in constant expression");
185038fd1498Szrj /* If we're being permissive (and are in an enforcing
185138fd1498Szrj context), ignore the overflow. */
185238fd1498Szrj if (flag_permissive)
185338fd1498Szrj return *non_constant_p;
185438fd1498Szrj }
185538fd1498Szrj *overflow_p = true;
185638fd1498Szrj }
185738fd1498Szrj return *non_constant_p;
185838fd1498Szrj }
185938fd1498Szrj
186038fd1498Szrj /* Check whether the shift operation with code CODE and type TYPE on LHS
186138fd1498Szrj and RHS is undefined. If it is, give an error with an explanation,
186238fd1498Szrj and return true; return false otherwise. */
186338fd1498Szrj
186438fd1498Szrj static bool
cxx_eval_check_shift_p(location_t loc,const constexpr_ctx * ctx,enum tree_code code,tree type,tree lhs,tree rhs)186538fd1498Szrj cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
186638fd1498Szrj enum tree_code code, tree type, tree lhs, tree rhs)
186738fd1498Szrj {
186838fd1498Szrj if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR)
186938fd1498Szrj || TREE_CODE (lhs) != INTEGER_CST
187038fd1498Szrj || TREE_CODE (rhs) != INTEGER_CST)
187138fd1498Szrj return false;
187238fd1498Szrj
187338fd1498Szrj tree lhstype = TREE_TYPE (lhs);
187438fd1498Szrj unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
187538fd1498Szrj
187638fd1498Szrj /* [expr.shift] The behavior is undefined if the right operand
187738fd1498Szrj is negative, or greater than or equal to the length in bits
187838fd1498Szrj of the promoted left operand. */
187938fd1498Szrj if (tree_int_cst_sgn (rhs) == -1)
188038fd1498Szrj {
188138fd1498Szrj if (!ctx->quiet)
188238fd1498Szrj permerror (loc, "right operand of shift expression %q+E is negative",
188338fd1498Szrj build2_loc (loc, code, type, lhs, rhs));
188438fd1498Szrj return (!flag_permissive || ctx->quiet);
188538fd1498Szrj }
188638fd1498Szrj if (compare_tree_int (rhs, uprec) >= 0)
188738fd1498Szrj {
188838fd1498Szrj if (!ctx->quiet)
188938fd1498Szrj permerror (loc, "right operand of shift expression %q+E is >= than "
189038fd1498Szrj "the precision of the left operand",
189138fd1498Szrj build2_loc (loc, code, type, lhs, rhs));
189238fd1498Szrj return (!flag_permissive || ctx->quiet);
189338fd1498Szrj }
189438fd1498Szrj
189538fd1498Szrj /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...]
189638fd1498Szrj if E1 has a signed type and non-negative value, and E1x2^E2 is
189738fd1498Szrj representable in the corresponding unsigned type of the result type,
189838fd1498Szrj then that value, converted to the result type, is the resulting value;
189938fd1498Szrj otherwise, the behavior is undefined. */
190038fd1498Szrj if (code == LSHIFT_EXPR && !TYPE_UNSIGNED (lhstype)
190138fd1498Szrj && (cxx_dialect >= cxx11))
190238fd1498Szrj {
190338fd1498Szrj if (tree_int_cst_sgn (lhs) == -1)
190438fd1498Szrj {
190538fd1498Szrj if (!ctx->quiet)
190638fd1498Szrj permerror (loc,
190738fd1498Szrj "left operand of shift expression %q+E is negative",
190838fd1498Szrj build2_loc (loc, code, type, lhs, rhs));
190938fd1498Szrj return (!flag_permissive || ctx->quiet);
191038fd1498Szrj }
191138fd1498Szrj /* For signed x << y the following:
191238fd1498Szrj (unsigned) x >> ((prec (lhs) - 1) - y)
191338fd1498Szrj if > 1, is undefined. The right-hand side of this formula
191438fd1498Szrj is the highest bit of the LHS that can be set (starting from 0),
191538fd1498Szrj so that the shift doesn't overflow. We then right-shift the LHS
191638fd1498Szrj to see whether any other bit is set making the original shift
191738fd1498Szrj undefined -- the result is not representable in the corresponding
191838fd1498Szrj unsigned type. */
191938fd1498Szrj tree t = build_int_cst (unsigned_type_node, uprec - 1);
192038fd1498Szrj t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
192138fd1498Szrj tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
192238fd1498Szrj t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
192338fd1498Szrj if (tree_int_cst_lt (integer_one_node, t))
192438fd1498Szrj {
192538fd1498Szrj if (!ctx->quiet)
192638fd1498Szrj permerror (loc, "shift expression %q+E overflows",
192738fd1498Szrj build2_loc (loc, code, type, lhs, rhs));
192838fd1498Szrj return (!flag_permissive || ctx->quiet);
192938fd1498Szrj }
193038fd1498Szrj }
193138fd1498Szrj return false;
193238fd1498Szrj }
193338fd1498Szrj
193438fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
193538fd1498Szrj Attempt to reduce the unary expression tree T to a compile time value.
193638fd1498Szrj If successful, return the value. Otherwise issue a diagnostic
193738fd1498Szrj and return error_mark_node. */
193838fd1498Szrj
193938fd1498Szrj static tree
cxx_eval_unary_expression(const constexpr_ctx * ctx,tree t,bool,bool * non_constant_p,bool * overflow_p)194038fd1498Szrj cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
194138fd1498Szrj bool /*lval*/,
194238fd1498Szrj bool *non_constant_p, bool *overflow_p)
194338fd1498Szrj {
194438fd1498Szrj tree r;
194538fd1498Szrj tree orig_arg = TREE_OPERAND (t, 0);
194638fd1498Szrj tree arg = cxx_eval_constant_expression (ctx, orig_arg, /*lval*/false,
194738fd1498Szrj non_constant_p, overflow_p);
194838fd1498Szrj VERIFY_CONSTANT (arg);
194938fd1498Szrj location_t loc = EXPR_LOCATION (t);
195038fd1498Szrj enum tree_code code = TREE_CODE (t);
195138fd1498Szrj tree type = TREE_TYPE (t);
195238fd1498Szrj r = fold_unary_loc (loc, code, type, arg);
195338fd1498Szrj if (r == NULL_TREE)
195438fd1498Szrj {
195538fd1498Szrj if (arg == orig_arg)
195638fd1498Szrj r = t;
195738fd1498Szrj else
195838fd1498Szrj r = build1_loc (loc, code, type, arg);
195938fd1498Szrj }
196038fd1498Szrj VERIFY_CONSTANT (r);
196138fd1498Szrj return r;
196238fd1498Szrj }
196338fd1498Szrj
196438fd1498Szrj /* Helper function for cxx_eval_binary_expression. Try to optimize
196538fd1498Szrj original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
196638fd1498Szrj generic folding should be used. */
196738fd1498Szrj
196838fd1498Szrj static tree
cxx_fold_pointer_plus_expression(const constexpr_ctx * ctx,tree t,tree lhs,tree rhs,bool * non_constant_p,bool * overflow_p)196938fd1498Szrj cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
197038fd1498Szrj tree lhs, tree rhs, bool *non_constant_p,
197138fd1498Szrj bool *overflow_p)
197238fd1498Szrj {
197338fd1498Szrj STRIP_NOPS (lhs);
197438fd1498Szrj if (TREE_CODE (lhs) != ADDR_EXPR)
197538fd1498Szrj return NULL_TREE;
197638fd1498Szrj
197738fd1498Szrj lhs = TREE_OPERAND (lhs, 0);
197838fd1498Szrj
197938fd1498Szrj /* &A[i] p+ j => &A[i + j] */
198038fd1498Szrj if (TREE_CODE (lhs) == ARRAY_REF
198138fd1498Szrj && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
198238fd1498Szrj && TREE_CODE (rhs) == INTEGER_CST
198338fd1498Szrj && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
198438fd1498Szrj && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
198538fd1498Szrj {
198638fd1498Szrj tree orig_type = TREE_TYPE (t);
198738fd1498Szrj location_t loc = EXPR_LOCATION (t);
198838fd1498Szrj tree type = TREE_TYPE (lhs);
198938fd1498Szrj
199038fd1498Szrj t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
199138fd1498Szrj tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
199238fd1498Szrj nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
199338fd1498Szrj overflow_p);
199438fd1498Szrj if (*non_constant_p)
199538fd1498Szrj return NULL_TREE;
199638fd1498Szrj /* Don't fold an out-of-bound access. */
199738fd1498Szrj if (!tree_int_cst_le (t, nelts))
199838fd1498Szrj return NULL_TREE;
199938fd1498Szrj rhs = cp_fold_convert (ssizetype, rhs);
200038fd1498Szrj /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
200138fd1498Szrj constexpr int A[1]; ... (char *)&A[0] + 1 */
200238fd1498Szrj if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
200338fd1498Szrj rhs, TYPE_SIZE_UNIT (type))))
200438fd1498Szrj return NULL_TREE;
200538fd1498Szrj /* Make sure to treat the second operand of POINTER_PLUS_EXPR
200638fd1498Szrj as signed. */
200738fd1498Szrj rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
200838fd1498Szrj TYPE_SIZE_UNIT (type));
200938fd1498Szrj t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
201038fd1498Szrj t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0),
201138fd1498Szrj t, NULL_TREE, NULL_TREE);
201238fd1498Szrj t = cp_build_addr_expr (t, tf_warning_or_error);
201338fd1498Szrj t = cp_fold_convert (orig_type, t);
201438fd1498Szrj return cxx_eval_constant_expression (ctx, t, /*lval*/false,
201538fd1498Szrj non_constant_p, overflow_p);
201638fd1498Szrj }
201738fd1498Szrj
201838fd1498Szrj return NULL_TREE;
201938fd1498Szrj }
202038fd1498Szrj
202138fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
202238fd1498Szrj Like cxx_eval_unary_expression, except for binary expressions. */
202338fd1498Szrj
202438fd1498Szrj static tree
cxx_eval_binary_expression(const constexpr_ctx * ctx,tree t,bool,bool * non_constant_p,bool * overflow_p)202538fd1498Szrj cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
202638fd1498Szrj bool /*lval*/,
202738fd1498Szrj bool *non_constant_p, bool *overflow_p)
202838fd1498Szrj {
202938fd1498Szrj tree r = NULL_TREE;
203038fd1498Szrj tree orig_lhs = TREE_OPERAND (t, 0);
203138fd1498Szrj tree orig_rhs = TREE_OPERAND (t, 1);
203238fd1498Szrj tree lhs, rhs;
203338fd1498Szrj lhs = cxx_eval_constant_expression (ctx, orig_lhs, /*lval*/false,
203438fd1498Szrj non_constant_p, overflow_p);
203538fd1498Szrj /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
203638fd1498Szrj subtraction. */
203738fd1498Szrj if (*non_constant_p)
203838fd1498Szrj return t;
203938fd1498Szrj rhs = cxx_eval_constant_expression (ctx, orig_rhs, /*lval*/false,
204038fd1498Szrj non_constant_p, overflow_p);
204138fd1498Szrj if (*non_constant_p)
204238fd1498Szrj return t;
204338fd1498Szrj
204438fd1498Szrj location_t loc = EXPR_LOCATION (t);
204538fd1498Szrj enum tree_code code = TREE_CODE (t);
204638fd1498Szrj tree type = TREE_TYPE (t);
204738fd1498Szrj
204838fd1498Szrj if (code == EQ_EXPR || code == NE_EXPR)
204938fd1498Szrj {
205038fd1498Szrj bool is_code_eq = (code == EQ_EXPR);
205138fd1498Szrj
205238fd1498Szrj if (TREE_CODE (lhs) == PTRMEM_CST
205338fd1498Szrj && TREE_CODE (rhs) == PTRMEM_CST)
205438fd1498Szrj r = constant_boolean_node (cp_tree_equal (lhs, rhs) == is_code_eq,
205538fd1498Szrj type);
205638fd1498Szrj else if ((TREE_CODE (lhs) == PTRMEM_CST
205738fd1498Szrj || TREE_CODE (rhs) == PTRMEM_CST)
205838fd1498Szrj && (null_member_pointer_value_p (lhs)
205938fd1498Szrj || null_member_pointer_value_p (rhs)))
206038fd1498Szrj r = constant_boolean_node (!is_code_eq, type);
206138fd1498Szrj else if (TREE_CODE (lhs) == PTRMEM_CST)
206238fd1498Szrj lhs = cplus_expand_constant (lhs);
206338fd1498Szrj else if (TREE_CODE (rhs) == PTRMEM_CST)
206438fd1498Szrj rhs = cplus_expand_constant (rhs);
206538fd1498Szrj }
206638fd1498Szrj if (code == POINTER_PLUS_EXPR && !*non_constant_p
206738fd1498Szrj && integer_zerop (lhs) && !integer_zerop (rhs))
206838fd1498Szrj {
206938fd1498Szrj if (!ctx->quiet)
207038fd1498Szrj error ("arithmetic involving a null pointer in %qE", lhs);
2071*58e805e6Szrj *non_constant_p = true;
207238fd1498Szrj return t;
207338fd1498Szrj }
207438fd1498Szrj else if (code == POINTER_PLUS_EXPR)
207538fd1498Szrj r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
207638fd1498Szrj overflow_p);
207738fd1498Szrj
207838fd1498Szrj if (r == NULL_TREE)
207938fd1498Szrj r = fold_binary_loc (loc, code, type, lhs, rhs);
208038fd1498Szrj
208138fd1498Szrj if (r == NULL_TREE)
208238fd1498Szrj {
208338fd1498Szrj if (lhs == orig_lhs && rhs == orig_rhs)
208438fd1498Szrj r = t;
208538fd1498Szrj else
208638fd1498Szrj r = build2_loc (loc, code, type, lhs, rhs);
208738fd1498Szrj }
208838fd1498Szrj else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
208938fd1498Szrj *non_constant_p = true;
209038fd1498Szrj /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
209138fd1498Szrj a local array in a constexpr function. */
209238fd1498Szrj bool ptr = POINTER_TYPE_P (TREE_TYPE (lhs));
209338fd1498Szrj if (!ptr)
209438fd1498Szrj VERIFY_CONSTANT (r);
209538fd1498Szrj return r;
209638fd1498Szrj }
209738fd1498Szrj
209838fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
209938fd1498Szrj Attempt to evaluate condition expressions. Dead branches are not
210038fd1498Szrj looked into. */
210138fd1498Szrj
210238fd1498Szrj static tree
cxx_eval_conditional_expression(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p,tree * jump_target)210338fd1498Szrj cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
210438fd1498Szrj bool lval,
210538fd1498Szrj bool *non_constant_p, bool *overflow_p,
210638fd1498Szrj tree *jump_target)
210738fd1498Szrj {
210838fd1498Szrj tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
210938fd1498Szrj /*lval*/false,
211038fd1498Szrj non_constant_p, overflow_p);
211138fd1498Szrj VERIFY_CONSTANT (val);
211238fd1498Szrj /* Don't VERIFY_CONSTANT the other operands. */
211338fd1498Szrj if (integer_zerop (val))
211438fd1498Szrj return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
211538fd1498Szrj lval,
211638fd1498Szrj non_constant_p, overflow_p,
211738fd1498Szrj jump_target);
211838fd1498Szrj return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
211938fd1498Szrj lval,
212038fd1498Szrj non_constant_p, overflow_p,
212138fd1498Szrj jump_target);
212238fd1498Szrj }
212338fd1498Szrj
212438fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
212538fd1498Szrj Attempt to evaluate vector condition expressions. Unlike
212638fd1498Szrj cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal
212738fd1498Szrj ternary arithmetics operation, where all 3 arguments have to be
212838fd1498Szrj evaluated as constants and then folding computes the result from
212938fd1498Szrj them. */
213038fd1498Szrj
213138fd1498Szrj static tree
cxx_eval_vector_conditional_expression(const constexpr_ctx * ctx,tree t,bool * non_constant_p,bool * overflow_p)213238fd1498Szrj cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
213338fd1498Szrj bool *non_constant_p, bool *overflow_p)
213438fd1498Szrj {
213538fd1498Szrj tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
213638fd1498Szrj /*lval*/false,
213738fd1498Szrj non_constant_p, overflow_p);
213838fd1498Szrj VERIFY_CONSTANT (arg1);
213938fd1498Szrj tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
214038fd1498Szrj /*lval*/false,
214138fd1498Szrj non_constant_p, overflow_p);
214238fd1498Szrj VERIFY_CONSTANT (arg2);
214338fd1498Szrj tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
214438fd1498Szrj /*lval*/false,
214538fd1498Szrj non_constant_p, overflow_p);
214638fd1498Szrj VERIFY_CONSTANT (arg3);
214738fd1498Szrj location_t loc = EXPR_LOCATION (t);
214838fd1498Szrj tree type = TREE_TYPE (t);
214938fd1498Szrj tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
215038fd1498Szrj if (r == NULL_TREE)
215138fd1498Szrj {
215238fd1498Szrj if (arg1 == TREE_OPERAND (t, 0)
215338fd1498Szrj && arg2 == TREE_OPERAND (t, 1)
215438fd1498Szrj && arg3 == TREE_OPERAND (t, 2))
215538fd1498Szrj r = t;
215638fd1498Szrj else
215738fd1498Szrj r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
215838fd1498Szrj }
215938fd1498Szrj VERIFY_CONSTANT (r);
216038fd1498Szrj return r;
216138fd1498Szrj }
216238fd1498Szrj
216338fd1498Szrj /* Returns less than, equal to, or greater than zero if KEY is found to be
216438fd1498Szrj less than, to match, or to be greater than the constructor_elt's INDEX. */
216538fd1498Szrj
216638fd1498Szrj static int
array_index_cmp(tree key,tree index)216738fd1498Szrj array_index_cmp (tree key, tree index)
216838fd1498Szrj {
216938fd1498Szrj gcc_assert (TREE_CODE (key) == INTEGER_CST);
217038fd1498Szrj
217138fd1498Szrj switch (TREE_CODE (index))
217238fd1498Szrj {
217338fd1498Szrj case INTEGER_CST:
217438fd1498Szrj return tree_int_cst_compare (key, index);
217538fd1498Szrj case RANGE_EXPR:
217638fd1498Szrj {
217738fd1498Szrj tree lo = TREE_OPERAND (index, 0);
217838fd1498Szrj tree hi = TREE_OPERAND (index, 1);
217938fd1498Szrj if (tree_int_cst_lt (key, lo))
218038fd1498Szrj return -1;
218138fd1498Szrj else if (tree_int_cst_lt (hi, key))
218238fd1498Szrj return 1;
218338fd1498Szrj else
218438fd1498Szrj return 0;
218538fd1498Szrj }
218638fd1498Szrj default:
218738fd1498Szrj gcc_unreachable ();
218838fd1498Szrj }
218938fd1498Szrj }
219038fd1498Szrj
219138fd1498Szrj /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1
219238fd1498Szrj if none. If INSERT is true, insert a matching element rather than fail. */
219338fd1498Szrj
219438fd1498Szrj static HOST_WIDE_INT
219538fd1498Szrj find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
219638fd1498Szrj {
219738fd1498Szrj if (tree_int_cst_sgn (dindex) < 0)
219838fd1498Szrj return -1;
219938fd1498Szrj
220038fd1498Szrj unsigned HOST_WIDE_INT i = tree_to_uhwi (dindex);
220138fd1498Szrj vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary);
220238fd1498Szrj unsigned HOST_WIDE_INT len = vec_safe_length (elts);
220338fd1498Szrj
220438fd1498Szrj unsigned HOST_WIDE_INT end = len;
220538fd1498Szrj unsigned HOST_WIDE_INT begin = 0;
220638fd1498Szrj
220738fd1498Szrj /* If the last element of the CONSTRUCTOR has its own index, we can assume
220838fd1498Szrj that the same is true of the other elements and index directly. */
220938fd1498Szrj if (end > 0)
221038fd1498Szrj {
221138fd1498Szrj tree cindex = (*elts)[end - 1].index;
221238fd1498Szrj if (TREE_CODE (cindex) == INTEGER_CST
221338fd1498Szrj && compare_tree_int (cindex, end - 1) == 0)
221438fd1498Szrj {
221538fd1498Szrj if (i < end)
221638fd1498Szrj return i;
221738fd1498Szrj else
221838fd1498Szrj begin = end;
221938fd1498Szrj }
222038fd1498Szrj }
222138fd1498Szrj
222238fd1498Szrj /* Otherwise, find a matching index by means of a binary search. */
222338fd1498Szrj while (begin != end)
222438fd1498Szrj {
222538fd1498Szrj unsigned HOST_WIDE_INT middle = (begin + end) / 2;
222638fd1498Szrj constructor_elt &elt = (*elts)[middle];
222738fd1498Szrj tree idx = elt.index;
222838fd1498Szrj
222938fd1498Szrj int cmp = array_index_cmp (dindex, idx);
223038fd1498Szrj if (cmp < 0)
223138fd1498Szrj end = middle;
223238fd1498Szrj else if (cmp > 0)
223338fd1498Szrj begin = middle + 1;
223438fd1498Szrj else
223538fd1498Szrj {
223638fd1498Szrj if (insert && TREE_CODE (idx) == RANGE_EXPR)
223738fd1498Szrj {
223838fd1498Szrj /* We need to split the range. */
223938fd1498Szrj constructor_elt e;
224038fd1498Szrj tree lo = TREE_OPERAND (idx, 0);
224138fd1498Szrj tree hi = TREE_OPERAND (idx, 1);
224238fd1498Szrj tree value = elt.value;
224338fd1498Szrj dindex = fold_convert (sizetype, dindex);
224438fd1498Szrj if (tree_int_cst_lt (lo, dindex))
224538fd1498Szrj {
224638fd1498Szrj /* There are still some lower elts; shorten the range. */
224738fd1498Szrj tree new_hi = int_const_binop (MINUS_EXPR, dindex,
224838fd1498Szrj size_one_node);
224938fd1498Szrj if (tree_int_cst_equal (lo, new_hi))
225038fd1498Szrj /* Only one element left, no longer a range. */
225138fd1498Szrj elt.index = lo;
225238fd1498Szrj else
225338fd1498Szrj TREE_OPERAND (idx, 1) = new_hi;
225438fd1498Szrj /* Append the element we want to insert. */
225538fd1498Szrj ++middle;
225638fd1498Szrj e.index = dindex;
225738fd1498Szrj e.value = unshare_constructor (value);
225838fd1498Szrj vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
225938fd1498Szrj }
226038fd1498Szrj else
226138fd1498Szrj /* No lower elts, the range elt is now ours. */
226238fd1498Szrj elt.index = dindex;
226338fd1498Szrj
226438fd1498Szrj if (tree_int_cst_lt (dindex, hi))
226538fd1498Szrj {
226638fd1498Szrj /* There are still some higher elts; append a range. */
226738fd1498Szrj tree new_lo = int_const_binop (PLUS_EXPR, dindex,
226838fd1498Szrj size_one_node);
226938fd1498Szrj if (tree_int_cst_equal (new_lo, hi))
227038fd1498Szrj e.index = hi;
227138fd1498Szrj else
227238fd1498Szrj e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
227338fd1498Szrj e.value = unshare_constructor (value);
227438fd1498Szrj vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
227538fd1498Szrj }
227638fd1498Szrj }
227738fd1498Szrj return middle;
227838fd1498Szrj }
227938fd1498Szrj }
228038fd1498Szrj
228138fd1498Szrj if (insert)
228238fd1498Szrj {
228338fd1498Szrj constructor_elt e = { dindex, NULL_TREE };
228438fd1498Szrj vec_safe_insert (CONSTRUCTOR_ELTS (ary), end, e);
228538fd1498Szrj return end;
228638fd1498Szrj }
228738fd1498Szrj
228838fd1498Szrj return -1;
228938fd1498Szrj }
229038fd1498Szrj
229138fd1498Szrj /* Under the control of CTX, issue a detailed diagnostic for
229238fd1498Szrj an out-of-bounds subscript INDEX into the expression ARRAY. */
229338fd1498Szrj
229438fd1498Szrj static void
diag_array_subscript(const constexpr_ctx * ctx,tree array,tree index)229538fd1498Szrj diag_array_subscript (const constexpr_ctx *ctx, tree array, tree index)
229638fd1498Szrj {
229738fd1498Szrj if (!ctx->quiet)
229838fd1498Szrj {
229938fd1498Szrj tree arraytype = TREE_TYPE (array);
230038fd1498Szrj
230138fd1498Szrj /* Convert the unsigned array subscript to a signed integer to avoid
230238fd1498Szrj printing huge numbers for small negative values. */
230338fd1498Szrj tree sidx = fold_convert (ssizetype, index);
230438fd1498Szrj if (DECL_P (array))
230538fd1498Szrj {
230638fd1498Szrj if (TYPE_DOMAIN (arraytype))
230738fd1498Szrj error ("array subscript value %qE is outside the bounds "
230838fd1498Szrj "of array %qD of type %qT", sidx, array, arraytype);
230938fd1498Szrj else
231038fd1498Szrj error ("non-zero array subscript %qE is used with array %qD of "
231138fd1498Szrj "type %qT with unknown bounds", sidx, array, arraytype);
231238fd1498Szrj inform (DECL_SOURCE_LOCATION (array), "declared here");
231338fd1498Szrj }
231438fd1498Szrj else if (TYPE_DOMAIN (arraytype))
231538fd1498Szrj error ("array subscript value %qE is outside the bounds "
231638fd1498Szrj "of array type %qT", sidx, arraytype);
231738fd1498Szrj else
231838fd1498Szrj error ("non-zero array subscript %qE is used with array of type %qT "
231938fd1498Szrj "with unknown bounds", sidx, arraytype);
232038fd1498Szrj }
232138fd1498Szrj }
232238fd1498Szrj
232338fd1498Szrj /* Return the number of elements for TYPE (which is an ARRAY_TYPE or
232438fd1498Szrj a VECTOR_TYPE). */
232538fd1498Szrj
232638fd1498Szrj static tree
get_array_or_vector_nelts(const constexpr_ctx * ctx,tree type,bool * non_constant_p,bool * overflow_p)232738fd1498Szrj get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
232838fd1498Szrj bool *non_constant_p, bool *overflow_p)
232938fd1498Szrj {
233038fd1498Szrj tree nelts;
233138fd1498Szrj if (TREE_CODE (type) == ARRAY_TYPE)
233238fd1498Szrj {
233338fd1498Szrj if (TYPE_DOMAIN (type))
233438fd1498Szrj nelts = array_type_nelts_top (type);
233538fd1498Szrj else
233638fd1498Szrj nelts = size_zero_node;
233738fd1498Szrj }
233838fd1498Szrj else if (VECTOR_TYPE_P (type))
233938fd1498Szrj nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
234038fd1498Szrj else
234138fd1498Szrj gcc_unreachable ();
234238fd1498Szrj
234338fd1498Szrj /* For VLAs, the number of elements won't be an integer constant. */
234438fd1498Szrj nelts = cxx_eval_constant_expression (ctx, nelts, false,
234538fd1498Szrj non_constant_p, overflow_p);
234638fd1498Szrj return nelts;
234738fd1498Szrj }
234838fd1498Szrj
234938fd1498Szrj /* Extract element INDEX consisting of CHARS_PER_ELT chars from
235038fd1498Szrj STRING_CST STRING. */
235138fd1498Szrj
235238fd1498Szrj static tree
extract_string_elt(tree string,unsigned chars_per_elt,unsigned index)235338fd1498Szrj extract_string_elt (tree string, unsigned chars_per_elt, unsigned index)
235438fd1498Szrj {
235538fd1498Szrj tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string)));
235638fd1498Szrj tree r;
235738fd1498Szrj
235838fd1498Szrj if (chars_per_elt == 1)
235938fd1498Szrj r = build_int_cst (type, TREE_STRING_POINTER (string)[index]);
236038fd1498Szrj else
236138fd1498Szrj {
236238fd1498Szrj const unsigned char *ptr
236338fd1498Szrj = ((const unsigned char *)TREE_STRING_POINTER (string)
236438fd1498Szrj + index * chars_per_elt);
236538fd1498Szrj r = native_interpret_expr (type, ptr, chars_per_elt);
236638fd1498Szrj }
236738fd1498Szrj return r;
236838fd1498Szrj }
236938fd1498Szrj
237038fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
237138fd1498Szrj Attempt to reduce a reference to an array slot. */
237238fd1498Szrj
237338fd1498Szrj static tree
cxx_eval_array_reference(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)237438fd1498Szrj cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
237538fd1498Szrj bool lval,
237638fd1498Szrj bool *non_constant_p, bool *overflow_p)
237738fd1498Szrj {
237838fd1498Szrj tree oldary = TREE_OPERAND (t, 0);
237938fd1498Szrj tree ary = cxx_eval_constant_expression (ctx, oldary,
238038fd1498Szrj lval,
238138fd1498Szrj non_constant_p, overflow_p);
238238fd1498Szrj tree index, oldidx;
238338fd1498Szrj HOST_WIDE_INT i = 0;
238438fd1498Szrj tree elem_type = NULL_TREE;
238538fd1498Szrj unsigned len = 0, elem_nchars = 1;
238638fd1498Szrj if (*non_constant_p)
238738fd1498Szrj return t;
238838fd1498Szrj oldidx = TREE_OPERAND (t, 1);
238938fd1498Szrj index = cxx_eval_constant_expression (ctx, oldidx,
239038fd1498Szrj false,
239138fd1498Szrj non_constant_p, overflow_p);
239238fd1498Szrj VERIFY_CONSTANT (index);
239338fd1498Szrj if (!lval)
239438fd1498Szrj {
239538fd1498Szrj elem_type = TREE_TYPE (TREE_TYPE (ary));
239638fd1498Szrj if (TREE_CODE (ary) == VIEW_CONVERT_EXPR
239738fd1498Szrj && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
239838fd1498Szrj && TREE_TYPE (t) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))
239938fd1498Szrj ary = TREE_OPERAND (ary, 0);
240038fd1498Szrj if (TREE_CODE (ary) == CONSTRUCTOR)
240138fd1498Szrj len = CONSTRUCTOR_NELTS (ary);
240238fd1498Szrj else if (TREE_CODE (ary) == STRING_CST)
240338fd1498Szrj {
240438fd1498Szrj elem_nchars = (TYPE_PRECISION (elem_type)
240538fd1498Szrj / TYPE_PRECISION (char_type_node));
240638fd1498Szrj len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
240738fd1498Szrj }
240838fd1498Szrj else if (TREE_CODE (ary) == VECTOR_CST)
240938fd1498Szrj /* We don't create variable-length VECTOR_CSTs. */
241038fd1498Szrj len = VECTOR_CST_NELTS (ary).to_constant ();
241138fd1498Szrj else
241238fd1498Szrj {
241338fd1498Szrj /* We can't do anything with other tree codes, so use
241438fd1498Szrj VERIFY_CONSTANT to complain and fail. */
241538fd1498Szrj VERIFY_CONSTANT (ary);
241638fd1498Szrj gcc_unreachable ();
241738fd1498Szrj }
241838fd1498Szrj
241938fd1498Szrj if (!tree_fits_shwi_p (index)
242038fd1498Szrj || (i = tree_to_shwi (index)) < 0)
242138fd1498Szrj {
242238fd1498Szrj diag_array_subscript (ctx, ary, index);
242338fd1498Szrj *non_constant_p = true;
242438fd1498Szrj return t;
242538fd1498Szrj }
242638fd1498Szrj }
242738fd1498Szrj
242838fd1498Szrj tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
242938fd1498Szrj overflow_p);
243038fd1498Szrj VERIFY_CONSTANT (nelts);
243138fd1498Szrj if ((lval
243238fd1498Szrj ? !tree_int_cst_le (index, nelts)
243338fd1498Szrj : !tree_int_cst_lt (index, nelts))
243438fd1498Szrj || tree_int_cst_sgn (index) < 0)
243538fd1498Szrj {
243638fd1498Szrj diag_array_subscript (ctx, ary, index);
243738fd1498Szrj *non_constant_p = true;
243838fd1498Szrj return t;
243938fd1498Szrj }
244038fd1498Szrj
244138fd1498Szrj if (lval && ary == oldary && index == oldidx)
244238fd1498Szrj return t;
244338fd1498Szrj else if (lval)
244438fd1498Szrj return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
244538fd1498Szrj
244638fd1498Szrj bool found;
244738fd1498Szrj if (TREE_CODE (ary) == CONSTRUCTOR)
244838fd1498Szrj {
244938fd1498Szrj HOST_WIDE_INT ix = find_array_ctor_elt (ary, index);
245038fd1498Szrj found = (ix >= 0);
245138fd1498Szrj if (found)
245238fd1498Szrj i = ix;
245338fd1498Szrj }
245438fd1498Szrj else
245538fd1498Szrj found = (i < len);
245638fd1498Szrj
245738fd1498Szrj if (found)
245838fd1498Szrj {
245938fd1498Szrj tree r;
246038fd1498Szrj if (TREE_CODE (ary) == CONSTRUCTOR)
246138fd1498Szrj r = (*CONSTRUCTOR_ELTS (ary))[i].value;
246238fd1498Szrj else if (TREE_CODE (ary) == VECTOR_CST)
246338fd1498Szrj r = VECTOR_CST_ELT (ary, i);
246438fd1498Szrj else
246538fd1498Szrj r = extract_string_elt (ary, elem_nchars, i);
246638fd1498Szrj
246738fd1498Szrj if (r)
246838fd1498Szrj /* Don't VERIFY_CONSTANT here. */
246938fd1498Szrj return r;
247038fd1498Szrj
247138fd1498Szrj /* Otherwise the element doesn't have a value yet. */
247238fd1498Szrj }
247338fd1498Szrj
247438fd1498Szrj /* Not found. */
247538fd1498Szrj
247638fd1498Szrj if (TREE_CODE (ary) == CONSTRUCTOR
247738fd1498Szrj && CONSTRUCTOR_NO_IMPLICIT_ZERO (ary))
247838fd1498Szrj {
247938fd1498Szrj /* 'ary' is part of the aggregate initializer we're currently
248038fd1498Szrj building; if there's no initializer for this element yet,
248138fd1498Szrj that's an error. */
248238fd1498Szrj if (!ctx->quiet)
248338fd1498Szrj error ("accessing uninitialized array element");
248438fd1498Szrj *non_constant_p = true;
248538fd1498Szrj return t;
248638fd1498Szrj }
248738fd1498Szrj
248838fd1498Szrj /* If it's within the array bounds but doesn't have an explicit
248938fd1498Szrj initializer, it's value-initialized. */
249038fd1498Szrj tree val = build_value_init (elem_type, tf_warning_or_error);
249138fd1498Szrj return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
249238fd1498Szrj overflow_p);
249338fd1498Szrj }
249438fd1498Szrj
249538fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
249638fd1498Szrj Attempt to reduce a field access of a value of class type. */
249738fd1498Szrj
249838fd1498Szrj static tree
cxx_eval_component_reference(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)249938fd1498Szrj cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
250038fd1498Szrj bool lval,
250138fd1498Szrj bool *non_constant_p, bool *overflow_p)
250238fd1498Szrj {
250338fd1498Szrj unsigned HOST_WIDE_INT i;
250438fd1498Szrj tree field;
250538fd1498Szrj tree value;
250638fd1498Szrj tree part = TREE_OPERAND (t, 1);
250738fd1498Szrj tree orig_whole = TREE_OPERAND (t, 0);
250838fd1498Szrj tree whole = cxx_eval_constant_expression (ctx, orig_whole,
250938fd1498Szrj lval,
251038fd1498Szrj non_constant_p, overflow_p);
251138fd1498Szrj if (INDIRECT_REF_P (whole)
2512*58e805e6Szrj && integer_zerop (TREE_OPERAND (whole, 0)))
2513*58e805e6Szrj {
2514*58e805e6Szrj if (!ctx->quiet)
251538fd1498Szrj error ("dereferencing a null pointer in %qE", orig_whole);
2516*58e805e6Szrj *non_constant_p = true;
2517*58e805e6Szrj return t;
2518*58e805e6Szrj }
251938fd1498Szrj
252038fd1498Szrj if (TREE_CODE (whole) == PTRMEM_CST)
252138fd1498Szrj whole = cplus_expand_constant (whole);
252238fd1498Szrj if (whole == orig_whole)
252338fd1498Szrj return t;
252438fd1498Szrj if (lval)
252538fd1498Szrj return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
252638fd1498Szrj whole, part, NULL_TREE);
252738fd1498Szrj /* Don't VERIFY_CONSTANT here; we only want to check that we got a
252838fd1498Szrj CONSTRUCTOR. */
252938fd1498Szrj if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
253038fd1498Szrj {
253138fd1498Szrj if (!ctx->quiet)
253238fd1498Szrj error ("%qE is not a constant expression", orig_whole);
253338fd1498Szrj *non_constant_p = true;
253438fd1498Szrj }
253538fd1498Szrj if (DECL_MUTABLE_P (part))
253638fd1498Szrj {
253738fd1498Szrj if (!ctx->quiet)
253838fd1498Szrj error ("mutable %qD is not usable in a constant expression", part);
253938fd1498Szrj *non_constant_p = true;
254038fd1498Szrj }
254138fd1498Szrj if (*non_constant_p)
254238fd1498Szrj return t;
254338fd1498Szrj bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole));
254438fd1498Szrj FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
254538fd1498Szrj {
254638fd1498Szrj /* Use name match for PMF fields, as a variant will have a
254738fd1498Szrj different FIELD_DECL with a different type. */
254838fd1498Szrj if (pmf ? DECL_NAME (field) == DECL_NAME (part)
254938fd1498Szrj : field == part)
255038fd1498Szrj {
255138fd1498Szrj if (value)
255238fd1498Szrj return value;
255338fd1498Szrj else
255438fd1498Szrj /* We're in the middle of initializing it. */
255538fd1498Szrj break;
255638fd1498Szrj }
255738fd1498Szrj }
255838fd1498Szrj if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE
255938fd1498Szrj && CONSTRUCTOR_NELTS (whole) > 0)
256038fd1498Szrj {
256138fd1498Szrj /* DR 1188 says we don't have to deal with this. */
256238fd1498Szrj if (!ctx->quiet)
256338fd1498Szrj error ("accessing %qD member instead of initialized %qD member in "
256438fd1498Szrj "constant expression", part, CONSTRUCTOR_ELT (whole, 0)->index);
256538fd1498Szrj *non_constant_p = true;
256638fd1498Szrj return t;
256738fd1498Szrj }
256838fd1498Szrj
256938fd1498Szrj /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
257038fd1498Szrj classes never get represented; throw together a value now. */
257138fd1498Szrj if (is_really_empty_class (TREE_TYPE (t)))
257238fd1498Szrj return build_constructor (TREE_TYPE (t), NULL);
257338fd1498Szrj
257438fd1498Szrj gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)));
257538fd1498Szrj
257638fd1498Szrj if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole))
257738fd1498Szrj {
257838fd1498Szrj /* 'whole' is part of the aggregate initializer we're currently
257938fd1498Szrj building; if there's no initializer for this member yet, that's an
258038fd1498Szrj error. */
258138fd1498Szrj if (!ctx->quiet)
258238fd1498Szrj error ("accessing uninitialized member %qD", part);
258338fd1498Szrj *non_constant_p = true;
258438fd1498Szrj return t;
258538fd1498Szrj }
258638fd1498Szrj
258738fd1498Szrj /* If there's no explicit init for this field, it's value-initialized. */
258838fd1498Szrj value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
258938fd1498Szrj return cxx_eval_constant_expression (ctx, value,
259038fd1498Szrj lval,
259138fd1498Szrj non_constant_p, overflow_p);
259238fd1498Szrj }
259338fd1498Szrj
259438fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
259538fd1498Szrj Attempt to reduce a field access of a value of class type that is
259638fd1498Szrj expressed as a BIT_FIELD_REF. */
259738fd1498Szrj
259838fd1498Szrj static tree
cxx_eval_bit_field_ref(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)259938fd1498Szrj cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
260038fd1498Szrj bool lval,
260138fd1498Szrj bool *non_constant_p, bool *overflow_p)
260238fd1498Szrj {
260338fd1498Szrj tree orig_whole = TREE_OPERAND (t, 0);
260438fd1498Szrj tree retval, fldval, utype, mask;
260538fd1498Szrj bool fld_seen = false;
260638fd1498Szrj HOST_WIDE_INT istart, isize;
260738fd1498Szrj tree whole = cxx_eval_constant_expression (ctx, orig_whole,
260838fd1498Szrj lval,
260938fd1498Szrj non_constant_p, overflow_p);
261038fd1498Szrj tree start, field, value;
261138fd1498Szrj unsigned HOST_WIDE_INT i;
261238fd1498Szrj
261338fd1498Szrj if (whole == orig_whole)
261438fd1498Szrj return t;
261538fd1498Szrj /* Don't VERIFY_CONSTANT here; we only want to check that we got a
261638fd1498Szrj CONSTRUCTOR. */
261738fd1498Szrj if (!*non_constant_p
261838fd1498Szrj && TREE_CODE (whole) != VECTOR_CST
261938fd1498Szrj && TREE_CODE (whole) != CONSTRUCTOR)
262038fd1498Szrj {
262138fd1498Szrj if (!ctx->quiet)
262238fd1498Szrj error ("%qE is not a constant expression", orig_whole);
262338fd1498Szrj *non_constant_p = true;
262438fd1498Szrj }
262538fd1498Szrj if (*non_constant_p)
262638fd1498Szrj return t;
262738fd1498Szrj
262838fd1498Szrj if (TREE_CODE (whole) == VECTOR_CST)
262938fd1498Szrj return fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
263038fd1498Szrj TREE_OPERAND (t, 1), TREE_OPERAND (t, 2));
263138fd1498Szrj
263238fd1498Szrj start = TREE_OPERAND (t, 2);
263338fd1498Szrj istart = tree_to_shwi (start);
263438fd1498Szrj isize = tree_to_shwi (TREE_OPERAND (t, 1));
263538fd1498Szrj utype = TREE_TYPE (t);
263638fd1498Szrj if (!TYPE_UNSIGNED (utype))
263738fd1498Szrj utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
263838fd1498Szrj retval = build_int_cst (utype, 0);
263938fd1498Szrj FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
264038fd1498Szrj {
264138fd1498Szrj tree bitpos = bit_position (field);
264238fd1498Szrj if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
264338fd1498Szrj return value;
264438fd1498Szrj if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
264538fd1498Szrj && TREE_CODE (value) == INTEGER_CST
264638fd1498Szrj && tree_fits_shwi_p (bitpos)
264738fd1498Szrj && tree_fits_shwi_p (DECL_SIZE (field)))
264838fd1498Szrj {
264938fd1498Szrj HOST_WIDE_INT bit = tree_to_shwi (bitpos);
265038fd1498Szrj HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field));
265138fd1498Szrj HOST_WIDE_INT shift;
265238fd1498Szrj if (bit >= istart && bit + sz <= istart + isize)
265338fd1498Szrj {
265438fd1498Szrj fldval = fold_convert (utype, value);
265538fd1498Szrj mask = build_int_cst_type (utype, -1);
265638fd1498Szrj mask = fold_build2 (LSHIFT_EXPR, utype, mask,
265738fd1498Szrj size_int (TYPE_PRECISION (utype) - sz));
265838fd1498Szrj mask = fold_build2 (RSHIFT_EXPR, utype, mask,
265938fd1498Szrj size_int (TYPE_PRECISION (utype) - sz));
266038fd1498Szrj fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask);
266138fd1498Szrj shift = bit - istart;
266238fd1498Szrj if (BYTES_BIG_ENDIAN)
266338fd1498Szrj shift = TYPE_PRECISION (utype) - shift - sz;
266438fd1498Szrj fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,
266538fd1498Szrj size_int (shift));
266638fd1498Szrj retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval);
266738fd1498Szrj fld_seen = true;
266838fd1498Szrj }
266938fd1498Szrj }
267038fd1498Szrj }
267138fd1498Szrj if (fld_seen)
267238fd1498Szrj return fold_convert (TREE_TYPE (t), retval);
267338fd1498Szrj gcc_unreachable ();
267438fd1498Szrj return error_mark_node;
267538fd1498Szrj }
267638fd1498Szrj
267738fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
267838fd1498Szrj Evaluate a short-circuited logical expression T in the context
267938fd1498Szrj of a given constexpr CALL. BAILOUT_VALUE is the value for
268038fd1498Szrj early return. CONTINUE_VALUE is used here purely for
268138fd1498Szrj sanity check purposes. */
268238fd1498Szrj
268338fd1498Szrj static tree
cxx_eval_logical_expression(const constexpr_ctx * ctx,tree t,tree bailout_value,tree continue_value,bool lval,bool * non_constant_p,bool * overflow_p)268438fd1498Szrj cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
268538fd1498Szrj tree bailout_value, tree continue_value,
268638fd1498Szrj bool lval,
268738fd1498Szrj bool *non_constant_p, bool *overflow_p)
268838fd1498Szrj {
268938fd1498Szrj tree r;
269038fd1498Szrj tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
269138fd1498Szrj lval,
269238fd1498Szrj non_constant_p, overflow_p);
269338fd1498Szrj VERIFY_CONSTANT (lhs);
269438fd1498Szrj if (tree_int_cst_equal (lhs, bailout_value))
269538fd1498Szrj return lhs;
269638fd1498Szrj gcc_assert (tree_int_cst_equal (lhs, continue_value));
269738fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
269838fd1498Szrj lval, non_constant_p,
269938fd1498Szrj overflow_p);
270038fd1498Szrj VERIFY_CONSTANT (r);
270138fd1498Szrj return r;
270238fd1498Szrj }
270338fd1498Szrj
270438fd1498Szrj /* REF is a COMPONENT_REF designating a particular field. V is a vector of
270538fd1498Szrj CONSTRUCTOR elements to initialize (part of) an object containing that
270638fd1498Szrj field. Return a pointer to the constructor_elt corresponding to the
270738fd1498Szrj initialization of the field. */
270838fd1498Szrj
270938fd1498Szrj static constructor_elt *
base_field_constructor_elt(vec<constructor_elt,va_gc> * v,tree ref)271038fd1498Szrj base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref)
271138fd1498Szrj {
271238fd1498Szrj tree aggr = TREE_OPERAND (ref, 0);
271338fd1498Szrj tree field = TREE_OPERAND (ref, 1);
271438fd1498Szrj HOST_WIDE_INT i;
271538fd1498Szrj constructor_elt *ce;
271638fd1498Szrj
271738fd1498Szrj gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
271838fd1498Szrj
271938fd1498Szrj if (TREE_CODE (aggr) == COMPONENT_REF)
272038fd1498Szrj {
272138fd1498Szrj constructor_elt *base_ce
272238fd1498Szrj = base_field_constructor_elt (v, aggr);
272338fd1498Szrj v = CONSTRUCTOR_ELTS (base_ce->value);
272438fd1498Szrj }
272538fd1498Szrj
272638fd1498Szrj for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
272738fd1498Szrj if (ce->index == field)
272838fd1498Szrj return ce;
272938fd1498Szrj
273038fd1498Szrj gcc_unreachable ();
273138fd1498Szrj return NULL;
273238fd1498Szrj }
273338fd1498Szrj
273438fd1498Szrj /* Some of the expressions fed to the constexpr mechanism are calls to
273538fd1498Szrj constructors, which have type void. In that case, return the type being
273638fd1498Szrj initialized by the constructor. */
273738fd1498Szrj
273838fd1498Szrj static tree
initialized_type(tree t)273938fd1498Szrj initialized_type (tree t)
274038fd1498Szrj {
274138fd1498Szrj if (TYPE_P (t))
274238fd1498Szrj return t;
274338fd1498Szrj tree type = cv_unqualified (TREE_TYPE (t));
274438fd1498Szrj if (TREE_CODE (t) == CALL_EXPR || TREE_CODE (t) == AGGR_INIT_EXPR)
274538fd1498Szrj {
274638fd1498Szrj /* A constructor call has void type, so we need to look deeper. */
274738fd1498Szrj tree fn = get_function_named_in_call (t);
274838fd1498Szrj if (fn && TREE_CODE (fn) == FUNCTION_DECL
274938fd1498Szrj && DECL_CXX_CONSTRUCTOR_P (fn))
275038fd1498Szrj type = DECL_CONTEXT (fn);
275138fd1498Szrj }
275238fd1498Szrj return type;
275338fd1498Szrj }
275438fd1498Szrj
275538fd1498Szrj /* We're about to initialize element INDEX of an array or class from VALUE.
275638fd1498Szrj Set up NEW_CTX appropriately by adjusting .object to refer to the
275738fd1498Szrj subobject and creating a new CONSTRUCTOR if the element is itself
275838fd1498Szrj a class or array. */
275938fd1498Szrj
276038fd1498Szrj static void
init_subob_ctx(const constexpr_ctx * ctx,constexpr_ctx & new_ctx,tree index,tree & value)276138fd1498Szrj init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
276238fd1498Szrj tree index, tree &value)
276338fd1498Szrj {
276438fd1498Szrj new_ctx = *ctx;
276538fd1498Szrj
276638fd1498Szrj if (index && TREE_CODE (index) != INTEGER_CST
276738fd1498Szrj && TREE_CODE (index) != FIELD_DECL)
276838fd1498Szrj /* This won't have an element in the new CONSTRUCTOR. */
276938fd1498Szrj return;
277038fd1498Szrj
277138fd1498Szrj tree type = initialized_type (value);
277238fd1498Szrj if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
277338fd1498Szrj /* A non-aggregate member doesn't get its own CONSTRUCTOR. */
277438fd1498Szrj return;
277538fd1498Szrj
277638fd1498Szrj /* The sub-aggregate initializer might contain a placeholder;
277738fd1498Szrj update object to refer to the subobject and ctor to refer to
277838fd1498Szrj the (newly created) sub-initializer. */
277938fd1498Szrj if (ctx->object)
278038fd1498Szrj new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
278138fd1498Szrj tree elt = build_constructor (type, NULL);
278238fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (elt) = true;
278338fd1498Szrj new_ctx.ctor = elt;
278438fd1498Szrj
278538fd1498Szrj if (TREE_CODE (value) == TARGET_EXPR)
278638fd1498Szrj /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR. */
278738fd1498Szrj value = TARGET_EXPR_INITIAL (value);
278838fd1498Szrj }
278938fd1498Szrj
279038fd1498Szrj /* We're about to process an initializer for a class or array TYPE. Make
279138fd1498Szrj sure that CTX is set up appropriately. */
279238fd1498Szrj
279338fd1498Szrj static void
verify_ctor_sanity(const constexpr_ctx * ctx,tree type)279438fd1498Szrj verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
279538fd1498Szrj {
279638fd1498Szrj /* We don't bother building a ctor for an empty base subobject. */
279738fd1498Szrj if (is_empty_class (type))
279838fd1498Szrj return;
279938fd1498Szrj
280038fd1498Szrj /* We're in the middle of an initializer that might involve placeholders;
280138fd1498Szrj our caller should have created a CONSTRUCTOR for us to put the
280238fd1498Szrj initializer into. We will either return that constructor or T. */
280338fd1498Szrj gcc_assert (ctx->ctor);
280438fd1498Szrj gcc_assert (same_type_ignoring_top_level_qualifiers_p
280538fd1498Szrj (type, TREE_TYPE (ctx->ctor)));
280638fd1498Szrj /* We used to check that ctx->ctor was empty, but that isn't the case when
280738fd1498Szrj the object is zero-initialized before calling the constructor. */
280838fd1498Szrj if (ctx->object)
280938fd1498Szrj {
281038fd1498Szrj tree otype = TREE_TYPE (ctx->object);
281138fd1498Szrj gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, otype)
281238fd1498Szrj /* Handle flexible array members. */
281338fd1498Szrj || (TREE_CODE (otype) == ARRAY_TYPE
281438fd1498Szrj && TYPE_DOMAIN (otype) == NULL_TREE
281538fd1498Szrj && TREE_CODE (type) == ARRAY_TYPE
281638fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
281738fd1498Szrj (TREE_TYPE (type), TREE_TYPE (otype)))));
281838fd1498Szrj }
281938fd1498Szrj gcc_assert (!ctx->object || !DECL_P (ctx->object)
282038fd1498Szrj || *(ctx->values->get (ctx->object)) == ctx->ctor);
282138fd1498Szrj }
282238fd1498Szrj
282338fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
282438fd1498Szrj The expression tree T denotes a C-style array or a C-style
282538fd1498Szrj aggregate. Reduce it to a constant expression. */
282638fd1498Szrj
282738fd1498Szrj static tree
cxx_eval_bare_aggregate(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)282838fd1498Szrj cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
282938fd1498Szrj bool lval,
283038fd1498Szrj bool *non_constant_p, bool *overflow_p)
283138fd1498Szrj {
283238fd1498Szrj vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
283338fd1498Szrj bool changed = false;
283438fd1498Szrj gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
283538fd1498Szrj tree type = TREE_TYPE (t);
283638fd1498Szrj
283738fd1498Szrj constexpr_ctx new_ctx;
283838fd1498Szrj if (TYPE_PTRMEMFUNC_P (type) || VECTOR_TYPE_P (type))
283938fd1498Szrj {
284038fd1498Szrj /* We don't really need the ctx->ctor business for a PMF or
284138fd1498Szrj vector, but it's simpler to use the same code. */
284238fd1498Szrj new_ctx = *ctx;
284338fd1498Szrj new_ctx.ctor = build_constructor (type, NULL);
284438fd1498Szrj new_ctx.object = NULL_TREE;
284538fd1498Szrj ctx = &new_ctx;
284638fd1498Szrj };
284738fd1498Szrj verify_ctor_sanity (ctx, type);
284838fd1498Szrj vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
284938fd1498Szrj vec_alloc (*p, vec_safe_length (v));
285038fd1498Szrj
285138fd1498Szrj unsigned i;
285238fd1498Szrj tree index, value;
285338fd1498Szrj bool constant_p = true;
285438fd1498Szrj bool side_effects_p = false;
285538fd1498Szrj FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
285638fd1498Szrj {
285738fd1498Szrj tree orig_value = value;
285838fd1498Szrj init_subob_ctx (ctx, new_ctx, index, value);
285938fd1498Szrj if (new_ctx.ctor != ctx->ctor)
286038fd1498Szrj /* If we built a new CONSTRUCTOR, attach it now so that other
286138fd1498Szrj initializers can refer to it. */
286238fd1498Szrj CONSTRUCTOR_APPEND_ELT (*p, index, new_ctx.ctor);
286338fd1498Szrj tree elt = cxx_eval_constant_expression (&new_ctx, value,
286438fd1498Szrj lval,
286538fd1498Szrj non_constant_p, overflow_p);
286638fd1498Szrj /* Don't VERIFY_CONSTANT here. */
286738fd1498Szrj if (ctx->quiet && *non_constant_p)
286838fd1498Szrj break;
286938fd1498Szrj if (elt != orig_value)
287038fd1498Szrj changed = true;
287138fd1498Szrj
287238fd1498Szrj if (!TREE_CONSTANT (elt))
287338fd1498Szrj constant_p = false;
287438fd1498Szrj if (TREE_SIDE_EFFECTS (elt))
287538fd1498Szrj side_effects_p = true;
287638fd1498Szrj if (index && TREE_CODE (index) == COMPONENT_REF)
287738fd1498Szrj {
287838fd1498Szrj /* This is an initialization of a vfield inside a base
287938fd1498Szrj subaggregate that we already initialized; push this
288038fd1498Szrj initialization into the previous initialization. */
288138fd1498Szrj constructor_elt *inner = base_field_constructor_elt (*p, index);
288238fd1498Szrj inner->value = elt;
288338fd1498Szrj changed = true;
288438fd1498Szrj }
288538fd1498Szrj else if (index
288638fd1498Szrj && (TREE_CODE (index) == NOP_EXPR
288738fd1498Szrj || TREE_CODE (index) == POINTER_PLUS_EXPR))
288838fd1498Szrj {
288938fd1498Szrj /* This is an initializer for an empty base; now that we've
289038fd1498Szrj checked that it's constant, we can ignore it. */
289138fd1498Szrj gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index))));
289238fd1498Szrj changed = true;
289338fd1498Szrj }
289438fd1498Szrj else
289538fd1498Szrj {
289638fd1498Szrj if (new_ctx.ctor != ctx->ctor)
289738fd1498Szrj {
289838fd1498Szrj /* We appended this element above; update the value. */
289938fd1498Szrj gcc_assert ((*p)->last().index == index);
290038fd1498Szrj (*p)->last().value = elt;
290138fd1498Szrj }
290238fd1498Szrj else
290338fd1498Szrj CONSTRUCTOR_APPEND_ELT (*p, index, elt);
290438fd1498Szrj /* Adding or replacing an element might change the ctor's flags. */
290538fd1498Szrj TREE_CONSTANT (ctx->ctor) = constant_p;
290638fd1498Szrj TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
290738fd1498Szrj }
290838fd1498Szrj }
290938fd1498Szrj if (*non_constant_p || !changed)
291038fd1498Szrj return t;
291138fd1498Szrj t = ctx->ctor;
291238fd1498Szrj /* We're done building this CONSTRUCTOR, so now we can interpret an
291338fd1498Szrj element without an explicit initializer as value-initialized. */
291438fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (t) = false;
291538fd1498Szrj TREE_CONSTANT (t) = constant_p;
291638fd1498Szrj TREE_SIDE_EFFECTS (t) = side_effects_p;
291738fd1498Szrj if (VECTOR_TYPE_P (type))
291838fd1498Szrj t = fold (t);
291938fd1498Szrj return t;
292038fd1498Szrj }
292138fd1498Szrj
292238fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
292338fd1498Szrj The expression tree T is a VEC_INIT_EXPR which denotes the desired
292438fd1498Szrj initialization of a non-static data member of array type. Reduce it to a
292538fd1498Szrj CONSTRUCTOR.
292638fd1498Szrj
292738fd1498Szrj Note that apart from value-initialization (when VALUE_INIT is true),
292838fd1498Szrj this is only intended to support value-initialization and the
292938fd1498Szrj initializations done by defaulted constructors for classes with
293038fd1498Szrj non-static data members of array type. In this case, VEC_INIT_EXPR_INIT
293138fd1498Szrj will either be NULL_TREE for the default constructor, or a COMPONENT_REF
293238fd1498Szrj for the copy/move constructor. */
293338fd1498Szrj
293438fd1498Szrj static tree
cxx_eval_vec_init_1(const constexpr_ctx * ctx,tree atype,tree init,bool value_init,bool lval,bool * non_constant_p,bool * overflow_p)293538fd1498Szrj cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
293638fd1498Szrj bool value_init, bool lval,
293738fd1498Szrj bool *non_constant_p, bool *overflow_p)
293838fd1498Szrj {
293938fd1498Szrj tree elttype = TREE_TYPE (atype);
294038fd1498Szrj verify_ctor_sanity (ctx, atype);
294138fd1498Szrj vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
294238fd1498Szrj bool pre_init = false;
294338fd1498Szrj unsigned HOST_WIDE_INT i;
294438fd1498Szrj
294538fd1498Szrj /* For the default constructor, build up a call to the default
294638fd1498Szrj constructor of the element type. We only need to handle class types
294738fd1498Szrj here, as for a constructor to be constexpr, all members must be
294838fd1498Szrj initialized, which for a defaulted default constructor means they must
294938fd1498Szrj be of a class type with a constexpr default constructor. */
295038fd1498Szrj if (TREE_CODE (elttype) == ARRAY_TYPE)
295138fd1498Szrj /* We only do this at the lowest level. */;
295238fd1498Szrj else if (value_init)
295338fd1498Szrj {
295438fd1498Szrj init = build_value_init (elttype, tf_warning_or_error);
295538fd1498Szrj pre_init = true;
295638fd1498Szrj }
295738fd1498Szrj else if (!init)
295838fd1498Szrj {
295938fd1498Szrj vec<tree, va_gc> *argvec = make_tree_vector ();
296038fd1498Szrj init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
296138fd1498Szrj &argvec, elttype, LOOKUP_NORMAL,
296238fd1498Szrj tf_warning_or_error);
296338fd1498Szrj release_tree_vector (argvec);
296438fd1498Szrj init = build_aggr_init_expr (TREE_TYPE (init), init);
296538fd1498Szrj pre_init = true;
296638fd1498Szrj }
296738fd1498Szrj
296838fd1498Szrj tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
296938fd1498Szrj overflow_p);
297038fd1498Szrj unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
297138fd1498Szrj for (i = 0; i < max; ++i)
297238fd1498Szrj {
297338fd1498Szrj tree idx = build_int_cst (size_type_node, i);
297438fd1498Szrj tree eltinit;
297538fd1498Szrj bool reuse = false;
297638fd1498Szrj constexpr_ctx new_ctx;
297738fd1498Szrj init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype);
297838fd1498Szrj if (new_ctx.ctor != ctx->ctor)
297938fd1498Szrj CONSTRUCTOR_APPEND_ELT (*p, idx, new_ctx.ctor);
298038fd1498Szrj if (TREE_CODE (elttype) == ARRAY_TYPE)
298138fd1498Szrj {
298238fd1498Szrj /* A multidimensional array; recurse. */
298338fd1498Szrj if (value_init || init == NULL_TREE)
298438fd1498Szrj {
298538fd1498Szrj eltinit = NULL_TREE;
298638fd1498Szrj reuse = i == 0;
298738fd1498Szrj }
298838fd1498Szrj else
298938fd1498Szrj eltinit = cp_build_array_ref (input_location, init, idx,
299038fd1498Szrj tf_warning_or_error);
299138fd1498Szrj eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, value_init,
299238fd1498Szrj lval,
299338fd1498Szrj non_constant_p, overflow_p);
299438fd1498Szrj }
299538fd1498Szrj else if (pre_init)
299638fd1498Szrj {
299738fd1498Szrj /* Initializing an element using value or default initialization
299838fd1498Szrj we just pre-built above. */
2999*58e805e6Szrj if (init == void_node)
3000*58e805e6Szrj /* Trivial default-init, don't do anything to the CONSTRUCTOR. */
3001*58e805e6Szrj return ctx->ctor;
300238fd1498Szrj eltinit = cxx_eval_constant_expression (&new_ctx, init, lval,
300338fd1498Szrj non_constant_p, overflow_p);
300438fd1498Szrj reuse = i == 0;
300538fd1498Szrj }
300638fd1498Szrj else
300738fd1498Szrj {
300838fd1498Szrj /* Copying an element. */
300938fd1498Szrj gcc_assert (same_type_ignoring_top_level_qualifiers_p
301038fd1498Szrj (atype, TREE_TYPE (init)));
301138fd1498Szrj eltinit = cp_build_array_ref (input_location, init, idx,
301238fd1498Szrj tf_warning_or_error);
301338fd1498Szrj if (!lvalue_p (init))
301438fd1498Szrj eltinit = move (eltinit);
301538fd1498Szrj eltinit = force_rvalue (eltinit, tf_warning_or_error);
301638fd1498Szrj eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
301738fd1498Szrj non_constant_p, overflow_p);
301838fd1498Szrj }
301938fd1498Szrj if (*non_constant_p && !ctx->quiet)
302038fd1498Szrj break;
302138fd1498Szrj if (new_ctx.ctor != ctx->ctor)
302238fd1498Szrj {
302338fd1498Szrj /* We appended this element above; update the value. */
302438fd1498Szrj gcc_assert ((*p)->last().index == idx);
302538fd1498Szrj (*p)->last().value = eltinit;
302638fd1498Szrj }
302738fd1498Szrj else
302838fd1498Szrj CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
302938fd1498Szrj /* Reuse the result of cxx_eval_constant_expression call
303038fd1498Szrj from the first iteration to all others if it is a constant
303138fd1498Szrj initializer that doesn't require relocations. */
303238fd1498Szrj if (reuse
303338fd1498Szrj && max > 1
303438fd1498Szrj && (eltinit == NULL_TREE
303538fd1498Szrj || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
303638fd1498Szrj == null_pointer_node)))
303738fd1498Szrj {
303838fd1498Szrj if (new_ctx.ctor != ctx->ctor)
303938fd1498Szrj eltinit = new_ctx.ctor;
304038fd1498Szrj tree range = build2 (RANGE_EXPR, size_type_node,
304138fd1498Szrj build_int_cst (size_type_node, 1),
304238fd1498Szrj build_int_cst (size_type_node, max - 1));
304338fd1498Szrj CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit));
304438fd1498Szrj break;
304538fd1498Szrj }
304638fd1498Szrj else if (i == 0)
304738fd1498Szrj vec_safe_reserve (*p, max);
304838fd1498Szrj }
304938fd1498Szrj
305038fd1498Szrj if (!*non_constant_p)
305138fd1498Szrj {
305238fd1498Szrj init = ctx->ctor;
305338fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (init) = false;
305438fd1498Szrj }
305538fd1498Szrj return init;
305638fd1498Szrj }
305738fd1498Szrj
305838fd1498Szrj static tree
cxx_eval_vec_init(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)305938fd1498Szrj cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
306038fd1498Szrj bool lval,
306138fd1498Szrj bool *non_constant_p, bool *overflow_p)
306238fd1498Szrj {
306338fd1498Szrj tree atype = TREE_TYPE (t);
306438fd1498Szrj tree init = VEC_INIT_EXPR_INIT (t);
306538fd1498Szrj tree r = cxx_eval_vec_init_1 (ctx, atype, init,
306638fd1498Szrj VEC_INIT_EXPR_VALUE_INIT (t),
306738fd1498Szrj lval, non_constant_p, overflow_p);
306838fd1498Szrj if (*non_constant_p)
306938fd1498Szrj return t;
307038fd1498Szrj else
307138fd1498Szrj return r;
307238fd1498Szrj }
307338fd1498Szrj
307438fd1498Szrj /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
307538fd1498Szrj match. We want to be less strict for simple *& folding; if we have a
307638fd1498Szrj non-const temporary that we access through a const pointer, that should
307738fd1498Szrj work. We handle this here rather than change fold_indirect_ref_1
307838fd1498Szrj because we're dealing with things like ADDR_EXPR of INTEGER_CST which
307938fd1498Szrj don't really make sense outside of constant expression evaluation. Also
308038fd1498Szrj we want to allow folding to COMPONENT_REF, which could cause trouble
308138fd1498Szrj with TBAA in fold_indirect_ref_1.
308238fd1498Szrj
308338fd1498Szrj Try to keep this function synced with fold_indirect_ref_1. */
308438fd1498Szrj
308538fd1498Szrj static tree
cxx_fold_indirect_ref(location_t loc,tree type,tree op0,bool * empty_base)308638fd1498Szrj cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
308738fd1498Szrj {
308838fd1498Szrj tree sub = op0;
308938fd1498Szrj tree subtype;
309038fd1498Szrj poly_uint64 const_op01;
309138fd1498Szrj
309238fd1498Szrj STRIP_NOPS (sub);
309338fd1498Szrj subtype = TREE_TYPE (sub);
309438fd1498Szrj if (!POINTER_TYPE_P (subtype))
309538fd1498Szrj return NULL_TREE;
309638fd1498Szrj
309738fd1498Szrj if (TREE_CODE (sub) == ADDR_EXPR)
309838fd1498Szrj {
309938fd1498Szrj tree op = TREE_OPERAND (sub, 0);
310038fd1498Szrj tree optype = TREE_TYPE (op);
310138fd1498Szrj
310238fd1498Szrj /* *&CONST_DECL -> to the value of the const decl. */
310338fd1498Szrj if (TREE_CODE (op) == CONST_DECL)
310438fd1498Szrj return DECL_INITIAL (op);
310538fd1498Szrj /* *&p => p; make sure to handle *&"str"[cst] here. */
310638fd1498Szrj if (same_type_ignoring_top_level_qualifiers_p (optype, type)
310738fd1498Szrj /* Also handle the case where the desired type is an array of unknown
310838fd1498Szrj bounds because the variable has had its bounds deduced since the
310938fd1498Szrj ADDR_EXPR was created. */
311038fd1498Szrj || (TREE_CODE (type) == ARRAY_TYPE
311138fd1498Szrj && TREE_CODE (optype) == ARRAY_TYPE
311238fd1498Szrj && TYPE_DOMAIN (type) == NULL_TREE
311338fd1498Szrj && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (optype),
311438fd1498Szrj TREE_TYPE (type))))
311538fd1498Szrj {
311638fd1498Szrj tree fop = fold_read_from_constant_string (op);
311738fd1498Szrj if (fop)
311838fd1498Szrj return fop;
311938fd1498Szrj else
312038fd1498Szrj return op;
312138fd1498Szrj }
312238fd1498Szrj /* *(foo *)&fooarray => fooarray[0] */
312338fd1498Szrj else if (TREE_CODE (optype) == ARRAY_TYPE
312438fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
312538fd1498Szrj (type, TREE_TYPE (optype))))
312638fd1498Szrj {
312738fd1498Szrj tree type_domain = TYPE_DOMAIN (optype);
312838fd1498Szrj tree min_val = size_zero_node;
312938fd1498Szrj if (type_domain && TYPE_MIN_VALUE (type_domain))
313038fd1498Szrj min_val = TYPE_MIN_VALUE (type_domain);
313138fd1498Szrj return build4_loc (loc, ARRAY_REF, type, op, min_val,
313238fd1498Szrj NULL_TREE, NULL_TREE);
313338fd1498Szrj }
313438fd1498Szrj /* *(foo *)&complexfoo => __real__ complexfoo */
313538fd1498Szrj else if (TREE_CODE (optype) == COMPLEX_TYPE
313638fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
313738fd1498Szrj (type, TREE_TYPE (optype))))
313838fd1498Szrj return fold_build1_loc (loc, REALPART_EXPR, type, op);
313938fd1498Szrj /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
314038fd1498Szrj else if (VECTOR_TYPE_P (optype)
314138fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
314238fd1498Szrj (type, TREE_TYPE (optype))))
314338fd1498Szrj {
314438fd1498Szrj tree part_width = TYPE_SIZE (type);
314538fd1498Szrj tree index = bitsize_int (0);
314638fd1498Szrj return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width,
314738fd1498Szrj index);
314838fd1498Szrj }
314938fd1498Szrj /* Also handle conversion to an empty base class, which
315038fd1498Szrj is represented with a NOP_EXPR. */
315138fd1498Szrj else if (is_empty_class (type)
315238fd1498Szrj && CLASS_TYPE_P (optype)
315338fd1498Szrj && DERIVED_FROM_P (type, optype))
315438fd1498Szrj {
315538fd1498Szrj *empty_base = true;
315638fd1498Szrj return op;
315738fd1498Szrj }
315838fd1498Szrj /* *(foo *)&struct_with_foo_field => COMPONENT_REF */
315938fd1498Szrj else if (RECORD_OR_UNION_TYPE_P (optype))
316038fd1498Szrj {
316138fd1498Szrj tree field = TYPE_FIELDS (optype);
316238fd1498Szrj for (; field; field = DECL_CHAIN (field))
316338fd1498Szrj if (TREE_CODE (field) == FIELD_DECL
316438fd1498Szrj && TREE_TYPE (field) != error_mark_node
316538fd1498Szrj && integer_zerop (byte_position (field))
316638fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
316738fd1498Szrj (TREE_TYPE (field), type)))
316838fd1498Szrj return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE);
316938fd1498Szrj }
317038fd1498Szrj }
317138fd1498Szrj else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
317238fd1498Szrj && poly_int_tree_p (TREE_OPERAND (sub, 1), &const_op01))
317338fd1498Szrj {
317438fd1498Szrj tree op00 = TREE_OPERAND (sub, 0);
317538fd1498Szrj tree op01 = TREE_OPERAND (sub, 1);
317638fd1498Szrj
317738fd1498Szrj STRIP_NOPS (op00);
317838fd1498Szrj if (TREE_CODE (op00) == ADDR_EXPR)
317938fd1498Szrj {
318038fd1498Szrj tree op00type;
318138fd1498Szrj op00 = TREE_OPERAND (op00, 0);
318238fd1498Szrj op00type = TREE_TYPE (op00);
318338fd1498Szrj
318438fd1498Szrj /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
318538fd1498Szrj if (VECTOR_TYPE_P (op00type)
318638fd1498Szrj && same_type_ignoring_top_level_qualifiers_p
318738fd1498Szrj (type, TREE_TYPE (op00type))
318838fd1498Szrj /* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
318938fd1498Szrj but we want to treat offsets with MSB set as negative.
319038fd1498Szrj For the code below negative offsets are invalid and
319138fd1498Szrj TYPE_SIZE of the element is something unsigned, so
319238fd1498Szrj check whether op01 fits into poly_int64, which implies
319338fd1498Szrj it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and
319438fd1498Szrj then just use poly_uint64 because we want to treat the
319538fd1498Szrj value as unsigned. */
319638fd1498Szrj && tree_fits_poly_int64_p (op01))
319738fd1498Szrj {
319838fd1498Szrj tree part_width = TYPE_SIZE (type);
319938fd1498Szrj poly_uint64 max_offset
320038fd1498Szrj = (tree_to_uhwi (part_width) / BITS_PER_UNIT
320138fd1498Szrj * TYPE_VECTOR_SUBPARTS (op00type));
320238fd1498Szrj if (known_lt (const_op01, max_offset))
320338fd1498Szrj {
320438fd1498Szrj tree index = bitsize_int (const_op01 * BITS_PER_UNIT);
320538fd1498Szrj return fold_build3_loc (loc,
320638fd1498Szrj BIT_FIELD_REF, type, op00,
320738fd1498Szrj part_width, index);
320838fd1498Szrj }
320938fd1498Szrj }
321038fd1498Szrj /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
321138fd1498Szrj else if (TREE_CODE (op00type) == COMPLEX_TYPE
321238fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
321338fd1498Szrj (type, TREE_TYPE (op00type))))
321438fd1498Szrj {
321538fd1498Szrj if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
321638fd1498Szrj const_op01))
321738fd1498Szrj return fold_build1_loc (loc, IMAGPART_EXPR, type, op00);
321838fd1498Szrj }
321938fd1498Szrj /* ((foo *)&fooarray)[1] => fooarray[1] */
322038fd1498Szrj else if (TREE_CODE (op00type) == ARRAY_TYPE
322138fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
322238fd1498Szrj (type, TREE_TYPE (op00type))))
322338fd1498Szrj {
322438fd1498Szrj tree type_domain = TYPE_DOMAIN (op00type);
322538fd1498Szrj tree min_val = size_zero_node;
322638fd1498Szrj if (type_domain && TYPE_MIN_VALUE (type_domain))
322738fd1498Szrj min_val = TYPE_MIN_VALUE (type_domain);
322838fd1498Szrj offset_int off = wi::to_offset (op01);
322938fd1498Szrj offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type));
323038fd1498Szrj offset_int remainder;
323138fd1498Szrj off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder);
323238fd1498Szrj if (remainder == 0 && TREE_CODE (min_val) == INTEGER_CST)
323338fd1498Szrj {
323438fd1498Szrj off = off + wi::to_offset (min_val);
323538fd1498Szrj op01 = wide_int_to_tree (sizetype, off);
323638fd1498Szrj return build4_loc (loc, ARRAY_REF, type, op00, op01,
323738fd1498Szrj NULL_TREE, NULL_TREE);
323838fd1498Szrj }
323938fd1498Szrj }
324038fd1498Szrj /* Also handle conversion to an empty base class, which
324138fd1498Szrj is represented with a NOP_EXPR. */
324238fd1498Szrj else if (is_empty_class (type)
324338fd1498Szrj && CLASS_TYPE_P (op00type)
324438fd1498Szrj && DERIVED_FROM_P (type, op00type))
324538fd1498Szrj {
324638fd1498Szrj *empty_base = true;
324738fd1498Szrj return op00;
324838fd1498Szrj }
324938fd1498Szrj /* ((foo *)&struct_with_foo_field)[1] => COMPONENT_REF */
325038fd1498Szrj else if (RECORD_OR_UNION_TYPE_P (op00type))
325138fd1498Szrj {
325238fd1498Szrj tree field = TYPE_FIELDS (op00type);
325338fd1498Szrj for (; field; field = DECL_CHAIN (field))
325438fd1498Szrj if (TREE_CODE (field) == FIELD_DECL
325538fd1498Szrj && TREE_TYPE (field) != error_mark_node
325638fd1498Szrj && tree_int_cst_equal (byte_position (field), op01)
325738fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
325838fd1498Szrj (TREE_TYPE (field), type)))
325938fd1498Szrj return fold_build3 (COMPONENT_REF, type, op00,
326038fd1498Szrj field, NULL_TREE);
326138fd1498Szrj }
326238fd1498Szrj }
326338fd1498Szrj }
326438fd1498Szrj /* *(foo *)fooarrptr => (*fooarrptr)[0] */
326538fd1498Szrj else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
326638fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
326738fd1498Szrj (type, TREE_TYPE (TREE_TYPE (subtype)))))
326838fd1498Szrj {
326938fd1498Szrj tree type_domain;
327038fd1498Szrj tree min_val = size_zero_node;
327138fd1498Szrj tree newsub
327238fd1498Szrj = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
327338fd1498Szrj if (newsub)
327438fd1498Szrj sub = newsub;
327538fd1498Szrj else
327638fd1498Szrj sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
327738fd1498Szrj type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
327838fd1498Szrj if (type_domain && TYPE_MIN_VALUE (type_domain))
327938fd1498Szrj min_val = TYPE_MIN_VALUE (type_domain);
328038fd1498Szrj return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
328138fd1498Szrj NULL_TREE);
328238fd1498Szrj }
328338fd1498Szrj
328438fd1498Szrj return NULL_TREE;
328538fd1498Szrj }
328638fd1498Szrj
328738fd1498Szrj static tree
cxx_eval_indirect_ref(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)328838fd1498Szrj cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
328938fd1498Szrj bool lval,
329038fd1498Szrj bool *non_constant_p, bool *overflow_p)
329138fd1498Szrj {
329238fd1498Szrj tree orig_op0 = TREE_OPERAND (t, 0);
329338fd1498Szrj bool empty_base = false;
329438fd1498Szrj
329538fd1498Szrj /* We can handle a MEM_REF like an INDIRECT_REF, if MEM_REF's second
329638fd1498Szrj operand is an integer-zero. Otherwise reject the MEM_REF for now. */
329738fd1498Szrj
329838fd1498Szrj if (TREE_CODE (t) == MEM_REF
329938fd1498Szrj && (!TREE_OPERAND (t, 1) || !integer_zerop (TREE_OPERAND (t, 1))))
330038fd1498Szrj {
330138fd1498Szrj gcc_assert (ctx->quiet);
330238fd1498Szrj *non_constant_p = true;
330338fd1498Szrj return t;
330438fd1498Szrj }
330538fd1498Szrj
330638fd1498Szrj /* First try to simplify it directly. */
330738fd1498Szrj tree r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), orig_op0,
330838fd1498Szrj &empty_base);
330938fd1498Szrj if (!r)
331038fd1498Szrj {
331138fd1498Szrj /* If that didn't work, evaluate the operand first. */
331238fd1498Szrj tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
331338fd1498Szrj /*lval*/false, non_constant_p,
331438fd1498Szrj overflow_p);
331538fd1498Szrj /* Don't VERIFY_CONSTANT here. */
331638fd1498Szrj if (*non_constant_p)
331738fd1498Szrj return t;
331838fd1498Szrj
331938fd1498Szrj if (!lval && integer_zerop (op0))
332038fd1498Szrj {
332138fd1498Szrj if (!ctx->quiet)
332238fd1498Szrj error ("dereferencing a null pointer");
332338fd1498Szrj *non_constant_p = true;
332438fd1498Szrj return t;
332538fd1498Szrj }
332638fd1498Szrj
332738fd1498Szrj r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
332838fd1498Szrj &empty_base);
332938fd1498Szrj if (r == NULL_TREE)
333038fd1498Szrj {
333138fd1498Szrj /* We couldn't fold to a constant value. Make sure it's not
333238fd1498Szrj something we should have been able to fold. */
333338fd1498Szrj tree sub = op0;
333438fd1498Szrj STRIP_NOPS (sub);
333538fd1498Szrj if (TREE_CODE (sub) == ADDR_EXPR)
333638fd1498Szrj {
333738fd1498Szrj gcc_assert (!same_type_ignoring_top_level_qualifiers_p
333838fd1498Szrj (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
333938fd1498Szrj /* DR 1188 says we don't have to deal with this. */
334038fd1498Szrj if (!ctx->quiet)
334138fd1498Szrj error ("accessing value of %qE through a %qT glvalue in a "
334238fd1498Szrj "constant expression", build_fold_indirect_ref (sub),
334338fd1498Szrj TREE_TYPE (t));
334438fd1498Szrj *non_constant_p = true;
334538fd1498Szrj return t;
334638fd1498Szrj }
334738fd1498Szrj
334838fd1498Szrj if (lval && op0 != orig_op0)
334938fd1498Szrj return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
335038fd1498Szrj if (!lval)
335138fd1498Szrj VERIFY_CONSTANT (t);
335238fd1498Szrj return t;
335338fd1498Szrj }
335438fd1498Szrj }
335538fd1498Szrj
335638fd1498Szrj r = cxx_eval_constant_expression (ctx, r,
335738fd1498Szrj lval, non_constant_p, overflow_p);
335838fd1498Szrj if (*non_constant_p)
335938fd1498Szrj return t;
336038fd1498Szrj
336138fd1498Szrj /* If we're pulling out the value of an empty base, just return an empty
336238fd1498Szrj CONSTRUCTOR. */
336338fd1498Szrj if (empty_base && !lval)
336438fd1498Szrj {
336538fd1498Szrj r = build_constructor (TREE_TYPE (t), NULL);
336638fd1498Szrj TREE_CONSTANT (r) = true;
336738fd1498Szrj }
336838fd1498Szrj
336938fd1498Szrj return r;
337038fd1498Szrj }
337138fd1498Szrj
337238fd1498Szrj /* Complain about R, a VAR_DECL, not being usable in a constant expression.
337338fd1498Szrj Shared between potential_constant_expression and
337438fd1498Szrj cxx_eval_constant_expression. */
337538fd1498Szrj
337638fd1498Szrj static void
non_const_var_error(tree r)337738fd1498Szrj non_const_var_error (tree r)
337838fd1498Szrj {
337938fd1498Szrj tree type = TREE_TYPE (r);
338038fd1498Szrj error ("the value of %qD is not usable in a constant "
338138fd1498Szrj "expression", r);
338238fd1498Szrj /* Avoid error cascade. */
338338fd1498Szrj if (DECL_INITIAL (r) == error_mark_node)
338438fd1498Szrj return;
338538fd1498Szrj if (DECL_DECLARED_CONSTEXPR_P (r))
338638fd1498Szrj inform (DECL_SOURCE_LOCATION (r),
338738fd1498Szrj "%qD used in its own initializer", r);
338838fd1498Szrj else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
338938fd1498Szrj {
339038fd1498Szrj if (!CP_TYPE_CONST_P (type))
339138fd1498Szrj inform (DECL_SOURCE_LOCATION (r),
339238fd1498Szrj "%q#D is not const", r);
339338fd1498Szrj else if (CP_TYPE_VOLATILE_P (type))
339438fd1498Szrj inform (DECL_SOURCE_LOCATION (r),
339538fd1498Szrj "%q#D is volatile", r);
339638fd1498Szrj else if (!DECL_INITIAL (r)
339738fd1498Szrj || !TREE_CONSTANT (DECL_INITIAL (r))
339838fd1498Szrj || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
339938fd1498Szrj inform (DECL_SOURCE_LOCATION (r),
340038fd1498Szrj "%qD was not initialized with a constant "
340138fd1498Szrj "expression", r);
340238fd1498Szrj else
340338fd1498Szrj gcc_unreachable ();
340438fd1498Szrj }
340538fd1498Szrj else if (TREE_CODE (type) == REFERENCE_TYPE)
340638fd1498Szrj inform (DECL_SOURCE_LOCATION (r),
340738fd1498Szrj "%qD was not initialized with a constant "
340838fd1498Szrj "expression", r);
340938fd1498Szrj else
341038fd1498Szrj {
341138fd1498Szrj if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
341238fd1498Szrj inform (DECL_SOURCE_LOCATION (r),
341338fd1498Szrj "%qD was not declared %<constexpr%>", r);
341438fd1498Szrj else
341538fd1498Szrj inform (DECL_SOURCE_LOCATION (r),
341638fd1498Szrj "%qD does not have integral or enumeration type",
341738fd1498Szrj r);
341838fd1498Szrj }
341938fd1498Szrj }
342038fd1498Szrj
342138fd1498Szrj /* Subroutine of cxx_eval_constant_expression.
342238fd1498Szrj Like cxx_eval_unary_expression, except for trinary expressions. */
342338fd1498Szrj
342438fd1498Szrj static tree
cxx_eval_trinary_expression(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)342538fd1498Szrj cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
342638fd1498Szrj bool lval,
342738fd1498Szrj bool *non_constant_p, bool *overflow_p)
342838fd1498Szrj {
342938fd1498Szrj int i;
343038fd1498Szrj tree args[3];
343138fd1498Szrj tree val;
343238fd1498Szrj
343338fd1498Szrj for (i = 0; i < 3; i++)
343438fd1498Szrj {
343538fd1498Szrj args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
343638fd1498Szrj lval,
343738fd1498Szrj non_constant_p, overflow_p);
343838fd1498Szrj VERIFY_CONSTANT (args[i]);
343938fd1498Szrj }
344038fd1498Szrj
344138fd1498Szrj val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
344238fd1498Szrj args[0], args[1], args[2]);
344338fd1498Szrj if (val == NULL_TREE)
344438fd1498Szrj return t;
344538fd1498Szrj VERIFY_CONSTANT (val);
344638fd1498Szrj return val;
344738fd1498Szrj }
344838fd1498Szrj
344938fd1498Szrj /* True if T was declared in a function declared to be constexpr, and
345038fd1498Szrj therefore potentially constant in C++14. */
345138fd1498Szrj
345238fd1498Szrj bool
var_in_constexpr_fn(tree t)345338fd1498Szrj var_in_constexpr_fn (tree t)
345438fd1498Szrj {
345538fd1498Szrj tree ctx = DECL_CONTEXT (t);
345638fd1498Szrj return (ctx && TREE_CODE (ctx) == FUNCTION_DECL
345738fd1498Szrj && DECL_DECLARED_CONSTEXPR_P (ctx));
345838fd1498Szrj }
345938fd1498Szrj
346038fd1498Szrj /* True if T was declared in a function that might be constexpr: either a
346138fd1498Szrj function that was declared constexpr, or a C++17 lambda op(). */
346238fd1498Szrj
346338fd1498Szrj bool
var_in_maybe_constexpr_fn(tree t)346438fd1498Szrj var_in_maybe_constexpr_fn (tree t)
346538fd1498Szrj {
346638fd1498Szrj if (cxx_dialect >= cxx17
346738fd1498Szrj && DECL_FUNCTION_SCOPE_P (t)
346838fd1498Szrj && LAMBDA_FUNCTION_P (DECL_CONTEXT (t)))
346938fd1498Szrj return true;
347038fd1498Szrj return var_in_constexpr_fn (t);
347138fd1498Szrj }
347238fd1498Szrj
347338fd1498Szrj /* We're assigning INIT to TARGET. In do_build_copy_constructor and
347438fd1498Szrj build_over_call we implement trivial copy of a class with tail padding using
347538fd1498Szrj assignment of character arrays, which is valid in normal code, but not in
347638fd1498Szrj constexpr evaluation. We don't need to worry about clobbering tail padding
347738fd1498Szrj in constexpr evaluation, so strip the type punning. */
347838fd1498Szrj
347938fd1498Szrj static void
maybe_simplify_trivial_copy(tree & target,tree & init)348038fd1498Szrj maybe_simplify_trivial_copy (tree &target, tree &init)
348138fd1498Szrj {
348238fd1498Szrj if (TREE_CODE (target) == MEM_REF
348338fd1498Szrj && TREE_CODE (init) == MEM_REF
348438fd1498Szrj && TREE_TYPE (target) == TREE_TYPE (init)
348538fd1498Szrj && TREE_CODE (TREE_TYPE (target)) == ARRAY_TYPE
348638fd1498Szrj && TREE_TYPE (TREE_TYPE (target)) == unsigned_char_type_node)
348738fd1498Szrj {
348838fd1498Szrj target = build_fold_indirect_ref (TREE_OPERAND (target, 0));
348938fd1498Szrj init = build_fold_indirect_ref (TREE_OPERAND (init, 0));
349038fd1498Szrj }
349138fd1498Szrj }
349238fd1498Szrj
349338fd1498Szrj /* Evaluate an INIT_EXPR or MODIFY_EXPR. */
349438fd1498Szrj
349538fd1498Szrj static tree
cxx_eval_store_expression(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)349638fd1498Szrj cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
349738fd1498Szrj bool lval,
349838fd1498Szrj bool *non_constant_p, bool *overflow_p)
349938fd1498Szrj {
350038fd1498Szrj constexpr_ctx new_ctx = *ctx;
350138fd1498Szrj
350238fd1498Szrj tree init = TREE_OPERAND (t, 1);
350338fd1498Szrj if (TREE_CLOBBER_P (init))
350438fd1498Szrj /* Just ignore clobbers. */
350538fd1498Szrj return void_node;
350638fd1498Szrj
350738fd1498Szrj /* First we figure out where we're storing to. */
350838fd1498Szrj tree target = TREE_OPERAND (t, 0);
350938fd1498Szrj
351038fd1498Szrj maybe_simplify_trivial_copy (target, init);
351138fd1498Szrj
351238fd1498Szrj tree type = TREE_TYPE (target);
351338fd1498Szrj target = cxx_eval_constant_expression (ctx, target,
351438fd1498Szrj true,
351538fd1498Szrj non_constant_p, overflow_p);
351638fd1498Szrj if (*non_constant_p)
351738fd1498Szrj return t;
351838fd1498Szrj
351938fd1498Szrj /* cxx_eval_array_reference for lval = true allows references one past
352038fd1498Szrj end of array, because it does not know if it is just taking address
352138fd1498Szrj (which is valid), or actual dereference. Here we know it is
352238fd1498Szrj a dereference, so diagnose it here. */
352338fd1498Szrj for (tree probe = target; probe; )
352438fd1498Szrj {
352538fd1498Szrj switch (TREE_CODE (probe))
352638fd1498Szrj {
352738fd1498Szrj case ARRAY_REF:
352838fd1498Szrj tree nelts, ary;
352938fd1498Szrj ary = TREE_OPERAND (probe, 0);
353038fd1498Szrj nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary),
353138fd1498Szrj non_constant_p, overflow_p);
353238fd1498Szrj VERIFY_CONSTANT (nelts);
353338fd1498Szrj gcc_assert (TREE_CODE (nelts) == INTEGER_CST
353438fd1498Szrj && TREE_CODE (TREE_OPERAND (probe, 1)) == INTEGER_CST);
353538fd1498Szrj if (wi::to_widest (TREE_OPERAND (probe, 1)) == wi::to_widest (nelts))
353638fd1498Szrj {
353738fd1498Szrj diag_array_subscript (ctx, ary, TREE_OPERAND (probe, 1));
353838fd1498Szrj *non_constant_p = true;
353938fd1498Szrj return t;
354038fd1498Szrj }
354138fd1498Szrj /* FALLTHRU */
354238fd1498Szrj
354338fd1498Szrj case BIT_FIELD_REF:
354438fd1498Szrj case COMPONENT_REF:
354538fd1498Szrj probe = TREE_OPERAND (probe, 0);
354638fd1498Szrj continue;
354738fd1498Szrj
354838fd1498Szrj default:
354938fd1498Szrj probe = NULL_TREE;
355038fd1498Szrj continue;
355138fd1498Szrj }
355238fd1498Szrj }
355338fd1498Szrj
355438fd1498Szrj if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (target), type))
355538fd1498Szrj {
355638fd1498Szrj /* For initialization of an empty base, the original target will be
355738fd1498Szrj *(base*)this, which the above evaluation resolves to the object
355838fd1498Szrj argument, which has the derived type rather than the base type. In
355938fd1498Szrj this situation, just evaluate the initializer and return, since
356038fd1498Szrj there's no actual data to store. */
356138fd1498Szrj gcc_assert (is_empty_class (type));
356238fd1498Szrj return cxx_eval_constant_expression (ctx, init, false,
356338fd1498Szrj non_constant_p, overflow_p);
356438fd1498Szrj }
356538fd1498Szrj
356638fd1498Szrj /* And then find the underlying variable. */
356738fd1498Szrj vec<tree,va_gc> *refs = make_tree_vector();
356838fd1498Szrj tree object = NULL_TREE;
356938fd1498Szrj for (tree probe = target; object == NULL_TREE; )
357038fd1498Szrj {
357138fd1498Szrj switch (TREE_CODE (probe))
357238fd1498Szrj {
357338fd1498Szrj case BIT_FIELD_REF:
357438fd1498Szrj case COMPONENT_REF:
357538fd1498Szrj case ARRAY_REF:
357638fd1498Szrj vec_safe_push (refs, TREE_OPERAND (probe, 1));
357738fd1498Szrj vec_safe_push (refs, TREE_TYPE (probe));
357838fd1498Szrj probe = TREE_OPERAND (probe, 0);
357938fd1498Szrj break;
358038fd1498Szrj
358138fd1498Szrj default:
358238fd1498Szrj object = probe;
358338fd1498Szrj }
358438fd1498Szrj }
358538fd1498Szrj
358638fd1498Szrj /* And then find/build up our initializer for the path to the subobject
358738fd1498Szrj we're initializing. */
358838fd1498Szrj tree *valp;
358938fd1498Szrj if (object == ctx->object && VAR_P (object)
359038fd1498Szrj && DECL_NAME (object) && ctx->call == NULL)
359138fd1498Szrj /* The variable we're building up an aggregate initializer for is outside
359238fd1498Szrj the constant-expression, so don't evaluate the store. We check
359338fd1498Szrj DECL_NAME to handle TARGET_EXPR temporaries, which are fair game. */
359438fd1498Szrj valp = NULL;
359538fd1498Szrj else if (DECL_P (object))
359638fd1498Szrj valp = ctx->values->get (object);
359738fd1498Szrj else
359838fd1498Szrj valp = NULL;
359938fd1498Szrj if (!valp)
360038fd1498Szrj {
360138fd1498Szrj /* A constant-expression cannot modify objects from outside the
360238fd1498Szrj constant-expression. */
360338fd1498Szrj if (!ctx->quiet)
360438fd1498Szrj error ("modification of %qE is not a constant expression", object);
360538fd1498Szrj *non_constant_p = true;
360638fd1498Szrj return t;
360738fd1498Szrj }
360838fd1498Szrj type = TREE_TYPE (object);
360938fd1498Szrj bool no_zero_init = true;
361038fd1498Szrj
361138fd1498Szrj vec<tree,va_gc> *ctors = make_tree_vector ();
361238fd1498Szrj while (!refs->is_empty())
361338fd1498Szrj {
361438fd1498Szrj if (*valp == NULL_TREE)
361538fd1498Szrj {
361638fd1498Szrj *valp = build_constructor (type, NULL);
361738fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = no_zero_init;
361838fd1498Szrj }
361938fd1498Szrj else if (TREE_CODE (*valp) == STRING_CST)
362038fd1498Szrj {
362138fd1498Szrj /* An array was initialized with a string constant, and now
362238fd1498Szrj we're writing into one of its elements. Explode the
362338fd1498Szrj single initialization into a set of element
362438fd1498Szrj initializations. */
362538fd1498Szrj gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
362638fd1498Szrj
362738fd1498Szrj tree string = *valp;
362838fd1498Szrj tree elt_type = TREE_TYPE (type);
362938fd1498Szrj unsigned chars_per_elt = (TYPE_PRECISION (elt_type)
363038fd1498Szrj / TYPE_PRECISION (char_type_node));
363138fd1498Szrj unsigned num_elts = TREE_STRING_LENGTH (string) / chars_per_elt;
363238fd1498Szrj tree ary_ctor = build_constructor (type, NULL);
363338fd1498Szrj
363438fd1498Szrj vec_safe_reserve (CONSTRUCTOR_ELTS (ary_ctor), num_elts);
363538fd1498Szrj for (unsigned ix = 0; ix != num_elts; ix++)
363638fd1498Szrj {
363738fd1498Szrj constructor_elt elt =
363838fd1498Szrj {
363938fd1498Szrj build_int_cst (size_type_node, ix),
364038fd1498Szrj extract_string_elt (string, chars_per_elt, ix)
364138fd1498Szrj };
364238fd1498Szrj CONSTRUCTOR_ELTS (ary_ctor)->quick_push (elt);
364338fd1498Szrj }
364438fd1498Szrj
364538fd1498Szrj *valp = ary_ctor;
364638fd1498Szrj }
364738fd1498Szrj
364838fd1498Szrj /* If the value of object is already zero-initialized, any new ctors for
364938fd1498Szrj subobjects will also be zero-initialized. */
365038fd1498Szrj no_zero_init = CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp);
365138fd1498Szrj
365238fd1498Szrj vec_safe_push (ctors, *valp);
365338fd1498Szrj
365438fd1498Szrj enum tree_code code = TREE_CODE (type);
365538fd1498Szrj type = refs->pop();
365638fd1498Szrj tree index = refs->pop();
365738fd1498Szrj
365838fd1498Szrj constructor_elt *cep = NULL;
365938fd1498Szrj if (code == ARRAY_TYPE)
366038fd1498Szrj {
366138fd1498Szrj HOST_WIDE_INT i
366238fd1498Szrj = find_array_ctor_elt (*valp, index, /*insert*/true);
366338fd1498Szrj gcc_assert (i >= 0);
366438fd1498Szrj cep = CONSTRUCTOR_ELT (*valp, i);
366538fd1498Szrj gcc_assert (TREE_CODE (cep->index) != RANGE_EXPR);
366638fd1498Szrj }
366738fd1498Szrj else
366838fd1498Szrj {
366938fd1498Szrj gcc_assert (TREE_CODE (index) == FIELD_DECL);
367038fd1498Szrj
367138fd1498Szrj /* We must keep the CONSTRUCTOR's ELTS in FIELD order.
367238fd1498Szrj Usually we meet initializers in that order, but it is
367338fd1498Szrj possible for base types to be placed not in program
367438fd1498Szrj order. */
367538fd1498Szrj tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
367638fd1498Szrj unsigned HOST_WIDE_INT idx;
367738fd1498Szrj
367838fd1498Szrj if (code == UNION_TYPE && CONSTRUCTOR_NELTS (*valp)
367938fd1498Szrj && CONSTRUCTOR_ELT (*valp, 0)->index != index)
368038fd1498Szrj /* Changing active member. */
368138fd1498Szrj vec_safe_truncate (CONSTRUCTOR_ELTS (*valp), 0);
368238fd1498Szrj
368338fd1498Szrj for (idx = 0;
368438fd1498Szrj vec_safe_iterate (CONSTRUCTOR_ELTS (*valp), idx, &cep);
368538fd1498Szrj idx++, fields = DECL_CHAIN (fields))
368638fd1498Szrj {
368738fd1498Szrj if (index == cep->index)
368838fd1498Szrj goto found;
368938fd1498Szrj
369038fd1498Szrj /* The field we're initializing must be on the field
369138fd1498Szrj list. Look to see if it is present before the
369238fd1498Szrj field the current ELT initializes. */
369338fd1498Szrj for (; fields != cep->index; fields = DECL_CHAIN (fields))
369438fd1498Szrj if (index == fields)
369538fd1498Szrj goto insert;
369638fd1498Szrj }
369738fd1498Szrj
369838fd1498Szrj /* We fell off the end of the CONSTRUCTOR, so insert a new
369938fd1498Szrj entry at the end. */
370038fd1498Szrj insert:
370138fd1498Szrj {
370238fd1498Szrj constructor_elt ce = { index, NULL_TREE };
370338fd1498Szrj
370438fd1498Szrj vec_safe_insert (CONSTRUCTOR_ELTS (*valp), idx, ce);
370538fd1498Szrj cep = CONSTRUCTOR_ELT (*valp, idx);
370638fd1498Szrj }
370738fd1498Szrj found:;
370838fd1498Szrj }
370938fd1498Szrj valp = &cep->value;
371038fd1498Szrj }
371138fd1498Szrj release_tree_vector (refs);
371238fd1498Szrj
371338fd1498Szrj if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
371438fd1498Szrj {
371538fd1498Szrj /* Create a new CONSTRUCTOR in case evaluation of the initializer
371638fd1498Szrj wants to modify it. */
371738fd1498Szrj if (*valp == NULL_TREE)
371838fd1498Szrj {
371938fd1498Szrj *valp = build_constructor (type, NULL);
372038fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = no_zero_init;
372138fd1498Szrj }
372238fd1498Szrj else if (TREE_CODE (*valp) == PTRMEM_CST)
372338fd1498Szrj *valp = cplus_expand_constant (*valp);
372438fd1498Szrj new_ctx.ctor = *valp;
372538fd1498Szrj new_ctx.object = target;
372638fd1498Szrj }
372738fd1498Szrj
372838fd1498Szrj init = cxx_eval_constant_expression (&new_ctx, init, false,
372938fd1498Szrj non_constant_p, overflow_p);
373038fd1498Szrj /* Don't share a CONSTRUCTOR that might be changed later. */
373138fd1498Szrj init = unshare_constructor (init);
373238fd1498Szrj if (target == object)
373338fd1498Szrj /* The hash table might have moved since the get earlier. */
373438fd1498Szrj valp = ctx->values->get (object);
373538fd1498Szrj
373638fd1498Szrj if (TREE_CODE (init) == CONSTRUCTOR)
373738fd1498Szrj {
373838fd1498Szrj /* An outer ctx->ctor might be pointing to *valp, so replace
373938fd1498Szrj its contents. */
374038fd1498Szrj CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
374138fd1498Szrj TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
374238fd1498Szrj TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
374338fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp)
374438fd1498Szrj = CONSTRUCTOR_NO_IMPLICIT_ZERO (init);
374538fd1498Szrj }
374638fd1498Szrj else
374738fd1498Szrj *valp = init;
374838fd1498Szrj
374938fd1498Szrj /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing
375038fd1498Szrj CONSTRUCTORs, if any. */
375138fd1498Szrj tree elt;
375238fd1498Szrj unsigned i;
375338fd1498Szrj bool c = TREE_CONSTANT (init);
375438fd1498Szrj bool s = TREE_SIDE_EFFECTS (init);
375538fd1498Szrj if (!c || s)
375638fd1498Szrj FOR_EACH_VEC_SAFE_ELT (ctors, i, elt)
375738fd1498Szrj {
375838fd1498Szrj if (!c)
375938fd1498Szrj TREE_CONSTANT (elt) = false;
376038fd1498Szrj if (s)
376138fd1498Szrj TREE_SIDE_EFFECTS (elt) = true;
376238fd1498Szrj }
376338fd1498Szrj release_tree_vector (ctors);
376438fd1498Szrj
376538fd1498Szrj if (*non_constant_p)
376638fd1498Szrj return t;
376738fd1498Szrj else if (lval)
376838fd1498Szrj return target;
376938fd1498Szrj else
377038fd1498Szrj return init;
377138fd1498Szrj }
377238fd1498Szrj
377338fd1498Szrj /* Evaluate a ++ or -- expression. */
377438fd1498Szrj
377538fd1498Szrj static tree
cxx_eval_increment_expression(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p)377638fd1498Szrj cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
377738fd1498Szrj bool lval,
377838fd1498Szrj bool *non_constant_p, bool *overflow_p)
377938fd1498Szrj {
378038fd1498Szrj enum tree_code code = TREE_CODE (t);
378138fd1498Szrj tree type = TREE_TYPE (t);
378238fd1498Szrj tree op = TREE_OPERAND (t, 0);
378338fd1498Szrj tree offset = TREE_OPERAND (t, 1);
378438fd1498Szrj gcc_assert (TREE_CONSTANT (offset));
378538fd1498Szrj
378638fd1498Szrj /* The operand as an lvalue. */
378738fd1498Szrj op = cxx_eval_constant_expression (ctx, op, true,
378838fd1498Szrj non_constant_p, overflow_p);
378938fd1498Szrj
379038fd1498Szrj /* The operand as an rvalue. */
379138fd1498Szrj tree val
379238fd1498Szrj = cxx_eval_constant_expression (ctx, op, false,
379338fd1498Szrj non_constant_p, overflow_p);
379438fd1498Szrj /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
379538fd1498Szrj a local array in a constexpr function. */
379638fd1498Szrj bool ptr = POINTER_TYPE_P (TREE_TYPE (val));
379738fd1498Szrj if (!ptr)
379838fd1498Szrj VERIFY_CONSTANT (val);
379938fd1498Szrj
380038fd1498Szrj /* The modified value. */
380138fd1498Szrj bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
380238fd1498Szrj tree mod;
380338fd1498Szrj if (POINTER_TYPE_P (type))
380438fd1498Szrj {
380538fd1498Szrj /* The middle end requires pointers to use POINTER_PLUS_EXPR. */
380638fd1498Szrj offset = convert_to_ptrofftype (offset);
380738fd1498Szrj if (!inc)
380838fd1498Szrj offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
380938fd1498Szrj mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
381038fd1498Szrj }
381138fd1498Szrj else
381238fd1498Szrj mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
381338fd1498Szrj if (!ptr)
381438fd1498Szrj VERIFY_CONSTANT (mod);
381538fd1498Szrj
381638fd1498Szrj /* Storing the modified value. */
381738fd1498Szrj tree store = build2 (MODIFY_EXPR, type, op, mod);
381838fd1498Szrj cxx_eval_constant_expression (ctx, store,
381938fd1498Szrj true, non_constant_p, overflow_p);
382038fd1498Szrj
382138fd1498Szrj /* And the value of the expression. */
382238fd1498Szrj if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
382338fd1498Szrj {
382438fd1498Szrj /* Prefix ops are lvalues. */
382538fd1498Szrj if (lval)
382638fd1498Szrj return op;
382738fd1498Szrj else
382838fd1498Szrj /* But we optimize when the caller wants an rvalue. */
382938fd1498Szrj return mod;
383038fd1498Szrj }
383138fd1498Szrj else
383238fd1498Szrj /* Postfix ops are rvalues. */
383338fd1498Szrj return val;
383438fd1498Szrj }
383538fd1498Szrj
383638fd1498Szrj /* Predicates for the meaning of *jump_target. */
383738fd1498Szrj
383838fd1498Szrj static bool
returns(tree * jump_target)383938fd1498Szrj returns (tree *jump_target)
384038fd1498Szrj {
384138fd1498Szrj return *jump_target
384238fd1498Szrj && (TREE_CODE (*jump_target) == RETURN_EXPR
384338fd1498Szrj || (TREE_CODE (*jump_target) == LABEL_DECL
384438fd1498Szrj && LABEL_DECL_CDTOR (*jump_target)));
384538fd1498Szrj }
384638fd1498Szrj
384738fd1498Szrj static bool
breaks(tree * jump_target)384838fd1498Szrj breaks (tree *jump_target)
384938fd1498Szrj {
385038fd1498Szrj return *jump_target
385138fd1498Szrj && ((TREE_CODE (*jump_target) == LABEL_DECL
385238fd1498Szrj && LABEL_DECL_BREAK (*jump_target))
385338fd1498Szrj || TREE_CODE (*jump_target) == EXIT_EXPR);
385438fd1498Szrj }
385538fd1498Szrj
385638fd1498Szrj static bool
continues(tree * jump_target)385738fd1498Szrj continues (tree *jump_target)
385838fd1498Szrj {
385938fd1498Szrj return *jump_target
386038fd1498Szrj && TREE_CODE (*jump_target) == LABEL_DECL
386138fd1498Szrj && LABEL_DECL_CONTINUE (*jump_target);
386238fd1498Szrj }
386338fd1498Szrj
386438fd1498Szrj static bool
switches(tree * jump_target)386538fd1498Szrj switches (tree *jump_target)
386638fd1498Szrj {
386738fd1498Szrj return *jump_target
386838fd1498Szrj && TREE_CODE (*jump_target) == INTEGER_CST;
386938fd1498Szrj }
387038fd1498Szrj
387138fd1498Szrj /* Subroutine of cxx_eval_statement_list. Determine whether the statement
387238fd1498Szrj STMT matches *jump_target. If we're looking for a case label and we see
387338fd1498Szrj the default label, note it in ctx->css_state. */
387438fd1498Szrj
387538fd1498Szrj static bool
label_matches(const constexpr_ctx * ctx,tree * jump_target,tree stmt)387638fd1498Szrj label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
387738fd1498Szrj {
387838fd1498Szrj switch (TREE_CODE (*jump_target))
387938fd1498Szrj {
388038fd1498Szrj case LABEL_DECL:
388138fd1498Szrj if (TREE_CODE (stmt) == LABEL_EXPR
388238fd1498Szrj && LABEL_EXPR_LABEL (stmt) == *jump_target)
388338fd1498Szrj return true;
388438fd1498Szrj break;
388538fd1498Szrj
388638fd1498Szrj case INTEGER_CST:
388738fd1498Szrj if (TREE_CODE (stmt) == CASE_LABEL_EXPR)
388838fd1498Szrj {
388938fd1498Szrj gcc_assert (ctx->css_state != NULL);
389038fd1498Szrj if (!CASE_LOW (stmt))
389138fd1498Szrj {
389238fd1498Szrj /* default: should appear just once in a SWITCH_EXPR
389338fd1498Szrj body (excluding nested SWITCH_EXPR). */
389438fd1498Szrj gcc_assert (*ctx->css_state != css_default_seen);
389538fd1498Szrj /* When evaluating SWITCH_EXPR body for the second time,
389638fd1498Szrj return true for the default: label. */
389738fd1498Szrj if (*ctx->css_state == css_default_processing)
389838fd1498Szrj return true;
389938fd1498Szrj *ctx->css_state = css_default_seen;
390038fd1498Szrj }
390138fd1498Szrj else if (CASE_HIGH (stmt))
390238fd1498Szrj {
390338fd1498Szrj if (tree_int_cst_le (CASE_LOW (stmt), *jump_target)
390438fd1498Szrj && tree_int_cst_le (*jump_target, CASE_HIGH (stmt)))
390538fd1498Szrj return true;
390638fd1498Szrj }
390738fd1498Szrj else if (tree_int_cst_equal (*jump_target, CASE_LOW (stmt)))
390838fd1498Szrj return true;
390938fd1498Szrj }
391038fd1498Szrj break;
391138fd1498Szrj
391238fd1498Szrj default:
391338fd1498Szrj gcc_unreachable ();
391438fd1498Szrj }
391538fd1498Szrj return false;
391638fd1498Szrj }
391738fd1498Szrj
391838fd1498Szrj /* Evaluate a STATEMENT_LIST for side-effects. Handles various jump
391938fd1498Szrj semantics, for switch, break, continue, and return. */
392038fd1498Szrj
392138fd1498Szrj static tree
cxx_eval_statement_list(const constexpr_ctx * ctx,tree t,bool * non_constant_p,bool * overflow_p,tree * jump_target)392238fd1498Szrj cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
392338fd1498Szrj bool *non_constant_p, bool *overflow_p,
392438fd1498Szrj tree *jump_target)
392538fd1498Szrj {
392638fd1498Szrj tree_stmt_iterator i;
392738fd1498Szrj tree local_target;
392838fd1498Szrj /* In a statement-expression we want to return the last value.
392938fd1498Szrj For empty statement expression return void_node. */
393038fd1498Szrj tree r = void_node;
393138fd1498Szrj if (!jump_target)
393238fd1498Szrj {
393338fd1498Szrj local_target = NULL_TREE;
393438fd1498Szrj jump_target = &local_target;
393538fd1498Szrj }
393638fd1498Szrj for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
393738fd1498Szrj {
393838fd1498Szrj tree stmt = tsi_stmt (i);
3939*58e805e6Szrj /* We've found a continue, so skip everything until we reach
3940*58e805e6Szrj the label its jumping to. */
3941*58e805e6Szrj if (continues (jump_target))
3942*58e805e6Szrj {
3943*58e805e6Szrj if (label_matches (ctx, jump_target, stmt))
3944*58e805e6Szrj /* Found it. */
3945*58e805e6Szrj *jump_target = NULL_TREE;
3946*58e805e6Szrj else
3947*58e805e6Szrj continue;
3948*58e805e6Szrj }
394938fd1498Szrj if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
395038fd1498Szrj continue;
395138fd1498Szrj r = cxx_eval_constant_expression (ctx, stmt, false,
395238fd1498Szrj non_constant_p, overflow_p,
395338fd1498Szrj jump_target);
395438fd1498Szrj if (*non_constant_p)
395538fd1498Szrj break;
395638fd1498Szrj if (returns (jump_target) || breaks (jump_target))
395738fd1498Szrj break;
395838fd1498Szrj }
395938fd1498Szrj return r;
396038fd1498Szrj }
396138fd1498Szrj
396238fd1498Szrj /* Evaluate a LOOP_EXPR for side-effects. Handles break and return
396338fd1498Szrj semantics; continue semantics are covered by cxx_eval_statement_list. */
396438fd1498Szrj
396538fd1498Szrj static tree
cxx_eval_loop_expr(const constexpr_ctx * ctx,tree t,bool * non_constant_p,bool * overflow_p,tree * jump_target)396638fd1498Szrj cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
396738fd1498Szrj bool *non_constant_p, bool *overflow_p,
396838fd1498Szrj tree *jump_target)
396938fd1498Szrj {
397038fd1498Szrj constexpr_ctx new_ctx = *ctx;
397138fd1498Szrj
397238fd1498Szrj tree body = TREE_OPERAND (t, 0);
397338fd1498Szrj int count = 0;
397438fd1498Szrj do
397538fd1498Szrj {
397638fd1498Szrj hash_set<tree> save_exprs;
397738fd1498Szrj new_ctx.save_exprs = &save_exprs;
397838fd1498Szrj
397938fd1498Szrj cxx_eval_constant_expression (&new_ctx, body, /*lval*/false,
398038fd1498Szrj non_constant_p, overflow_p, jump_target);
398138fd1498Szrj
398238fd1498Szrj /* Forget saved values of SAVE_EXPRs. */
398338fd1498Szrj for (hash_set<tree>::iterator iter = save_exprs.begin();
398438fd1498Szrj iter != save_exprs.end(); ++iter)
398538fd1498Szrj new_ctx.values->remove (*iter);
398638fd1498Szrj if (++count >= constexpr_loop_limit)
398738fd1498Szrj {
398838fd1498Szrj if (!ctx->quiet)
398938fd1498Szrj error_at (EXPR_LOC_OR_LOC (t, input_location),
399038fd1498Szrj "%<constexpr%> loop iteration count exceeds limit of %d "
399138fd1498Szrj "(use -fconstexpr-loop-limit= to increase the limit)",
399238fd1498Szrj constexpr_loop_limit);
399338fd1498Szrj *non_constant_p = true;
399438fd1498Szrj break;
399538fd1498Szrj }
399638fd1498Szrj }
399738fd1498Szrj while (!returns (jump_target)
399838fd1498Szrj && !breaks (jump_target)
399938fd1498Szrj && !switches (jump_target)
400038fd1498Szrj && !*non_constant_p);
400138fd1498Szrj
400238fd1498Szrj if (breaks (jump_target))
400338fd1498Szrj *jump_target = NULL_TREE;
400438fd1498Szrj
400538fd1498Szrj return NULL_TREE;
400638fd1498Szrj }
400738fd1498Szrj
400838fd1498Szrj /* Evaluate a SWITCH_EXPR for side-effects. Handles switch and break jump
400938fd1498Szrj semantics. */
401038fd1498Szrj
401138fd1498Szrj static tree
cxx_eval_switch_expr(const constexpr_ctx * ctx,tree t,bool * non_constant_p,bool * overflow_p,tree * jump_target)401238fd1498Szrj cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
401338fd1498Szrj bool *non_constant_p, bool *overflow_p,
401438fd1498Szrj tree *jump_target)
401538fd1498Szrj {
4016*58e805e6Szrj tree cond = SWITCH_COND (t);
401738fd1498Szrj cond = cxx_eval_constant_expression (ctx, cond, false,
401838fd1498Szrj non_constant_p, overflow_p);
401938fd1498Szrj VERIFY_CONSTANT (cond);
402038fd1498Szrj *jump_target = cond;
402138fd1498Szrj
4022*58e805e6Szrj tree body = SWITCH_BODY (t);
402338fd1498Szrj constexpr_ctx new_ctx = *ctx;
402438fd1498Szrj constexpr_switch_state css = css_default_not_seen;
402538fd1498Szrj new_ctx.css_state = &css;
402638fd1498Szrj cxx_eval_constant_expression (&new_ctx, body, false,
402738fd1498Szrj non_constant_p, overflow_p, jump_target);
402838fd1498Szrj if (switches (jump_target) && css == css_default_seen)
402938fd1498Szrj {
403038fd1498Szrj /* If the SWITCH_EXPR body has default: label, process it once again,
403138fd1498Szrj this time instructing label_matches to return true for default:
403238fd1498Szrj label on switches (jump_target). */
403338fd1498Szrj css = css_default_processing;
403438fd1498Szrj cxx_eval_constant_expression (&new_ctx, body, false,
403538fd1498Szrj non_constant_p, overflow_p, jump_target);
403638fd1498Szrj }
403738fd1498Szrj if (breaks (jump_target) || switches (jump_target))
403838fd1498Szrj *jump_target = NULL_TREE;
403938fd1498Szrj return NULL_TREE;
404038fd1498Szrj }
404138fd1498Szrj
404238fd1498Szrj /* Find the object of TYPE under initialization in CTX. */
404338fd1498Szrj
404438fd1498Szrj static tree
lookup_placeholder(const constexpr_ctx * ctx,bool lval,tree type)404538fd1498Szrj lookup_placeholder (const constexpr_ctx *ctx, bool lval, tree type)
404638fd1498Szrj {
404738fd1498Szrj if (!ctx)
404838fd1498Szrj return NULL_TREE;
404938fd1498Szrj
405038fd1498Szrj /* We could use ctx->object unconditionally, but using ctx->ctor when we
405138fd1498Szrj can is a minor optimization. */
405238fd1498Szrj if (!lval && ctx->ctor && same_type_p (TREE_TYPE (ctx->ctor), type))
405338fd1498Szrj return ctx->ctor;
405438fd1498Szrj
405538fd1498Szrj if (!ctx->object)
405638fd1498Szrj return NULL_TREE;
405738fd1498Szrj
405838fd1498Szrj /* Since an object cannot have a field of its own type, we can search outward
405938fd1498Szrj from ctx->object to find the unique containing object of TYPE. */
406038fd1498Szrj tree ob = ctx->object;
406138fd1498Szrj while (ob)
406238fd1498Szrj {
406338fd1498Szrj if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type))
406438fd1498Szrj break;
406538fd1498Szrj if (handled_component_p (ob))
406638fd1498Szrj ob = TREE_OPERAND (ob, 0);
406738fd1498Szrj else
406838fd1498Szrj ob = NULL_TREE;
406938fd1498Szrj }
407038fd1498Szrj
407138fd1498Szrj return ob;
407238fd1498Szrj }
407338fd1498Szrj
407438fd1498Szrj /* Attempt to reduce the expression T to a constant value.
407538fd1498Szrj On failure, issue diagnostic and return error_mark_node. */
407638fd1498Szrj /* FIXME unify with c_fully_fold */
407738fd1498Szrj /* FIXME overflow_p is too global */
407838fd1498Szrj
407938fd1498Szrj static tree
cxx_eval_constant_expression(const constexpr_ctx * ctx,tree t,bool lval,bool * non_constant_p,bool * overflow_p,tree * jump_target)408038fd1498Szrj cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
408138fd1498Szrj bool lval,
408238fd1498Szrj bool *non_constant_p, bool *overflow_p,
408338fd1498Szrj tree *jump_target)
408438fd1498Szrj {
408538fd1498Szrj constexpr_ctx new_ctx;
408638fd1498Szrj tree r = t;
408738fd1498Szrj
408838fd1498Szrj if (jump_target && *jump_target)
408938fd1498Szrj {
409038fd1498Szrj /* If we are jumping, ignore all statements/expressions except those
409138fd1498Szrj that could have LABEL_EXPR or CASE_LABEL_EXPR in their bodies. */
409238fd1498Szrj switch (TREE_CODE (t))
409338fd1498Szrj {
409438fd1498Szrj case BIND_EXPR:
409538fd1498Szrj case STATEMENT_LIST:
409638fd1498Szrj case LOOP_EXPR:
409738fd1498Szrj case COND_EXPR:
409838fd1498Szrj break;
409938fd1498Szrj case LABEL_EXPR:
410038fd1498Szrj case CASE_LABEL_EXPR:
410138fd1498Szrj if (label_matches (ctx, jump_target, t))
410238fd1498Szrj /* Found it. */
410338fd1498Szrj *jump_target = NULL_TREE;
410438fd1498Szrj return NULL_TREE;
410538fd1498Szrj default:
410638fd1498Szrj return NULL_TREE;
410738fd1498Szrj }
410838fd1498Szrj }
410938fd1498Szrj if (t == error_mark_node)
411038fd1498Szrj {
411138fd1498Szrj *non_constant_p = true;
411238fd1498Szrj return t;
411338fd1498Szrj }
411438fd1498Szrj if (CONSTANT_CLASS_P (t))
411538fd1498Szrj {
411638fd1498Szrj if (TREE_OVERFLOW (t))
411738fd1498Szrj {
411838fd1498Szrj if (!ctx->quiet)
411938fd1498Szrj permerror (input_location, "overflow in constant expression");
412038fd1498Szrj if (!flag_permissive || ctx->quiet)
412138fd1498Szrj *overflow_p = true;
412238fd1498Szrj }
412338fd1498Szrj
412438fd1498Szrj if (TREE_CODE (t) == INTEGER_CST
412538fd1498Szrj && TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
412638fd1498Szrj && !integer_zerop (t))
412738fd1498Szrj {
412838fd1498Szrj if (!ctx->quiet)
412938fd1498Szrj error ("value %qE of type %qT is not a constant expression",
413038fd1498Szrj t, TREE_TYPE (t));
413138fd1498Szrj *non_constant_p = true;
413238fd1498Szrj }
413338fd1498Szrj
413438fd1498Szrj return t;
413538fd1498Szrj }
413638fd1498Szrj
413738fd1498Szrj tree_code tcode = TREE_CODE (t);
413838fd1498Szrj switch (tcode)
413938fd1498Szrj {
414038fd1498Szrj case RESULT_DECL:
414138fd1498Szrj if (lval)
414238fd1498Szrj return t;
414338fd1498Szrj /* We ask for an rvalue for the RESULT_DECL when indirecting
414438fd1498Szrj through an invisible reference, or in named return value
414538fd1498Szrj optimization. */
414638fd1498Szrj if (tree *p = ctx->values->get (t))
414738fd1498Szrj return *p;
414838fd1498Szrj else
414938fd1498Szrj {
415038fd1498Szrj if (!ctx->quiet)
415138fd1498Szrj error ("%qE is not a constant expression", t);
415238fd1498Szrj *non_constant_p = true;
415338fd1498Szrj }
415438fd1498Szrj break;
415538fd1498Szrj
415638fd1498Szrj case VAR_DECL:
415738fd1498Szrj if (DECL_HAS_VALUE_EXPR_P (t))
415838fd1498Szrj return cxx_eval_constant_expression (ctx, DECL_VALUE_EXPR (t),
415938fd1498Szrj lval, non_constant_p, overflow_p);
416038fd1498Szrj /* fall through */
416138fd1498Szrj case CONST_DECL:
416238fd1498Szrj /* We used to not check lval for CONST_DECL, but darwin.c uses
416338fd1498Szrj CONST_DECL for aggregate constants. */
416438fd1498Szrj if (lval)
416538fd1498Szrj return t;
416638fd1498Szrj if (COMPLETE_TYPE_P (TREE_TYPE (t))
416738fd1498Szrj && is_really_empty_class (TREE_TYPE (t)))
416838fd1498Szrj {
416938fd1498Szrj /* If the class is empty, we aren't actually loading anything. */
417038fd1498Szrj r = build_constructor (TREE_TYPE (t), NULL);
417138fd1498Szrj TREE_CONSTANT (r) = true;
417238fd1498Szrj }
417338fd1498Szrj else if (ctx->strict)
417438fd1498Szrj r = decl_really_constant_value (t);
417538fd1498Szrj else
417638fd1498Szrj r = decl_constant_value (t);
417738fd1498Szrj if (TREE_CODE (r) == TARGET_EXPR
417838fd1498Szrj && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
417938fd1498Szrj r = TARGET_EXPR_INITIAL (r);
418038fd1498Szrj if (VAR_P (r))
418138fd1498Szrj if (tree *p = ctx->values->get (r))
418238fd1498Szrj if (*p != NULL_TREE)
418338fd1498Szrj r = *p;
418438fd1498Szrj if (DECL_P (r))
418538fd1498Szrj {
418638fd1498Szrj if (!ctx->quiet)
418738fd1498Szrj non_const_var_error (r);
418838fd1498Szrj *non_constant_p = true;
418938fd1498Szrj }
419038fd1498Szrj break;
419138fd1498Szrj
419238fd1498Szrj case DEBUG_BEGIN_STMT:
419338fd1498Szrj /* ??? It might be nice to retain this information somehow, so
419438fd1498Szrj as to be able to step into a constexpr function call. */
419538fd1498Szrj /* Fall through. */
419638fd1498Szrj
419738fd1498Szrj case FUNCTION_DECL:
419838fd1498Szrj case TEMPLATE_DECL:
419938fd1498Szrj case LABEL_DECL:
420038fd1498Szrj case LABEL_EXPR:
420138fd1498Szrj case CASE_LABEL_EXPR:
420238fd1498Szrj case PREDICT_EXPR:
420338fd1498Szrj return t;
420438fd1498Szrj
420538fd1498Szrj case PARM_DECL:
420638fd1498Szrj if (lval && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
420738fd1498Szrj /* glvalue use. */;
420838fd1498Szrj else if (tree *p = ctx->values->get (r))
420938fd1498Szrj r = *p;
421038fd1498Szrj else if (lval)
421138fd1498Szrj /* Defer in case this is only used for its type. */;
421238fd1498Szrj else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
421338fd1498Szrj /* Defer, there's no lvalue->rvalue conversion. */;
421438fd1498Szrj else if (COMPLETE_TYPE_P (TREE_TYPE (t))
421538fd1498Szrj && is_really_empty_class (TREE_TYPE (t)))
421638fd1498Szrj {
421738fd1498Szrj /* If the class is empty, we aren't actually loading anything. */
421838fd1498Szrj r = build_constructor (TREE_TYPE (t), NULL);
421938fd1498Szrj TREE_CONSTANT (r) = true;
422038fd1498Szrj }
422138fd1498Szrj else
422238fd1498Szrj {
422338fd1498Szrj if (!ctx->quiet)
422438fd1498Szrj error ("%qE is not a constant expression", t);
422538fd1498Szrj *non_constant_p = true;
422638fd1498Szrj }
422738fd1498Szrj break;
422838fd1498Szrj
422938fd1498Szrj case CALL_EXPR:
423038fd1498Szrj case AGGR_INIT_EXPR:
423138fd1498Szrj r = cxx_eval_call_expression (ctx, t, lval,
423238fd1498Szrj non_constant_p, overflow_p);
423338fd1498Szrj break;
423438fd1498Szrj
423538fd1498Szrj case DECL_EXPR:
423638fd1498Szrj {
423738fd1498Szrj r = DECL_EXPR_DECL (t);
423838fd1498Szrj if (AGGREGATE_TYPE_P (TREE_TYPE (r))
423938fd1498Szrj || VECTOR_TYPE_P (TREE_TYPE (r)))
424038fd1498Szrj {
424138fd1498Szrj new_ctx = *ctx;
424238fd1498Szrj new_ctx.object = r;
424338fd1498Szrj new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
424438fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = true;
424538fd1498Szrj new_ctx.values->put (r, new_ctx.ctor);
424638fd1498Szrj ctx = &new_ctx;
424738fd1498Szrj }
424838fd1498Szrj
424938fd1498Szrj if (tree init = DECL_INITIAL (r))
425038fd1498Szrj {
425138fd1498Szrj init = cxx_eval_constant_expression (ctx, init,
425238fd1498Szrj false,
425338fd1498Szrj non_constant_p, overflow_p);
425438fd1498Szrj /* Don't share a CONSTRUCTOR that might be changed. */
425538fd1498Szrj init = unshare_constructor (init);
425638fd1498Szrj ctx->values->put (r, init);
425738fd1498Szrj }
425838fd1498Szrj else if (ctx == &new_ctx)
425938fd1498Szrj /* We gave it a CONSTRUCTOR above. */;
426038fd1498Szrj else
426138fd1498Szrj ctx->values->put (r, NULL_TREE);
426238fd1498Szrj }
426338fd1498Szrj break;
426438fd1498Szrj
426538fd1498Szrj case TARGET_EXPR:
426638fd1498Szrj if (!literal_type_p (TREE_TYPE (t)))
426738fd1498Szrj {
426838fd1498Szrj if (!ctx->quiet)
426938fd1498Szrj {
427038fd1498Szrj error ("temporary of non-literal type %qT in a "
427138fd1498Szrj "constant expression", TREE_TYPE (t));
427238fd1498Szrj explain_non_literal_class (TREE_TYPE (t));
427338fd1498Szrj }
427438fd1498Szrj *non_constant_p = true;
427538fd1498Szrj break;
427638fd1498Szrj }
427738fd1498Szrj if ((AGGREGATE_TYPE_P (TREE_TYPE (t)) || VECTOR_TYPE_P (TREE_TYPE (t))))
427838fd1498Szrj {
427938fd1498Szrj /* We're being expanded without an explicit target, so start
428038fd1498Szrj initializing a new object; expansion with an explicit target
428138fd1498Szrj strips the TARGET_EXPR before we get here. */
428238fd1498Szrj new_ctx = *ctx;
428338fd1498Szrj new_ctx.ctor = build_constructor (TREE_TYPE (t), NULL);
428438fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = true;
428538fd1498Szrj new_ctx.object = TARGET_EXPR_SLOT (t);
428638fd1498Szrj ctx->values->put (new_ctx.object, new_ctx.ctor);
428738fd1498Szrj ctx = &new_ctx;
428838fd1498Szrj }
428938fd1498Szrj /* Pass false for 'lval' because this indicates
429038fd1498Szrj initialization of a temporary. */
429138fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
429238fd1498Szrj false,
429338fd1498Szrj non_constant_p, overflow_p);
429438fd1498Szrj if (!*non_constant_p)
429538fd1498Szrj /* Adjust the type of the result to the type of the temporary. */
429638fd1498Szrj r = adjust_temp_type (TREE_TYPE (t), r);
429738fd1498Szrj if (lval)
429838fd1498Szrj {
429938fd1498Szrj tree slot = TARGET_EXPR_SLOT (t);
430038fd1498Szrj r = unshare_constructor (r);
430138fd1498Szrj ctx->values->put (slot, r);
430238fd1498Szrj return slot;
430338fd1498Szrj }
430438fd1498Szrj break;
430538fd1498Szrj
430638fd1498Szrj case INIT_EXPR:
430738fd1498Szrj case MODIFY_EXPR:
430838fd1498Szrj gcc_assert (jump_target == NULL || *jump_target == NULL_TREE);
430938fd1498Szrj r = cxx_eval_store_expression (ctx, t, lval,
431038fd1498Szrj non_constant_p, overflow_p);
431138fd1498Szrj break;
431238fd1498Szrj
431338fd1498Szrj case SCOPE_REF:
431438fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
431538fd1498Szrj lval,
431638fd1498Szrj non_constant_p, overflow_p);
431738fd1498Szrj break;
431838fd1498Szrj
431938fd1498Szrj case RETURN_EXPR:
432038fd1498Szrj if (TREE_OPERAND (t, 0) != NULL_TREE)
432138fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
432238fd1498Szrj lval,
432338fd1498Szrj non_constant_p, overflow_p);
432438fd1498Szrj if (jump_target)
432538fd1498Szrj *jump_target = t;
432638fd1498Szrj else
432738fd1498Szrj {
432838fd1498Szrj /* Can happen with ({ return true; }) && false; passed to
432938fd1498Szrj maybe_constant_value. There is nothing to jump over in this
433038fd1498Szrj case, and the bug will be diagnosed later. */
433138fd1498Szrj gcc_assert (ctx->quiet);
433238fd1498Szrj *non_constant_p = true;
433338fd1498Szrj }
433438fd1498Szrj break;
433538fd1498Szrj
433638fd1498Szrj case SAVE_EXPR:
433738fd1498Szrj /* Avoid evaluating a SAVE_EXPR more than once. */
433838fd1498Szrj if (tree *p = ctx->values->get (t))
433938fd1498Szrj r = *p;
434038fd1498Szrj else
434138fd1498Szrj {
434238fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), false,
434338fd1498Szrj non_constant_p, overflow_p);
434438fd1498Szrj ctx->values->put (t, r);
434538fd1498Szrj if (ctx->save_exprs)
434638fd1498Szrj ctx->save_exprs->add (t);
434738fd1498Szrj }
434838fd1498Szrj break;
434938fd1498Szrj
435038fd1498Szrj case NON_LVALUE_EXPR:
435138fd1498Szrj case TRY_CATCH_EXPR:
435238fd1498Szrj case TRY_BLOCK:
435338fd1498Szrj case CLEANUP_POINT_EXPR:
435438fd1498Szrj case MUST_NOT_THROW_EXPR:
435538fd1498Szrj case EXPR_STMT:
435638fd1498Szrj case EH_SPEC_BLOCK:
435738fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
435838fd1498Szrj lval,
435938fd1498Szrj non_constant_p, overflow_p,
436038fd1498Szrj jump_target);
436138fd1498Szrj break;
436238fd1498Szrj
436338fd1498Szrj case TRY_FINALLY_EXPR:
436438fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
436538fd1498Szrj non_constant_p, overflow_p,
436638fd1498Szrj jump_target);
436738fd1498Szrj if (!*non_constant_p)
436838fd1498Szrj /* Also evaluate the cleanup. */
436938fd1498Szrj cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), true,
437038fd1498Szrj non_constant_p, overflow_p,
437138fd1498Szrj jump_target);
437238fd1498Szrj break;
437338fd1498Szrj
437438fd1498Szrj /* These differ from cxx_eval_unary_expression in that this doesn't
437538fd1498Szrj check for a constant operand or result; an address can be
437638fd1498Szrj constant without its operand being, and vice versa. */
437738fd1498Szrj case MEM_REF:
437838fd1498Szrj case INDIRECT_REF:
437938fd1498Szrj r = cxx_eval_indirect_ref (ctx, t, lval,
438038fd1498Szrj non_constant_p, overflow_p);
438138fd1498Szrj break;
438238fd1498Szrj
438338fd1498Szrj case ADDR_EXPR:
438438fd1498Szrj {
438538fd1498Szrj tree oldop = TREE_OPERAND (t, 0);
438638fd1498Szrj tree op = cxx_eval_constant_expression (ctx, oldop,
438738fd1498Szrj /*lval*/true,
438838fd1498Szrj non_constant_p, overflow_p);
438938fd1498Szrj /* Don't VERIFY_CONSTANT here. */
439038fd1498Szrj if (*non_constant_p)
439138fd1498Szrj return t;
439238fd1498Szrj gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR);
439338fd1498Szrj /* This function does more aggressive folding than fold itself. */
439438fd1498Szrj r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
439538fd1498Szrj if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
439638fd1498Szrj return t;
439738fd1498Szrj break;
439838fd1498Szrj }
439938fd1498Szrj
440038fd1498Szrj case REALPART_EXPR:
440138fd1498Szrj case IMAGPART_EXPR:
440238fd1498Szrj if (lval)
440338fd1498Szrj {
440438fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
440538fd1498Szrj non_constant_p, overflow_p);
440638fd1498Szrj if (r == error_mark_node)
440738fd1498Szrj ;
440838fd1498Szrj else if (r == TREE_OPERAND (t, 0))
440938fd1498Szrj r = t;
441038fd1498Szrj else
441138fd1498Szrj r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
441238fd1498Szrj break;
441338fd1498Szrj }
441438fd1498Szrj /* FALLTHRU */
441538fd1498Szrj case CONJ_EXPR:
441638fd1498Szrj case FIX_TRUNC_EXPR:
441738fd1498Szrj case FLOAT_EXPR:
441838fd1498Szrj case NEGATE_EXPR:
441938fd1498Szrj case ABS_EXPR:
442038fd1498Szrj case BIT_NOT_EXPR:
442138fd1498Szrj case TRUTH_NOT_EXPR:
442238fd1498Szrj case FIXED_CONVERT_EXPR:
442338fd1498Szrj r = cxx_eval_unary_expression (ctx, t, lval,
442438fd1498Szrj non_constant_p, overflow_p);
442538fd1498Szrj break;
442638fd1498Szrj
442738fd1498Szrj case SIZEOF_EXPR:
442838fd1498Szrj r = fold_sizeof_expr (t);
442938fd1498Szrj VERIFY_CONSTANT (r);
443038fd1498Szrj break;
443138fd1498Szrj
443238fd1498Szrj case COMPOUND_EXPR:
443338fd1498Szrj {
443438fd1498Szrj /* check_return_expr sometimes wraps a TARGET_EXPR in a
443538fd1498Szrj COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
443638fd1498Szrj introduced by build_call_a. */
443738fd1498Szrj tree op0 = TREE_OPERAND (t, 0);
443838fd1498Szrj tree op1 = TREE_OPERAND (t, 1);
443938fd1498Szrj STRIP_NOPS (op1);
444038fd1498Szrj if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
444138fd1498Szrj || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
444238fd1498Szrj r = cxx_eval_constant_expression (ctx, op0,
444338fd1498Szrj lval, non_constant_p, overflow_p,
444438fd1498Szrj jump_target);
444538fd1498Szrj else
444638fd1498Szrj {
444738fd1498Szrj /* Check that the LHS is constant and then discard it. */
444838fd1498Szrj cxx_eval_constant_expression (ctx, op0,
444938fd1498Szrj true, non_constant_p, overflow_p,
445038fd1498Szrj jump_target);
445138fd1498Szrj if (*non_constant_p)
445238fd1498Szrj return t;
445338fd1498Szrj op1 = TREE_OPERAND (t, 1);
445438fd1498Szrj r = cxx_eval_constant_expression (ctx, op1,
445538fd1498Szrj lval, non_constant_p, overflow_p,
445638fd1498Szrj jump_target);
445738fd1498Szrj }
445838fd1498Szrj }
445938fd1498Szrj break;
446038fd1498Szrj
446138fd1498Szrj case POINTER_PLUS_EXPR:
446238fd1498Szrj case POINTER_DIFF_EXPR:
446338fd1498Szrj case PLUS_EXPR:
446438fd1498Szrj case MINUS_EXPR:
446538fd1498Szrj case MULT_EXPR:
446638fd1498Szrj case TRUNC_DIV_EXPR:
446738fd1498Szrj case CEIL_DIV_EXPR:
446838fd1498Szrj case FLOOR_DIV_EXPR:
446938fd1498Szrj case ROUND_DIV_EXPR:
447038fd1498Szrj case TRUNC_MOD_EXPR:
447138fd1498Szrj case CEIL_MOD_EXPR:
447238fd1498Szrj case ROUND_MOD_EXPR:
447338fd1498Szrj case RDIV_EXPR:
447438fd1498Szrj case EXACT_DIV_EXPR:
447538fd1498Szrj case MIN_EXPR:
447638fd1498Szrj case MAX_EXPR:
447738fd1498Szrj case LSHIFT_EXPR:
447838fd1498Szrj case RSHIFT_EXPR:
447938fd1498Szrj case LROTATE_EXPR:
448038fd1498Szrj case RROTATE_EXPR:
448138fd1498Szrj case BIT_IOR_EXPR:
448238fd1498Szrj case BIT_XOR_EXPR:
448338fd1498Szrj case BIT_AND_EXPR:
448438fd1498Szrj case TRUTH_XOR_EXPR:
448538fd1498Szrj case LT_EXPR:
448638fd1498Szrj case LE_EXPR:
448738fd1498Szrj case GT_EXPR:
448838fd1498Szrj case GE_EXPR:
448938fd1498Szrj case EQ_EXPR:
449038fd1498Szrj case NE_EXPR:
449138fd1498Szrj case UNORDERED_EXPR:
449238fd1498Szrj case ORDERED_EXPR:
449338fd1498Szrj case UNLT_EXPR:
449438fd1498Szrj case UNLE_EXPR:
449538fd1498Szrj case UNGT_EXPR:
449638fd1498Szrj case UNGE_EXPR:
449738fd1498Szrj case UNEQ_EXPR:
449838fd1498Szrj case LTGT_EXPR:
449938fd1498Szrj case RANGE_EXPR:
450038fd1498Szrj case COMPLEX_EXPR:
450138fd1498Szrj r = cxx_eval_binary_expression (ctx, t, lval,
450238fd1498Szrj non_constant_p, overflow_p);
450338fd1498Szrj break;
450438fd1498Szrj
450538fd1498Szrj /* fold can introduce non-IF versions of these; still treat them as
450638fd1498Szrj short-circuiting. */
450738fd1498Szrj case TRUTH_AND_EXPR:
450838fd1498Szrj case TRUTH_ANDIF_EXPR:
450938fd1498Szrj r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
451038fd1498Szrj boolean_true_node,
451138fd1498Szrj lval,
451238fd1498Szrj non_constant_p, overflow_p);
451338fd1498Szrj break;
451438fd1498Szrj
451538fd1498Szrj case TRUTH_OR_EXPR:
451638fd1498Szrj case TRUTH_ORIF_EXPR:
451738fd1498Szrj r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
451838fd1498Szrj boolean_false_node,
451938fd1498Szrj lval,
452038fd1498Szrj non_constant_p, overflow_p);
452138fd1498Szrj break;
452238fd1498Szrj
452338fd1498Szrj case ARRAY_REF:
452438fd1498Szrj r = cxx_eval_array_reference (ctx, t, lval,
452538fd1498Szrj non_constant_p, overflow_p);
452638fd1498Szrj break;
452738fd1498Szrj
452838fd1498Szrj case COMPONENT_REF:
452938fd1498Szrj if (is_overloaded_fn (t))
453038fd1498Szrj {
453138fd1498Szrj /* We can only get here in checking mode via
453238fd1498Szrj build_non_dependent_expr, because any expression that
453338fd1498Szrj calls or takes the address of the function will have
453438fd1498Szrj pulled a FUNCTION_DECL out of the COMPONENT_REF. */
453538fd1498Szrj gcc_checking_assert (ctx->quiet || errorcount);
453638fd1498Szrj *non_constant_p = true;
453738fd1498Szrj return t;
453838fd1498Szrj }
453938fd1498Szrj r = cxx_eval_component_reference (ctx, t, lval,
454038fd1498Szrj non_constant_p, overflow_p);
454138fd1498Szrj break;
454238fd1498Szrj
454338fd1498Szrj case BIT_FIELD_REF:
454438fd1498Szrj r = cxx_eval_bit_field_ref (ctx, t, lval,
454538fd1498Szrj non_constant_p, overflow_p);
454638fd1498Szrj break;
454738fd1498Szrj
454838fd1498Szrj case COND_EXPR:
454938fd1498Szrj if (jump_target && *jump_target)
455038fd1498Szrj {
4551*58e805e6Szrj tree orig_jump = *jump_target;
455238fd1498Szrj /* When jumping to a label, the label might be either in the
455338fd1498Szrj then or else blocks, so process then block first in skipping
455438fd1498Szrj mode first, and if we are still in the skipping mode at its end,
455538fd1498Szrj process the else block too. */
455638fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
455738fd1498Szrj lval, non_constant_p, overflow_p,
455838fd1498Szrj jump_target);
4559*58e805e6Szrj /* It's possible that we found the label in the then block. But
4560*58e805e6Szrj it could have been followed by another jumping statement, e.g.
4561*58e805e6Szrj say we're looking for case 1:
4562*58e805e6Szrj if (cond)
4563*58e805e6Szrj {
4564*58e805e6Szrj // skipped statements
4565*58e805e6Szrj case 1:; // clears up *jump_target
4566*58e805e6Szrj return 1; // and sets it to a RETURN_EXPR
4567*58e805e6Szrj }
4568*58e805e6Szrj else { ... }
4569*58e805e6Szrj in which case we need not go looking to the else block.
4570*58e805e6Szrj (goto is not allowed in a constexpr function.) */
4571*58e805e6Szrj if (*jump_target == orig_jump)
457238fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
457338fd1498Szrj lval, non_constant_p, overflow_p,
457438fd1498Szrj jump_target);
457538fd1498Szrj break;
457638fd1498Szrj }
457738fd1498Szrj r = cxx_eval_conditional_expression (ctx, t, lval,
457838fd1498Szrj non_constant_p, overflow_p,
457938fd1498Szrj jump_target);
458038fd1498Szrj break;
458138fd1498Szrj case VEC_COND_EXPR:
458238fd1498Szrj r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p,
458338fd1498Szrj overflow_p);
458438fd1498Szrj break;
458538fd1498Szrj
458638fd1498Szrj case CONSTRUCTOR:
4587*58e805e6Szrj if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
458838fd1498Szrj {
458938fd1498Szrj /* Don't re-process a constant CONSTRUCTOR, but do fold it to
459038fd1498Szrj VECTOR_CST if applicable. */
459138fd1498Szrj verify_constructor_flags (t);
459238fd1498Szrj if (TREE_CONSTANT (t))
459338fd1498Szrj return fold (t);
459438fd1498Szrj }
459538fd1498Szrj r = cxx_eval_bare_aggregate (ctx, t, lval,
459638fd1498Szrj non_constant_p, overflow_p);
459738fd1498Szrj break;
459838fd1498Szrj
459938fd1498Szrj case VEC_INIT_EXPR:
460038fd1498Szrj /* We can get this in a defaulted constructor for a class with a
460138fd1498Szrj non-static data member of array type. Either the initializer will
460238fd1498Szrj be NULL, meaning default-initialization, or it will be an lvalue
460338fd1498Szrj or xvalue of the same type, meaning direct-initialization from the
460438fd1498Szrj corresponding member. */
460538fd1498Szrj r = cxx_eval_vec_init (ctx, t, lval,
460638fd1498Szrj non_constant_p, overflow_p);
460738fd1498Szrj break;
460838fd1498Szrj
460938fd1498Szrj case FMA_EXPR:
461038fd1498Szrj case VEC_PERM_EXPR:
461138fd1498Szrj r = cxx_eval_trinary_expression (ctx, t, lval,
461238fd1498Szrj non_constant_p, overflow_p);
461338fd1498Szrj break;
461438fd1498Szrj
461538fd1498Szrj case NOP_EXPR:
461638fd1498Szrj if (REINTERPRET_CAST_P (t))
461738fd1498Szrj {
461838fd1498Szrj if (!ctx->quiet)
461938fd1498Szrj error_at (EXPR_LOC_OR_LOC (t, input_location),
462038fd1498Szrj "a reinterpret_cast is not a constant expression");
462138fd1498Szrj *non_constant_p = true;
462238fd1498Szrj return t;
462338fd1498Szrj }
462438fd1498Szrj /* FALLTHROUGH. */
462538fd1498Szrj case CONVERT_EXPR:
462638fd1498Szrj case VIEW_CONVERT_EXPR:
462738fd1498Szrj case UNARY_PLUS_EXPR:
462838fd1498Szrj {
462938fd1498Szrj tree oldop = TREE_OPERAND (t, 0);
463038fd1498Szrj
463138fd1498Szrj tree op = cxx_eval_constant_expression (ctx, oldop,
463238fd1498Szrj lval,
463338fd1498Szrj non_constant_p, overflow_p);
463438fd1498Szrj if (*non_constant_p)
463538fd1498Szrj return t;
463638fd1498Szrj tree type = TREE_TYPE (t);
463738fd1498Szrj if (TREE_CODE (op) == PTRMEM_CST
463838fd1498Szrj && !TYPE_PTRMEM_P (type))
463938fd1498Szrj op = cplus_expand_constant (op);
464038fd1498Szrj
464138fd1498Szrj if (TREE_CODE (op) == PTRMEM_CST && tcode == NOP_EXPR)
464238fd1498Szrj {
464338fd1498Szrj if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op))
464438fd1498Szrj && !can_convert_qual (type, op))
464538fd1498Szrj op = cplus_expand_constant (op);
464638fd1498Szrj return cp_fold_convert (type, op);
464738fd1498Szrj }
464838fd1498Szrj
464938fd1498Szrj if (POINTER_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
465038fd1498Szrj {
465138fd1498Szrj if (integer_zerop (op))
465238fd1498Szrj {
465338fd1498Szrj if (TREE_CODE (type) == REFERENCE_TYPE)
465438fd1498Szrj {
465538fd1498Szrj if (!ctx->quiet)
465638fd1498Szrj error_at (EXPR_LOC_OR_LOC (t, input_location),
465738fd1498Szrj "dereferencing a null pointer");
465838fd1498Szrj *non_constant_p = true;
465938fd1498Szrj return t;
466038fd1498Szrj }
466138fd1498Szrj else if (TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
466238fd1498Szrj {
466338fd1498Szrj tree from = TREE_TYPE (op);
466438fd1498Szrj
466538fd1498Szrj if (!can_convert (type, from, tf_none))
466638fd1498Szrj {
466738fd1498Szrj if (!ctx->quiet)
466838fd1498Szrj error_at (EXPR_LOC_OR_LOC (t, input_location),
466938fd1498Szrj "conversion of %qT null pointer to %qT "
467038fd1498Szrj "is not a constant expression",
467138fd1498Szrj from, type);
467238fd1498Szrj *non_constant_p = true;
467338fd1498Szrj return t;
467438fd1498Szrj }
467538fd1498Szrj }
467638fd1498Szrj }
467738fd1498Szrj else
467838fd1498Szrj {
467938fd1498Szrj /* This detects for example:
468038fd1498Szrj reinterpret_cast<void*>(sizeof 0)
468138fd1498Szrj */
468238fd1498Szrj if (!ctx->quiet)
468338fd1498Szrj error_at (EXPR_LOC_OR_LOC (t, input_location),
468438fd1498Szrj "%<reinterpret_cast<%T>(%E)%> is not "
468538fd1498Szrj "a constant expression",
468638fd1498Szrj type, op);
468738fd1498Szrj *non_constant_p = true;
468838fd1498Szrj return t;
468938fd1498Szrj }
469038fd1498Szrj }
469138fd1498Szrj
469238fd1498Szrj if (op == oldop && tcode != UNARY_PLUS_EXPR)
469338fd1498Szrj /* We didn't fold at the top so we could check for ptr-int
469438fd1498Szrj conversion. */
469538fd1498Szrj return fold (t);
469638fd1498Szrj
469738fd1498Szrj if (tcode == UNARY_PLUS_EXPR)
469838fd1498Szrj r = fold_convert (TREE_TYPE (t), op);
469938fd1498Szrj else
470038fd1498Szrj r = fold_build1 (tcode, type, op);
470138fd1498Szrj
470238fd1498Szrj /* Conversion of an out-of-range value has implementation-defined
470338fd1498Szrj behavior; the language considers it different from arithmetic
470438fd1498Szrj overflow, which is undefined. */
470538fd1498Szrj if (TREE_OVERFLOW_P (r) && !TREE_OVERFLOW_P (op))
470638fd1498Szrj TREE_OVERFLOW (r) = false;
470738fd1498Szrj }
470838fd1498Szrj break;
470938fd1498Szrj
471038fd1498Szrj case EMPTY_CLASS_EXPR:
471138fd1498Szrj /* This is good enough for a function argument that might not get
471238fd1498Szrj used, and they can't do anything with it, so just return it. */
471338fd1498Szrj return t;
471438fd1498Szrj
471538fd1498Szrj case STATEMENT_LIST:
471638fd1498Szrj new_ctx = *ctx;
471738fd1498Szrj new_ctx.ctor = new_ctx.object = NULL_TREE;
471838fd1498Szrj return cxx_eval_statement_list (&new_ctx, t,
471938fd1498Szrj non_constant_p, overflow_p, jump_target);
472038fd1498Szrj
472138fd1498Szrj case BIND_EXPR:
472238fd1498Szrj return cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
472338fd1498Szrj lval,
472438fd1498Szrj non_constant_p, overflow_p,
472538fd1498Szrj jump_target);
472638fd1498Szrj
472738fd1498Szrj case PREINCREMENT_EXPR:
472838fd1498Szrj case POSTINCREMENT_EXPR:
472938fd1498Szrj case PREDECREMENT_EXPR:
473038fd1498Szrj case POSTDECREMENT_EXPR:
473138fd1498Szrj return cxx_eval_increment_expression (ctx, t,
473238fd1498Szrj lval, non_constant_p, overflow_p);
473338fd1498Szrj
473438fd1498Szrj case LAMBDA_EXPR:
473538fd1498Szrj case NEW_EXPR:
473638fd1498Szrj case VEC_NEW_EXPR:
473738fd1498Szrj case DELETE_EXPR:
473838fd1498Szrj case VEC_DELETE_EXPR:
473938fd1498Szrj case THROW_EXPR:
474038fd1498Szrj case MODOP_EXPR:
474138fd1498Szrj /* GCC internal stuff. */
474238fd1498Szrj case VA_ARG_EXPR:
474338fd1498Szrj case OBJ_TYPE_REF:
474438fd1498Szrj case NON_DEPENDENT_EXPR:
474538fd1498Szrj case BASELINK:
474638fd1498Szrj case OFFSET_REF:
474738fd1498Szrj if (!ctx->quiet)
474838fd1498Szrj error_at (EXPR_LOC_OR_LOC (t, input_location),
474938fd1498Szrj "expression %qE is not a constant expression", t);
475038fd1498Szrj *non_constant_p = true;
475138fd1498Szrj break;
475238fd1498Szrj
475338fd1498Szrj case PLACEHOLDER_EXPR:
475438fd1498Szrj /* Use of the value or address of the current object. */
475538fd1498Szrj if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t)))
475638fd1498Szrj return cxx_eval_constant_expression (ctx, ctor, lval,
475738fd1498Szrj non_constant_p, overflow_p);
475838fd1498Szrj /* A placeholder without a referent. We can get here when
475938fd1498Szrj checking whether NSDMIs are noexcept, or in massage_init_elt;
476038fd1498Szrj just say it's non-constant for now. */
476138fd1498Szrj gcc_assert (ctx->quiet);
476238fd1498Szrj *non_constant_p = true;
476338fd1498Szrj break;
476438fd1498Szrj
476538fd1498Szrj case EXIT_EXPR:
476638fd1498Szrj {
476738fd1498Szrj tree cond = TREE_OPERAND (t, 0);
476838fd1498Szrj cond = cxx_eval_constant_expression (ctx, cond, /*lval*/false,
476938fd1498Szrj non_constant_p, overflow_p);
477038fd1498Szrj VERIFY_CONSTANT (cond);
477138fd1498Szrj if (integer_nonzerop (cond))
477238fd1498Szrj *jump_target = t;
477338fd1498Szrj }
477438fd1498Szrj break;
477538fd1498Szrj
477638fd1498Szrj case GOTO_EXPR:
477738fd1498Szrj *jump_target = TREE_OPERAND (t, 0);
477838fd1498Szrj gcc_assert (breaks (jump_target) || continues (jump_target)
477938fd1498Szrj /* Allow for jumping to a cdtor_label. */
478038fd1498Szrj || returns (jump_target));
478138fd1498Szrj break;
478238fd1498Szrj
478338fd1498Szrj case LOOP_EXPR:
478438fd1498Szrj cxx_eval_loop_expr (ctx, t,
478538fd1498Szrj non_constant_p, overflow_p, jump_target);
478638fd1498Szrj break;
478738fd1498Szrj
478838fd1498Szrj case SWITCH_EXPR:
478938fd1498Szrj cxx_eval_switch_expr (ctx, t,
479038fd1498Szrj non_constant_p, overflow_p, jump_target);
479138fd1498Szrj break;
479238fd1498Szrj
479338fd1498Szrj case REQUIRES_EXPR:
479438fd1498Szrj /* It's possible to get a requires-expression in a constant
479538fd1498Szrj expression. For example:
479638fd1498Szrj
479738fd1498Szrj template<typename T> concept bool C() {
479838fd1498Szrj return requires (T t) { t; };
479938fd1498Szrj }
480038fd1498Szrj
480138fd1498Szrj template<typename T> requires !C<T>() void f(T);
480238fd1498Szrj
480338fd1498Szrj Normalization leaves f with the associated constraint
480438fd1498Szrj '!requires (T t) { ... }' which is not transformed into
480538fd1498Szrj a constraint. */
480638fd1498Szrj if (!processing_template_decl)
480738fd1498Szrj return evaluate_constraint_expression (t, NULL_TREE);
480838fd1498Szrj else
480938fd1498Szrj *non_constant_p = true;
481038fd1498Szrj return t;
481138fd1498Szrj
481238fd1498Szrj case ANNOTATE_EXPR:
481338fd1498Szrj r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
481438fd1498Szrj lval,
481538fd1498Szrj non_constant_p, overflow_p,
481638fd1498Szrj jump_target);
481738fd1498Szrj break;
481838fd1498Szrj
481938fd1498Szrj case USING_STMT:
482038fd1498Szrj r = void_node;
482138fd1498Szrj break;
482238fd1498Szrj
482338fd1498Szrj default:
482438fd1498Szrj if (STATEMENT_CODE_P (TREE_CODE (t)))
482538fd1498Szrj {
482638fd1498Szrj /* This function doesn't know how to deal with pre-genericize
482738fd1498Szrj statements; this can only happen with statement-expressions,
482838fd1498Szrj so for now just fail. */
482938fd1498Szrj if (!ctx->quiet)
483038fd1498Szrj error_at (EXPR_LOCATION (t),
483138fd1498Szrj "statement is not a constant expression");
483238fd1498Szrj }
483338fd1498Szrj else
483438fd1498Szrj internal_error ("unexpected expression %qE of kind %s", t,
483538fd1498Szrj get_tree_code_name (TREE_CODE (t)));
483638fd1498Szrj *non_constant_p = true;
483738fd1498Szrj break;
483838fd1498Szrj }
483938fd1498Szrj
484038fd1498Szrj if (r == error_mark_node)
484138fd1498Szrj *non_constant_p = true;
484238fd1498Szrj
484338fd1498Szrj if (*non_constant_p)
484438fd1498Szrj return t;
484538fd1498Szrj else
484638fd1498Szrj return r;
484738fd1498Szrj }
484838fd1498Szrj
484938fd1498Szrj static tree
485038fd1498Szrj cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
485138fd1498Szrj bool strict = true, tree object = NULL_TREE)
485238fd1498Szrj {
485338fd1498Szrj auto_timevar time (TV_CONSTEXPR);
485438fd1498Szrj
485538fd1498Szrj bool non_constant_p = false;
485638fd1498Szrj bool overflow_p = false;
485738fd1498Szrj hash_map<tree,tree> map;
485838fd1498Szrj
485938fd1498Szrj constexpr_ctx ctx = { NULL, &map, NULL, NULL, NULL, NULL,
486038fd1498Szrj allow_non_constant, strict };
486138fd1498Szrj
486238fd1498Szrj tree type = initialized_type (t);
486338fd1498Szrj tree r = t;
486438fd1498Szrj if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
486538fd1498Szrj {
486638fd1498Szrj /* In C++14 an NSDMI can participate in aggregate initialization,
486738fd1498Szrj and can refer to the address of the object being initialized, so
486838fd1498Szrj we need to pass in the relevant VAR_DECL if we want to do the
486938fd1498Szrj evaluation in a single pass. The evaluation will dynamically
487038fd1498Szrj update ctx.values for the VAR_DECL. We use the same strategy
487138fd1498Szrj for C++11 constexpr constructors that refer to the object being
487238fd1498Szrj initialized. */
487338fd1498Szrj ctx.ctor = build_constructor (type, NULL);
487438fd1498Szrj CONSTRUCTOR_NO_IMPLICIT_ZERO (ctx.ctor) = true;
487538fd1498Szrj if (!object)
487638fd1498Szrj {
487738fd1498Szrj if (TREE_CODE (t) == TARGET_EXPR)
487838fd1498Szrj object = TARGET_EXPR_SLOT (t);
487938fd1498Szrj else if (TREE_CODE (t) == AGGR_INIT_EXPR)
488038fd1498Szrj object = AGGR_INIT_EXPR_SLOT (t);
488138fd1498Szrj }
488238fd1498Szrj ctx.object = object;
488338fd1498Szrj if (object)
488438fd1498Szrj gcc_assert (same_type_ignoring_top_level_qualifiers_p
488538fd1498Szrj (type, TREE_TYPE (object)));
488638fd1498Szrj if (object && DECL_P (object))
488738fd1498Szrj map.put (object, ctx.ctor);
488838fd1498Szrj if (TREE_CODE (r) == TARGET_EXPR)
488938fd1498Szrj /* Avoid creating another CONSTRUCTOR when we expand the
489038fd1498Szrj TARGET_EXPR. */
489138fd1498Szrj r = TARGET_EXPR_INITIAL (r);
489238fd1498Szrj }
489338fd1498Szrj
489438fd1498Szrj r = cxx_eval_constant_expression (&ctx, r,
489538fd1498Szrj false, &non_constant_p, &overflow_p);
489638fd1498Szrj
489738fd1498Szrj verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
489838fd1498Szrj
489938fd1498Szrj /* Mutable logic is a bit tricky: we want to allow initialization of
490038fd1498Szrj constexpr variables with mutable members, but we can't copy those
490138fd1498Szrj members to another constexpr variable. */
490238fd1498Szrj if (TREE_CODE (r) == CONSTRUCTOR
490338fd1498Szrj && CONSTRUCTOR_MUTABLE_POISON (r))
490438fd1498Szrj {
490538fd1498Szrj if (!allow_non_constant)
490638fd1498Szrj error ("%qE is not a constant expression because it refers to "
490738fd1498Szrj "mutable subobjects of %qT", t, type);
490838fd1498Szrj non_constant_p = true;
490938fd1498Szrj }
491038fd1498Szrj
491138fd1498Szrj if (TREE_CODE (r) == CONSTRUCTOR
491238fd1498Szrj && CONSTRUCTOR_NO_IMPLICIT_ZERO (r))
491338fd1498Szrj {
491438fd1498Szrj if (!allow_non_constant)
491538fd1498Szrj error ("%qE is not a constant expression because it refers to "
491638fd1498Szrj "an incompletely initialized variable", t);
491738fd1498Szrj TREE_CONSTANT (r) = false;
491838fd1498Szrj non_constant_p = true;
491938fd1498Szrj }
492038fd1498Szrj
492138fd1498Szrj /* Technically we should check this for all subexpressions, but that
492238fd1498Szrj runs into problems with our internal representation of pointer
492338fd1498Szrj subtraction and the 5.19 rules are still in flux. */
492438fd1498Szrj if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
492538fd1498Szrj && ARITHMETIC_TYPE_P (TREE_TYPE (r))
492638fd1498Szrj && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
492738fd1498Szrj {
492838fd1498Szrj if (!allow_non_constant)
492938fd1498Szrj error ("conversion from pointer type %qT "
493038fd1498Szrj "to arithmetic type %qT in a constant expression",
493138fd1498Szrj TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
493238fd1498Szrj non_constant_p = true;
493338fd1498Szrj }
493438fd1498Szrj
493538fd1498Szrj if (!non_constant_p && overflow_p)
493638fd1498Szrj non_constant_p = true;
493738fd1498Szrj
493838fd1498Szrj /* Unshare the result unless it's a CONSTRUCTOR in which case it's already
493938fd1498Szrj unshared. */
494038fd1498Szrj bool should_unshare = true;
494138fd1498Szrj if (r == t || TREE_CODE (r) == CONSTRUCTOR)
494238fd1498Szrj should_unshare = false;
494338fd1498Szrj
494438fd1498Szrj if (non_constant_p && !allow_non_constant)
494538fd1498Szrj return error_mark_node;
494638fd1498Szrj else if (non_constant_p && TREE_CONSTANT (r))
494738fd1498Szrj {
494838fd1498Szrj /* This isn't actually constant, so unset TREE_CONSTANT.
494938fd1498Szrj Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
495038fd1498Szrj it to be set if it is invariant address, even when it is not
495138fd1498Szrj a valid C++ constant expression. Wrap it with a NOP_EXPR
495238fd1498Szrj instead. */
495338fd1498Szrj if (EXPR_P (r) && TREE_CODE (r) != ADDR_EXPR)
495438fd1498Szrj r = copy_node (r);
495538fd1498Szrj else if (TREE_CODE (r) == CONSTRUCTOR)
495638fd1498Szrj r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r);
495738fd1498Szrj else
495838fd1498Szrj r = build_nop (TREE_TYPE (r), r);
495938fd1498Szrj TREE_CONSTANT (r) = false;
496038fd1498Szrj }
496138fd1498Szrj else if (non_constant_p || r == t)
496238fd1498Szrj return t;
496338fd1498Szrj
496438fd1498Szrj if (should_unshare)
496538fd1498Szrj r = unshare_expr (r);
496638fd1498Szrj
496738fd1498Szrj if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
496838fd1498Szrj {
496938fd1498Szrj if (TREE_CODE (t) == TARGET_EXPR
497038fd1498Szrj && TARGET_EXPR_INITIAL (t) == r)
497138fd1498Szrj return t;
497238fd1498Szrj else
497338fd1498Szrj {
497438fd1498Szrj r = get_target_expr (r);
497538fd1498Szrj TREE_CONSTANT (r) = true;
497638fd1498Szrj return r;
497738fd1498Szrj }
497838fd1498Szrj }
497938fd1498Szrj else
498038fd1498Szrj return r;
498138fd1498Szrj }
498238fd1498Szrj
498338fd1498Szrj /* Returns true if T is a valid subexpression of a constant expression,
498438fd1498Szrj even if it isn't itself a constant expression. */
498538fd1498Szrj
498638fd1498Szrj bool
is_sub_constant_expr(tree t)498738fd1498Szrj is_sub_constant_expr (tree t)
498838fd1498Szrj {
498938fd1498Szrj bool non_constant_p = false;
499038fd1498Szrj bool overflow_p = false;
499138fd1498Szrj hash_map <tree, tree> map;
499238fd1498Szrj
499338fd1498Szrj constexpr_ctx ctx = { NULL, &map, NULL, NULL, NULL, NULL, true, true };
499438fd1498Szrj
499538fd1498Szrj cxx_eval_constant_expression (&ctx, t, false, &non_constant_p,
499638fd1498Szrj &overflow_p);
499738fd1498Szrj return !non_constant_p && !overflow_p;
499838fd1498Szrj }
499938fd1498Szrj
500038fd1498Szrj /* If T represents a constant expression returns its reduced value.
500138fd1498Szrj Otherwise return error_mark_node. If T is dependent, then
500238fd1498Szrj return NULL. */
500338fd1498Szrj
500438fd1498Szrj tree
cxx_constant_value(tree t,tree decl)500538fd1498Szrj cxx_constant_value (tree t, tree decl)
500638fd1498Szrj {
500738fd1498Szrj return cxx_eval_outermost_constant_expr (t, false, true, decl);
500838fd1498Szrj }
500938fd1498Szrj
501038fd1498Szrj /* Helper routine for fold_simple function. Either return simplified
501138fd1498Szrj expression T, otherwise NULL_TREE.
501238fd1498Szrj In contrast to cp_fully_fold, and to maybe_constant_value, we try to fold
501338fd1498Szrj even if we are within template-declaration. So be careful on call, as in
501438fd1498Szrj such case types can be undefined. */
501538fd1498Szrj
501638fd1498Szrj static tree
fold_simple_1(tree t)501738fd1498Szrj fold_simple_1 (tree t)
501838fd1498Szrj {
501938fd1498Szrj tree op1;
502038fd1498Szrj enum tree_code code = TREE_CODE (t);
502138fd1498Szrj
502238fd1498Szrj switch (code)
502338fd1498Szrj {
502438fd1498Szrj case INTEGER_CST:
502538fd1498Szrj case REAL_CST:
502638fd1498Szrj case VECTOR_CST:
502738fd1498Szrj case FIXED_CST:
502838fd1498Szrj case COMPLEX_CST:
502938fd1498Szrj return t;
503038fd1498Szrj
503138fd1498Szrj case SIZEOF_EXPR:
503238fd1498Szrj return fold_sizeof_expr (t);
503338fd1498Szrj
503438fd1498Szrj case ABS_EXPR:
503538fd1498Szrj case CONJ_EXPR:
503638fd1498Szrj case REALPART_EXPR:
503738fd1498Szrj case IMAGPART_EXPR:
503838fd1498Szrj case NEGATE_EXPR:
503938fd1498Szrj case BIT_NOT_EXPR:
504038fd1498Szrj case TRUTH_NOT_EXPR:
504138fd1498Szrj case NOP_EXPR:
504238fd1498Szrj case VIEW_CONVERT_EXPR:
504338fd1498Szrj case CONVERT_EXPR:
504438fd1498Szrj case FLOAT_EXPR:
504538fd1498Szrj case FIX_TRUNC_EXPR:
504638fd1498Szrj case FIXED_CONVERT_EXPR:
504738fd1498Szrj case ADDR_SPACE_CONVERT_EXPR:
504838fd1498Szrj
504938fd1498Szrj op1 = TREE_OPERAND (t, 0);
505038fd1498Szrj
505138fd1498Szrj t = const_unop (code, TREE_TYPE (t), op1);
505238fd1498Szrj if (!t)
505338fd1498Szrj return NULL_TREE;
505438fd1498Szrj
505538fd1498Szrj if (CONVERT_EXPR_CODE_P (code)
505638fd1498Szrj && TREE_OVERFLOW_P (t) && !TREE_OVERFLOW_P (op1))
505738fd1498Szrj TREE_OVERFLOW (t) = false;
505838fd1498Szrj return t;
505938fd1498Szrj
506038fd1498Szrj default:
506138fd1498Szrj return NULL_TREE;
506238fd1498Szrj }
506338fd1498Szrj }
506438fd1498Szrj
506538fd1498Szrj /* If T is a simple constant expression, returns its simplified value.
506638fd1498Szrj Otherwise returns T. In contrast to maybe_constant_value we
506738fd1498Szrj simplify only few operations on constant-expressions, and we don't
506838fd1498Szrj try to simplify constexpressions. */
506938fd1498Szrj
507038fd1498Szrj tree
fold_simple(tree t)507138fd1498Szrj fold_simple (tree t)
507238fd1498Szrj {
507338fd1498Szrj if (processing_template_decl)
507438fd1498Szrj return t;
507538fd1498Szrj
507638fd1498Szrj tree r = fold_simple_1 (t);
507738fd1498Szrj if (r)
507838fd1498Szrj return r;
507938fd1498Szrj
508038fd1498Szrj return t;
508138fd1498Szrj }
508238fd1498Szrj
508338fd1498Szrj /* If T is a constant expression, returns its reduced value.
508438fd1498Szrj Otherwise, if T does not have TREE_CONSTANT set, returns T.
508538fd1498Szrj Otherwise, returns a version of T without TREE_CONSTANT. */
508638fd1498Szrj
508738fd1498Szrj static GTY((deletable)) hash_map<tree, tree> *cv_cache;
508838fd1498Szrj
508938fd1498Szrj tree
maybe_constant_value(tree t,tree decl)509038fd1498Szrj maybe_constant_value (tree t, tree decl)
509138fd1498Szrj {
509238fd1498Szrj tree r;
509338fd1498Szrj
509438fd1498Szrj if (!is_nondependent_constant_expression (t))
509538fd1498Szrj {
509638fd1498Szrj if (TREE_OVERFLOW_P (t))
509738fd1498Szrj {
509838fd1498Szrj t = build_nop (TREE_TYPE (t), t);
509938fd1498Szrj TREE_CONSTANT (t) = false;
510038fd1498Szrj }
510138fd1498Szrj return t;
510238fd1498Szrj }
510338fd1498Szrj else if (CONSTANT_CLASS_P (t))
510438fd1498Szrj /* No caching or evaluation needed. */
510538fd1498Szrj return t;
510638fd1498Szrj
510738fd1498Szrj if (cv_cache == NULL)
510838fd1498Szrj cv_cache = hash_map<tree, tree>::create_ggc (101);
510938fd1498Szrj if (tree *cached = cv_cache->get (t))
511038fd1498Szrj return *cached;
511138fd1498Szrj
511238fd1498Szrj r = cxx_eval_outermost_constant_expr (t, true, true, decl);
511338fd1498Szrj gcc_checking_assert (r == t
511438fd1498Szrj || CONVERT_EXPR_P (t)
511538fd1498Szrj || TREE_CODE (t) == VIEW_CONVERT_EXPR
511638fd1498Szrj || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
511738fd1498Szrj || !cp_tree_equal (r, t));
511838fd1498Szrj cv_cache->put (t, r);
511938fd1498Szrj return r;
512038fd1498Szrj }
512138fd1498Szrj
512238fd1498Szrj /* Dispose of the whole CV_CACHE. */
512338fd1498Szrj
512438fd1498Szrj static void
clear_cv_cache(void)512538fd1498Szrj clear_cv_cache (void)
512638fd1498Szrj {
512738fd1498Szrj if (cv_cache != NULL)
512838fd1498Szrj cv_cache->empty ();
512938fd1498Szrj }
513038fd1498Szrj
513138fd1498Szrj /* Dispose of the whole CV_CACHE and FOLD_CACHE. */
513238fd1498Szrj
513338fd1498Szrj void
clear_cv_and_fold_caches(void)513438fd1498Szrj clear_cv_and_fold_caches (void)
513538fd1498Szrj {
513638fd1498Szrj clear_cv_cache ();
513738fd1498Szrj clear_fold_cache ();
513838fd1498Szrj }
513938fd1498Szrj
514038fd1498Szrj /* Like maybe_constant_value but first fully instantiate the argument.
514138fd1498Szrj
514238fd1498Szrj Note: this is equivalent to instantiate_non_dependent_expr_sfinae
5143*58e805e6Szrj (t, complain) followed by maybe_constant_value but is more efficient,
514438fd1498Szrj because calls instantiation_dependent_expression_p and
514538fd1498Szrj potential_constant_expression at most once. */
514638fd1498Szrj
514738fd1498Szrj tree
fold_non_dependent_expr(tree t,tsubst_flags_t complain)5148*58e805e6Szrj fold_non_dependent_expr (tree t, tsubst_flags_t complain /* = tf_none */)
514938fd1498Szrj {
515038fd1498Szrj if (t == NULL_TREE)
515138fd1498Szrj return NULL_TREE;
515238fd1498Szrj
515338fd1498Szrj /* If we're in a template, but T isn't value dependent, simplify
515438fd1498Szrj it. We're supposed to treat:
515538fd1498Szrj
515638fd1498Szrj template <typename T> void f(T[1 + 1]);
515738fd1498Szrj template <typename T> void f(T[2]);
515838fd1498Szrj
515938fd1498Szrj as two declarations of the same function, for example. */
516038fd1498Szrj if (processing_template_decl)
516138fd1498Szrj {
516238fd1498Szrj if (is_nondependent_constant_expression (t))
516338fd1498Szrj {
516438fd1498Szrj processing_template_decl_sentinel s;
5165*58e805e6Szrj t = instantiate_non_dependent_expr_internal (t, complain);
516638fd1498Szrj
516738fd1498Szrj if (type_unknown_p (t)
516838fd1498Szrj || BRACE_ENCLOSED_INITIALIZER_P (t))
516938fd1498Szrj {
517038fd1498Szrj if (TREE_OVERFLOW_P (t))
517138fd1498Szrj {
517238fd1498Szrj t = build_nop (TREE_TYPE (t), t);
517338fd1498Szrj TREE_CONSTANT (t) = false;
517438fd1498Szrj }
517538fd1498Szrj return t;
517638fd1498Szrj }
517738fd1498Szrj
517838fd1498Szrj tree r = cxx_eval_outermost_constant_expr (t, true, true, NULL_TREE);
517938fd1498Szrj /* cp_tree_equal looks through NOPs, so allow them. */
518038fd1498Szrj gcc_checking_assert (r == t
518138fd1498Szrj || CONVERT_EXPR_P (t)
518238fd1498Szrj || TREE_CODE (t) == VIEW_CONVERT_EXPR
518338fd1498Szrj || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
518438fd1498Szrj || !cp_tree_equal (r, t));
518538fd1498Szrj return r;
518638fd1498Szrj }
518738fd1498Szrj else if (TREE_OVERFLOW_P (t))
518838fd1498Szrj {
518938fd1498Szrj t = build_nop (TREE_TYPE (t), t);
519038fd1498Szrj TREE_CONSTANT (t) = false;
519138fd1498Szrj }
519238fd1498Szrj return t;
519338fd1498Szrj }
519438fd1498Szrj
519538fd1498Szrj return maybe_constant_value (t);
519638fd1498Szrj }
519738fd1498Szrj
519838fd1498Szrj /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
519938fd1498Szrj than wrapped in a TARGET_EXPR. */
520038fd1498Szrj
520138fd1498Szrj static tree
maybe_constant_init_1(tree t,tree decl,bool allow_non_constant)520238fd1498Szrj maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant)
520338fd1498Szrj {
520438fd1498Szrj if (!t)
520538fd1498Szrj return t;
520638fd1498Szrj if (TREE_CODE (t) == EXPR_STMT)
520738fd1498Szrj t = TREE_OPERAND (t, 0);
520838fd1498Szrj if (TREE_CODE (t) == CONVERT_EXPR
520938fd1498Szrj && VOID_TYPE_P (TREE_TYPE (t)))
521038fd1498Szrj t = TREE_OPERAND (t, 0);
521138fd1498Szrj if (TREE_CODE (t) == INIT_EXPR)
521238fd1498Szrj t = TREE_OPERAND (t, 1);
521338fd1498Szrj if (TREE_CODE (t) == TARGET_EXPR)
521438fd1498Szrj t = TARGET_EXPR_INITIAL (t);
521538fd1498Szrj if (!is_nondependent_static_init_expression (t))
521638fd1498Szrj /* Don't try to evaluate it. */;
521738fd1498Szrj else if (CONSTANT_CLASS_P (t) && allow_non_constant)
521838fd1498Szrj /* No evaluation needed. */;
521938fd1498Szrj else
522038fd1498Szrj t = cxx_eval_outermost_constant_expr (t, allow_non_constant, false, decl);
522138fd1498Szrj if (TREE_CODE (t) == TARGET_EXPR)
522238fd1498Szrj {
522338fd1498Szrj tree init = TARGET_EXPR_INITIAL (t);
522438fd1498Szrj if (TREE_CODE (init) == CONSTRUCTOR)
522538fd1498Szrj t = init;
522638fd1498Szrj }
522738fd1498Szrj return t;
522838fd1498Szrj }
522938fd1498Szrj
523038fd1498Szrj /* Wrapper for maybe_constant_init_1 which permits non constants. */
523138fd1498Szrj
523238fd1498Szrj tree
maybe_constant_init(tree t,tree decl)523338fd1498Szrj maybe_constant_init (tree t, tree decl)
523438fd1498Szrj {
523538fd1498Szrj return maybe_constant_init_1 (t, decl, true);
523638fd1498Szrj }
523738fd1498Szrj
523838fd1498Szrj /* Wrapper for maybe_constant_init_1 which does not permit non constants. */
523938fd1498Szrj
524038fd1498Szrj tree
cxx_constant_init(tree t,tree decl)524138fd1498Szrj cxx_constant_init (tree t, tree decl)
524238fd1498Szrj {
524338fd1498Szrj return maybe_constant_init_1 (t, decl, false);
524438fd1498Szrj }
524538fd1498Szrj
524638fd1498Szrj #if 0
524738fd1498Szrj /* FIXME see ADDR_EXPR section in potential_constant_expression_1. */
524838fd1498Szrj /* Return true if the object referred to by REF has automatic or thread
524938fd1498Szrj local storage. */
525038fd1498Szrj
525138fd1498Szrj enum { ck_ok, ck_bad, ck_unknown };
525238fd1498Szrj static int
525338fd1498Szrj check_automatic_or_tls (tree ref)
525438fd1498Szrj {
525538fd1498Szrj machine_mode mode;
525638fd1498Szrj poly_int64 bitsize, bitpos;
525738fd1498Szrj tree offset;
525838fd1498Szrj int volatilep = 0, unsignedp = 0;
525938fd1498Szrj tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
526038fd1498Szrj &mode, &unsignedp, &volatilep, false);
526138fd1498Szrj duration_kind dk;
526238fd1498Szrj
526338fd1498Szrj /* If there isn't a decl in the middle, we don't know the linkage here,
526438fd1498Szrj and this isn't a constant expression anyway. */
526538fd1498Szrj if (!DECL_P (decl))
526638fd1498Szrj return ck_unknown;
526738fd1498Szrj dk = decl_storage_duration (decl);
526838fd1498Szrj return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
526938fd1498Szrj }
527038fd1498Szrj #endif
527138fd1498Szrj
527238fd1498Szrj /* Return true if T denotes a potentially constant expression. Issue
527338fd1498Szrj diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true,
527438fd1498Szrj an lvalue-rvalue conversion is implied. If NOW is true, we want to
527538fd1498Szrj consider the expression in the current context, independent of constexpr
527638fd1498Szrj substitution.
527738fd1498Szrj
527838fd1498Szrj C++0x [expr.const] used to say
527938fd1498Szrj
528038fd1498Szrj 6 An expression is a potential constant expression if it is
528138fd1498Szrj a constant expression where all occurrences of function
528238fd1498Szrj parameters are replaced by arbitrary constant expressions
528338fd1498Szrj of the appropriate type.
528438fd1498Szrj
528538fd1498Szrj 2 A conditional expression is a constant expression unless it
528638fd1498Szrj involves one of the following as a potentially evaluated
528738fd1498Szrj subexpression (3.2), but subexpressions of logical AND (5.14),
528838fd1498Szrj logical OR (5.15), and conditional (5.16) operations that are
528938fd1498Szrj not evaluated are not considered. */
529038fd1498Szrj
529138fd1498Szrj static bool
potential_constant_expression_1(tree t,bool want_rval,bool strict,bool now,tsubst_flags_t flags)529238fd1498Szrj potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
529338fd1498Szrj tsubst_flags_t flags)
529438fd1498Szrj {
529538fd1498Szrj #define RECUR(T,RV) \
529638fd1498Szrj potential_constant_expression_1 ((T), (RV), strict, now, flags)
529738fd1498Szrj
529838fd1498Szrj enum { any = false, rval = true };
529938fd1498Szrj int i;
530038fd1498Szrj tree tmp;
530138fd1498Szrj
530238fd1498Szrj if (t == error_mark_node)
530338fd1498Szrj return false;
530438fd1498Szrj if (t == NULL_TREE)
530538fd1498Szrj return true;
530638fd1498Szrj location_t loc = EXPR_LOC_OR_LOC (t, input_location);
530738fd1498Szrj if (TREE_THIS_VOLATILE (t) && !DECL_P (t))
530838fd1498Szrj {
530938fd1498Szrj if (flags & tf_error)
531038fd1498Szrj error_at (loc, "expression %qE has side-effects", t);
531138fd1498Szrj return false;
531238fd1498Szrj }
531338fd1498Szrj if (CONSTANT_CLASS_P (t))
531438fd1498Szrj return true;
531538fd1498Szrj if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)
531638fd1498Szrj && TREE_TYPE (t) == error_mark_node)
531738fd1498Szrj return false;
531838fd1498Szrj
531938fd1498Szrj switch (TREE_CODE (t))
532038fd1498Szrj {
532138fd1498Szrj case FUNCTION_DECL:
532238fd1498Szrj case BASELINK:
532338fd1498Szrj case TEMPLATE_DECL:
532438fd1498Szrj case OVERLOAD:
532538fd1498Szrj case TEMPLATE_ID_EXPR:
532638fd1498Szrj case LABEL_DECL:
532738fd1498Szrj case LABEL_EXPR:
532838fd1498Szrj case CASE_LABEL_EXPR:
532938fd1498Szrj case CONST_DECL:
533038fd1498Szrj case SIZEOF_EXPR:
533138fd1498Szrj case ALIGNOF_EXPR:
533238fd1498Szrj case OFFSETOF_EXPR:
533338fd1498Szrj case NOEXCEPT_EXPR:
533438fd1498Szrj case TEMPLATE_PARM_INDEX:
533538fd1498Szrj case TRAIT_EXPR:
533638fd1498Szrj case IDENTIFIER_NODE:
533738fd1498Szrj case USERDEF_LITERAL:
533838fd1498Szrj /* We can see a FIELD_DECL in a pointer-to-member expression. */
533938fd1498Szrj case FIELD_DECL:
534038fd1498Szrj case RESULT_DECL:
534138fd1498Szrj case USING_DECL:
534238fd1498Szrj case USING_STMT:
534338fd1498Szrj case PLACEHOLDER_EXPR:
534438fd1498Szrj case BREAK_STMT:
534538fd1498Szrj case CONTINUE_STMT:
534638fd1498Szrj case REQUIRES_EXPR:
534738fd1498Szrj case STATIC_ASSERT:
534838fd1498Szrj case DEBUG_BEGIN_STMT:
534938fd1498Szrj return true;
535038fd1498Szrj
535138fd1498Szrj case PARM_DECL:
535238fd1498Szrj if (now)
535338fd1498Szrj {
535438fd1498Szrj if (flags & tf_error)
535538fd1498Szrj error ("%qE is not a constant expression", t);
535638fd1498Szrj return false;
535738fd1498Szrj }
535838fd1498Szrj return true;
535938fd1498Szrj
536038fd1498Szrj case AGGR_INIT_EXPR:
536138fd1498Szrj case CALL_EXPR:
536238fd1498Szrj /* -- an invocation of a function other than a constexpr function
536338fd1498Szrj or a constexpr constructor. */
536438fd1498Szrj {
536538fd1498Szrj tree fun = get_function_named_in_call (t);
536638fd1498Szrj const int nargs = call_expr_nargs (t);
536738fd1498Szrj i = 0;
536838fd1498Szrj
536938fd1498Szrj if (fun == NULL_TREE)
537038fd1498Szrj {
537138fd1498Szrj /* Reset to allow the function to continue past the end
537238fd1498Szrj of the block below. Otherwise return early. */
537338fd1498Szrj bool bail = true;
537438fd1498Szrj
537538fd1498Szrj if (TREE_CODE (t) == CALL_EXPR
537638fd1498Szrj && CALL_EXPR_FN (t) == NULL_TREE)
537738fd1498Szrj switch (CALL_EXPR_IFN (t))
537838fd1498Szrj {
537938fd1498Szrj /* These should be ignored, they are optimized away from
538038fd1498Szrj constexpr functions. */
538138fd1498Szrj case IFN_UBSAN_NULL:
538238fd1498Szrj case IFN_UBSAN_BOUNDS:
538338fd1498Szrj case IFN_UBSAN_VPTR:
538438fd1498Szrj case IFN_FALLTHROUGH:
538538fd1498Szrj return true;
538638fd1498Szrj
538738fd1498Szrj case IFN_ADD_OVERFLOW:
538838fd1498Szrj case IFN_SUB_OVERFLOW:
538938fd1498Szrj case IFN_MUL_OVERFLOW:
539038fd1498Szrj case IFN_LAUNDER:
539138fd1498Szrj bail = false;
539238fd1498Szrj
539338fd1498Szrj default:
539438fd1498Szrj break;
539538fd1498Szrj }
539638fd1498Szrj
539738fd1498Szrj if (bail)
539838fd1498Szrj {
539938fd1498Szrj /* fold_call_expr can't do anything with IFN calls. */
540038fd1498Szrj if (flags & tf_error)
540138fd1498Szrj error_at (loc, "call to internal function %qE", t);
540238fd1498Szrj return false;
540338fd1498Szrj }
540438fd1498Szrj }
540538fd1498Szrj
540638fd1498Szrj if (fun && is_overloaded_fn (fun))
540738fd1498Szrj {
540838fd1498Szrj if (TREE_CODE (fun) == FUNCTION_DECL)
540938fd1498Szrj {
541038fd1498Szrj if (builtin_valid_in_constant_expr_p (fun))
541138fd1498Szrj return true;
541238fd1498Szrj if (!DECL_DECLARED_CONSTEXPR_P (fun)
541338fd1498Szrj /* Allow any built-in function; if the expansion
541438fd1498Szrj isn't constant, we'll deal with that then. */
541538fd1498Szrj && !is_builtin_fn (fun))
541638fd1498Szrj {
541738fd1498Szrj if (flags & tf_error)
541838fd1498Szrj {
541938fd1498Szrj error_at (loc, "call to non-%<constexpr%> function %qD",
542038fd1498Szrj fun);
542138fd1498Szrj explain_invalid_constexpr_fn (fun);
542238fd1498Szrj }
542338fd1498Szrj return false;
542438fd1498Szrj }
542538fd1498Szrj /* A call to a non-static member function takes the address
542638fd1498Szrj of the object as the first argument. But in a constant
542738fd1498Szrj expression the address will be folded away, so look
542838fd1498Szrj through it now. */
542938fd1498Szrj if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
543038fd1498Szrj && !DECL_CONSTRUCTOR_P (fun))
543138fd1498Szrj {
543238fd1498Szrj tree x = get_nth_callarg (t, 0);
543338fd1498Szrj if (is_this_parameter (x))
543438fd1498Szrj return true;
543538fd1498Szrj /* Don't require an immediately constant value, as
543638fd1498Szrj constexpr substitution might not use the value. */
543738fd1498Szrj bool sub_now = false;
543838fd1498Szrj if (!potential_constant_expression_1 (x, rval, strict,
543938fd1498Szrj sub_now, flags))
544038fd1498Szrj return false;
544138fd1498Szrj i = 1;
544238fd1498Szrj }
544338fd1498Szrj }
544438fd1498Szrj else
544538fd1498Szrj {
544638fd1498Szrj if (!RECUR (fun, true))
544738fd1498Szrj return false;
544838fd1498Szrj fun = get_first_fn (fun);
544938fd1498Szrj }
545038fd1498Szrj /* Skip initial arguments to base constructors. */
545138fd1498Szrj if (DECL_BASE_CONSTRUCTOR_P (fun))
545238fd1498Szrj i = num_artificial_parms_for (fun);
545338fd1498Szrj fun = DECL_ORIGIN (fun);
545438fd1498Szrj }
545538fd1498Szrj else if (fun)
545638fd1498Szrj {
545738fd1498Szrj if (RECUR (fun, rval))
545838fd1498Szrj /* Might end up being a constant function pointer. */;
545938fd1498Szrj else
546038fd1498Szrj return false;
546138fd1498Szrj }
546238fd1498Szrj for (; i < nargs; ++i)
546338fd1498Szrj {
546438fd1498Szrj tree x = get_nth_callarg (t, i);
546538fd1498Szrj /* In a template, reference arguments haven't been converted to
546638fd1498Szrj REFERENCE_TYPE and we might not even know if the parameter
546738fd1498Szrj is a reference, so accept lvalue constants too. */
546838fd1498Szrj bool rv = processing_template_decl ? any : rval;
546938fd1498Szrj /* Don't require an immediately constant value, as constexpr
547038fd1498Szrj substitution might not use the value of the argument. */
547138fd1498Szrj bool sub_now = false;
547238fd1498Szrj if (!potential_constant_expression_1 (x, rv, strict,
547338fd1498Szrj sub_now, flags))
547438fd1498Szrj return false;
547538fd1498Szrj }
547638fd1498Szrj return true;
547738fd1498Szrj }
547838fd1498Szrj
547938fd1498Szrj case NON_LVALUE_EXPR:
548038fd1498Szrj /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
548138fd1498Szrj -- an lvalue of integral type that refers to a non-volatile
548238fd1498Szrj const variable or static data member initialized with
548338fd1498Szrj constant expressions, or
548438fd1498Szrj
548538fd1498Szrj -- an lvalue of literal type that refers to non-volatile
548638fd1498Szrj object defined with constexpr, or that refers to a
548738fd1498Szrj sub-object of such an object; */
548838fd1498Szrj return RECUR (TREE_OPERAND (t, 0), rval);
548938fd1498Szrj
549038fd1498Szrj case VAR_DECL:
549138fd1498Szrj if (DECL_HAS_VALUE_EXPR_P (t))
549238fd1498Szrj {
549338fd1498Szrj if (now && is_normal_capture_proxy (t))
549438fd1498Szrj {
549538fd1498Szrj /* -- in a lambda-expression, a reference to this or to a
549638fd1498Szrj variable with automatic storage duration defined outside that
549738fd1498Szrj lambda-expression, where the reference would be an
549838fd1498Szrj odr-use. */
549938fd1498Szrj if (flags & tf_error)
550038fd1498Szrj {
550138fd1498Szrj tree cap = DECL_CAPTURED_VARIABLE (t);
550238fd1498Szrj error ("lambda capture of %qE is not a constant expression",
550338fd1498Szrj cap);
550438fd1498Szrj if (!want_rval && decl_constant_var_p (cap))
550538fd1498Szrj inform (input_location, "because it is used as a glvalue");
550638fd1498Szrj }
550738fd1498Szrj return false;
550838fd1498Szrj }
550938fd1498Szrj return RECUR (DECL_VALUE_EXPR (t), rval);
551038fd1498Szrj }
551138fd1498Szrj if (want_rval
551238fd1498Szrj && !var_in_maybe_constexpr_fn (t)
551338fd1498Szrj && !type_dependent_expression_p (t)
551438fd1498Szrj && !decl_maybe_constant_var_p (t)
551538fd1498Szrj && (strict
551638fd1498Szrj || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
551738fd1498Szrj || (DECL_INITIAL (t)
551838fd1498Szrj && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t)))
551938fd1498Szrj && COMPLETE_TYPE_P (TREE_TYPE (t))
552038fd1498Szrj && !is_really_empty_class (TREE_TYPE (t)))
552138fd1498Szrj {
552238fd1498Szrj if (flags & tf_error)
552338fd1498Szrj non_const_var_error (t);
552438fd1498Szrj return false;
552538fd1498Szrj }
552638fd1498Szrj return true;
552738fd1498Szrj
552838fd1498Szrj case NOP_EXPR:
552938fd1498Szrj case CONVERT_EXPR:
553038fd1498Szrj case VIEW_CONVERT_EXPR:
553138fd1498Szrj /* -- a reinterpret_cast. FIXME not implemented, and this rule
553238fd1498Szrj may change to something more specific to type-punning (DR 1312). */
553338fd1498Szrj {
553438fd1498Szrj tree from = TREE_OPERAND (t, 0);
553538fd1498Szrj if (POINTER_TYPE_P (TREE_TYPE (t))
553638fd1498Szrj && TREE_CODE (from) == INTEGER_CST
553738fd1498Szrj && !integer_zerop (from))
553838fd1498Szrj {
553938fd1498Szrj if (flags & tf_error)
554038fd1498Szrj error_at (loc, "reinterpret_cast from integer to pointer");
554138fd1498Szrj return false;
554238fd1498Szrj }
554338fd1498Szrj return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR));
554438fd1498Szrj }
554538fd1498Szrj
554638fd1498Szrj case ADDRESSOF_EXPR:
554738fd1498Szrj /* This is like ADDR_EXPR, except it won't form pointer-to-member. */
554838fd1498Szrj t = TREE_OPERAND (t, 0);
554938fd1498Szrj goto handle_addr_expr;
555038fd1498Szrj
555138fd1498Szrj case ADDR_EXPR:
555238fd1498Szrj /* -- a unary operator & that is applied to an lvalue that
555338fd1498Szrj designates an object with thread or automatic storage
555438fd1498Szrj duration; */
555538fd1498Szrj t = TREE_OPERAND (t, 0);
555638fd1498Szrj
555738fd1498Szrj if (TREE_CODE (t) == OFFSET_REF && PTRMEM_OK_P (t))
555838fd1498Szrj /* A pointer-to-member constant. */
555938fd1498Szrj return true;
556038fd1498Szrj
556138fd1498Szrj handle_addr_expr:
556238fd1498Szrj #if 0
556338fd1498Szrj /* FIXME adjust when issue 1197 is fully resolved. For now don't do
556438fd1498Szrj any checking here, as we might dereference the pointer later. If
556538fd1498Szrj we remove this code, also remove check_automatic_or_tls. */
556638fd1498Szrj i = check_automatic_or_tls (t);
556738fd1498Szrj if (i == ck_ok)
556838fd1498Szrj return true;
556938fd1498Szrj if (i == ck_bad)
557038fd1498Szrj {
557138fd1498Szrj if (flags & tf_error)
557238fd1498Szrj error ("address-of an object %qE with thread local or "
557338fd1498Szrj "automatic storage is not a constant expression", t);
557438fd1498Szrj return false;
557538fd1498Szrj }
557638fd1498Szrj #endif
557738fd1498Szrj return RECUR (t, any);
557838fd1498Szrj
557938fd1498Szrj case REALPART_EXPR:
558038fd1498Szrj case IMAGPART_EXPR:
558138fd1498Szrj case COMPONENT_REF:
558238fd1498Szrj case BIT_FIELD_REF:
558338fd1498Szrj case ARROW_EXPR:
558438fd1498Szrj case OFFSET_REF:
558538fd1498Szrj /* -- a class member access unless its postfix-expression is
558638fd1498Szrj of literal type or of pointer to literal type. */
558738fd1498Szrj /* This test would be redundant, as it follows from the
558838fd1498Szrj postfix-expression being a potential constant expression. */
558938fd1498Szrj if (type_unknown_p (t))
559038fd1498Szrj return true;
559138fd1498Szrj return RECUR (TREE_OPERAND (t, 0), want_rval);
559238fd1498Szrj
559338fd1498Szrj case EXPR_PACK_EXPANSION:
559438fd1498Szrj return RECUR (PACK_EXPANSION_PATTERN (t), want_rval);
559538fd1498Szrj
559638fd1498Szrj case INDIRECT_REF:
559738fd1498Szrj {
559838fd1498Szrj tree x = TREE_OPERAND (t, 0);
559938fd1498Szrj STRIP_NOPS (x);
560038fd1498Szrj if (is_this_parameter (x) && !is_capture_proxy (x))
560138fd1498Szrj {
560238fd1498Szrj if (!var_in_maybe_constexpr_fn (x))
560338fd1498Szrj {
560438fd1498Szrj if (flags & tf_error)
560538fd1498Szrj error_at (loc, "use of %<this%> in a constant expression");
560638fd1498Szrj return false;
560738fd1498Szrj }
560838fd1498Szrj return true;
560938fd1498Szrj }
561038fd1498Szrj return RECUR (x, rval);
561138fd1498Szrj }
561238fd1498Szrj
561338fd1498Szrj case STATEMENT_LIST:
561438fd1498Szrj {
561538fd1498Szrj tree_stmt_iterator i;
561638fd1498Szrj for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
561738fd1498Szrj {
561838fd1498Szrj if (!RECUR (tsi_stmt (i), any))
561938fd1498Szrj return false;
562038fd1498Szrj }
562138fd1498Szrj return true;
562238fd1498Szrj }
562338fd1498Szrj break;
562438fd1498Szrj
562538fd1498Szrj case MODIFY_EXPR:
562638fd1498Szrj if (cxx_dialect < cxx14)
562738fd1498Szrj goto fail;
562838fd1498Szrj if (!RECUR (TREE_OPERAND (t, 0), any))
562938fd1498Szrj return false;
563038fd1498Szrj if (!RECUR (TREE_OPERAND (t, 1), rval))
563138fd1498Szrj return false;
563238fd1498Szrj return true;
563338fd1498Szrj
563438fd1498Szrj case MODOP_EXPR:
563538fd1498Szrj if (cxx_dialect < cxx14)
563638fd1498Szrj goto fail;
563738fd1498Szrj if (!RECUR (TREE_OPERAND (t, 0), rval))
563838fd1498Szrj return false;
563938fd1498Szrj if (!RECUR (TREE_OPERAND (t, 2), rval))
564038fd1498Szrj return false;
564138fd1498Szrj return true;
564238fd1498Szrj
564338fd1498Szrj case DO_STMT:
564438fd1498Szrj if (!RECUR (DO_COND (t), rval))
564538fd1498Szrj return false;
564638fd1498Szrj if (!RECUR (DO_BODY (t), any))
564738fd1498Szrj return false;
564838fd1498Szrj return true;
564938fd1498Szrj
565038fd1498Szrj case FOR_STMT:
565138fd1498Szrj if (!RECUR (FOR_INIT_STMT (t), any))
565238fd1498Szrj return false;
565338fd1498Szrj if (!RECUR (FOR_COND (t), rval))
565438fd1498Szrj return false;
565538fd1498Szrj if (!RECUR (FOR_EXPR (t), any))
565638fd1498Szrj return false;
565738fd1498Szrj if (!RECUR (FOR_BODY (t), any))
565838fd1498Szrj return false;
565938fd1498Szrj return true;
566038fd1498Szrj
566138fd1498Szrj case RANGE_FOR_STMT:
566238fd1498Szrj if (!RECUR (RANGE_FOR_EXPR (t), any))
566338fd1498Szrj return false;
566438fd1498Szrj if (!RECUR (RANGE_FOR_BODY (t), any))
566538fd1498Szrj return false;
566638fd1498Szrj return true;
566738fd1498Szrj
566838fd1498Szrj case WHILE_STMT:
566938fd1498Szrj if (!RECUR (WHILE_COND (t), rval))
567038fd1498Szrj return false;
567138fd1498Szrj if (!RECUR (WHILE_BODY (t), any))
567238fd1498Szrj return false;
567338fd1498Szrj return true;
567438fd1498Szrj
567538fd1498Szrj case SWITCH_STMT:
567638fd1498Szrj if (!RECUR (SWITCH_STMT_COND (t), rval))
567738fd1498Szrj return false;
567838fd1498Szrj /* FIXME we don't check SWITCH_STMT_BODY currently, because even
567938fd1498Szrj unreachable labels would be checked. */
568038fd1498Szrj return true;
568138fd1498Szrj
568238fd1498Szrj case STMT_EXPR:
568338fd1498Szrj return RECUR (STMT_EXPR_STMT (t), rval);
568438fd1498Szrj
568538fd1498Szrj case LAMBDA_EXPR:
568638fd1498Szrj if (cxx_dialect >= cxx17)
568738fd1498Szrj /* In C++17 lambdas can be constexpr, don't give up yet. */
568838fd1498Szrj return true;
568938fd1498Szrj else if (flags & tf_error)
569038fd1498Szrj error_at (loc, "lambda-expression is not a constant expression "
569138fd1498Szrj "before C++17");
569238fd1498Szrj return false;
569338fd1498Szrj
569438fd1498Szrj case DYNAMIC_CAST_EXPR:
569538fd1498Szrj case PSEUDO_DTOR_EXPR:
569638fd1498Szrj case NEW_EXPR:
569738fd1498Szrj case VEC_NEW_EXPR:
569838fd1498Szrj case DELETE_EXPR:
569938fd1498Szrj case VEC_DELETE_EXPR:
570038fd1498Szrj case THROW_EXPR:
570138fd1498Szrj case OMP_PARALLEL:
570238fd1498Szrj case OMP_TASK:
570338fd1498Szrj case OMP_FOR:
570438fd1498Szrj case OMP_SIMD:
570538fd1498Szrj case OMP_DISTRIBUTE:
570638fd1498Szrj case OMP_TASKLOOP:
570738fd1498Szrj case OMP_TEAMS:
570838fd1498Szrj case OMP_TARGET_DATA:
570938fd1498Szrj case OMP_TARGET:
571038fd1498Szrj case OMP_SECTIONS:
571138fd1498Szrj case OMP_ORDERED:
571238fd1498Szrj case OMP_CRITICAL:
571338fd1498Szrj case OMP_SINGLE:
571438fd1498Szrj case OMP_SECTION:
571538fd1498Szrj case OMP_MASTER:
571638fd1498Szrj case OMP_TASKGROUP:
571738fd1498Szrj case OMP_TARGET_UPDATE:
571838fd1498Szrj case OMP_TARGET_ENTER_DATA:
571938fd1498Szrj case OMP_TARGET_EXIT_DATA:
572038fd1498Szrj case OMP_ATOMIC:
572138fd1498Szrj case OMP_ATOMIC_READ:
572238fd1498Szrj case OMP_ATOMIC_CAPTURE_OLD:
572338fd1498Szrj case OMP_ATOMIC_CAPTURE_NEW:
572438fd1498Szrj case OACC_PARALLEL:
572538fd1498Szrj case OACC_KERNELS:
572638fd1498Szrj case OACC_DATA:
572738fd1498Szrj case OACC_HOST_DATA:
572838fd1498Szrj case OACC_LOOP:
572938fd1498Szrj case OACC_CACHE:
573038fd1498Szrj case OACC_DECLARE:
573138fd1498Szrj case OACC_ENTER_DATA:
573238fd1498Szrj case OACC_EXIT_DATA:
573338fd1498Szrj case OACC_UPDATE:
573438fd1498Szrj /* GCC internal stuff. */
573538fd1498Szrj case VA_ARG_EXPR:
573638fd1498Szrj case OBJ_TYPE_REF:
573738fd1498Szrj case TRANSACTION_EXPR:
573838fd1498Szrj case ASM_EXPR:
573938fd1498Szrj case AT_ENCODE_EXPR:
574038fd1498Szrj fail:
574138fd1498Szrj if (flags & tf_error)
574238fd1498Szrj error_at (loc, "expression %qE is not a constant expression", t);
574338fd1498Szrj return false;
574438fd1498Szrj
574538fd1498Szrj case TYPEID_EXPR:
574638fd1498Szrj /* -- a typeid expression whose operand is of polymorphic
574738fd1498Szrj class type; */
574838fd1498Szrj {
574938fd1498Szrj tree e = TREE_OPERAND (t, 0);
575038fd1498Szrj if (!TYPE_P (e) && !type_dependent_expression_p (e)
575138fd1498Szrj && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
575238fd1498Szrj {
575338fd1498Szrj if (flags & tf_error)
575438fd1498Szrj error_at (loc, "typeid-expression is not a constant expression "
575538fd1498Szrj "because %qE is of polymorphic type", e);
575638fd1498Szrj return false;
575738fd1498Szrj }
575838fd1498Szrj return true;
575938fd1498Szrj }
576038fd1498Szrj
576138fd1498Szrj case POINTER_DIFF_EXPR:
576238fd1498Szrj case MINUS_EXPR:
576338fd1498Szrj want_rval = true;
576438fd1498Szrj goto binary;
576538fd1498Szrj
576638fd1498Szrj case LT_EXPR:
576738fd1498Szrj case LE_EXPR:
576838fd1498Szrj case GT_EXPR:
576938fd1498Szrj case GE_EXPR:
577038fd1498Szrj case EQ_EXPR:
577138fd1498Szrj case NE_EXPR:
577238fd1498Szrj want_rval = true;
577338fd1498Szrj goto binary;
577438fd1498Szrj
577538fd1498Szrj case PREINCREMENT_EXPR:
577638fd1498Szrj case POSTINCREMENT_EXPR:
577738fd1498Szrj case PREDECREMENT_EXPR:
577838fd1498Szrj case POSTDECREMENT_EXPR:
577938fd1498Szrj if (cxx_dialect < cxx14)
578038fd1498Szrj goto fail;
578138fd1498Szrj goto unary;
578238fd1498Szrj
578338fd1498Szrj case BIT_NOT_EXPR:
578438fd1498Szrj /* A destructor. */
578538fd1498Szrj if (TYPE_P (TREE_OPERAND (t, 0)))
578638fd1498Szrj return true;
578738fd1498Szrj /* fall through. */
578838fd1498Szrj
578938fd1498Szrj case CONJ_EXPR:
579038fd1498Szrj case SAVE_EXPR:
579138fd1498Szrj case FIX_TRUNC_EXPR:
579238fd1498Szrj case FLOAT_EXPR:
579338fd1498Szrj case NEGATE_EXPR:
579438fd1498Szrj case ABS_EXPR:
579538fd1498Szrj case TRUTH_NOT_EXPR:
579638fd1498Szrj case FIXED_CONVERT_EXPR:
579738fd1498Szrj case UNARY_PLUS_EXPR:
579838fd1498Szrj case UNARY_LEFT_FOLD_EXPR:
579938fd1498Szrj case UNARY_RIGHT_FOLD_EXPR:
580038fd1498Szrj unary:
580138fd1498Szrj return RECUR (TREE_OPERAND (t, 0), rval);
580238fd1498Szrj
580338fd1498Szrj case CAST_EXPR:
580438fd1498Szrj case CONST_CAST_EXPR:
580538fd1498Szrj case STATIC_CAST_EXPR:
580638fd1498Szrj case REINTERPRET_CAST_EXPR:
580738fd1498Szrj case IMPLICIT_CONV_EXPR:
580838fd1498Szrj if (cxx_dialect < cxx11
580938fd1498Szrj && !dependent_type_p (TREE_TYPE (t))
581038fd1498Szrj && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)))
581138fd1498Szrj /* In C++98, a conversion to non-integral type can't be part of a
581238fd1498Szrj constant expression. */
581338fd1498Szrj {
581438fd1498Szrj if (flags & tf_error)
581538fd1498Szrj error_at (loc,
581638fd1498Szrj "cast to non-integral type %qT in a constant expression",
581738fd1498Szrj TREE_TYPE (t));
581838fd1498Szrj return false;
581938fd1498Szrj }
582038fd1498Szrj /* This might be a conversion from a class to a (potentially) literal
582138fd1498Szrj type. Let's consider it potentially constant since the conversion
582238fd1498Szrj might be a constexpr user-defined conversion. */
582338fd1498Szrj else if (cxx_dialect >= cxx11
582438fd1498Szrj && (dependent_type_p (TREE_TYPE (t))
582538fd1498Szrj || !COMPLETE_TYPE_P (TREE_TYPE (t))
582638fd1498Szrj || literal_type_p (TREE_TYPE (t)))
582738fd1498Szrj && TREE_OPERAND (t, 0))
582838fd1498Szrj {
582938fd1498Szrj tree type = TREE_TYPE (TREE_OPERAND (t, 0));
583038fd1498Szrj /* If this is a dependent type, it could end up being a class
583138fd1498Szrj with conversions. */
583238fd1498Szrj if (type == NULL_TREE || WILDCARD_TYPE_P (type))
583338fd1498Szrj return true;
583438fd1498Szrj /* Or a non-dependent class which has conversions. */
583538fd1498Szrj else if (CLASS_TYPE_P (type)
583638fd1498Szrj && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
583738fd1498Szrj return true;
583838fd1498Szrj }
583938fd1498Szrj
584038fd1498Szrj return (RECUR (TREE_OPERAND (t, 0),
584138fd1498Szrj TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE));
584238fd1498Szrj
584338fd1498Szrj case BIND_EXPR:
584438fd1498Szrj return RECUR (BIND_EXPR_BODY (t), want_rval);
584538fd1498Szrj
584638fd1498Szrj case CLEANUP_POINT_EXPR:
584738fd1498Szrj case MUST_NOT_THROW_EXPR:
584838fd1498Szrj case TRY_CATCH_EXPR:
584938fd1498Szrj case TRY_BLOCK:
585038fd1498Szrj case EH_SPEC_BLOCK:
585138fd1498Szrj case EXPR_STMT:
585238fd1498Szrj case PAREN_EXPR:
585338fd1498Szrj case NON_DEPENDENT_EXPR:
585438fd1498Szrj /* For convenience. */
585538fd1498Szrj case RETURN_EXPR:
585638fd1498Szrj case LOOP_EXPR:
585738fd1498Szrj case EXIT_EXPR:
585838fd1498Szrj return RECUR (TREE_OPERAND (t, 0), want_rval);
585938fd1498Szrj
586038fd1498Szrj case DECL_EXPR:
586138fd1498Szrj tmp = DECL_EXPR_DECL (t);
586238fd1498Szrj if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp))
586338fd1498Szrj {
586438fd1498Szrj if (TREE_STATIC (tmp))
586538fd1498Szrj {
586638fd1498Szrj if (flags & tf_error)
586738fd1498Szrj error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared "
586838fd1498Szrj "%<static%> in %<constexpr%> context", tmp);
586938fd1498Szrj return false;
587038fd1498Szrj }
587138fd1498Szrj else if (CP_DECL_THREAD_LOCAL_P (tmp))
587238fd1498Szrj {
587338fd1498Szrj if (flags & tf_error)
587438fd1498Szrj error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared "
587538fd1498Szrj "%<thread_local%> in %<constexpr%> context", tmp);
587638fd1498Szrj return false;
587738fd1498Szrj }
587838fd1498Szrj else if (!check_for_uninitialized_const_var
587938fd1498Szrj (tmp, /*constexpr_context_p=*/true, flags))
588038fd1498Szrj return false;
588138fd1498Szrj }
588238fd1498Szrj return RECUR (tmp, want_rval);
588338fd1498Szrj
588438fd1498Szrj case TRY_FINALLY_EXPR:
588538fd1498Szrj return (RECUR (TREE_OPERAND (t, 0), want_rval)
588638fd1498Szrj && RECUR (TREE_OPERAND (t, 1), any));
588738fd1498Szrj
588838fd1498Szrj case SCOPE_REF:
588938fd1498Szrj return RECUR (TREE_OPERAND (t, 1), want_rval);
589038fd1498Szrj
589138fd1498Szrj case TARGET_EXPR:
589238fd1498Szrj if (!TARGET_EXPR_DIRECT_INIT_P (t)
589338fd1498Szrj && !literal_type_p (TREE_TYPE (t)))
589438fd1498Szrj {
589538fd1498Szrj if (flags & tf_error)
589638fd1498Szrj {
589738fd1498Szrj error_at (loc, "temporary of non-literal type %qT in a "
589838fd1498Szrj "constant expression", TREE_TYPE (t));
589938fd1498Szrj explain_non_literal_class (TREE_TYPE (t));
590038fd1498Szrj }
590138fd1498Szrj return false;
590238fd1498Szrj }
590338fd1498Szrj /* FALLTHRU */
590438fd1498Szrj case INIT_EXPR:
590538fd1498Szrj return RECUR (TREE_OPERAND (t, 1), rval);
590638fd1498Szrj
590738fd1498Szrj case CONSTRUCTOR:
590838fd1498Szrj {
590938fd1498Szrj vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
591038fd1498Szrj constructor_elt *ce;
591138fd1498Szrj for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
591238fd1498Szrj if (!RECUR (ce->value, want_rval))
591338fd1498Szrj return false;
591438fd1498Szrj return true;
591538fd1498Szrj }
591638fd1498Szrj
591738fd1498Szrj case TREE_LIST:
591838fd1498Szrj {
591938fd1498Szrj gcc_assert (TREE_PURPOSE (t) == NULL_TREE
592038fd1498Szrj || DECL_P (TREE_PURPOSE (t)));
592138fd1498Szrj if (!RECUR (TREE_VALUE (t), want_rval))
592238fd1498Szrj return false;
592338fd1498Szrj if (TREE_CHAIN (t) == NULL_TREE)
592438fd1498Szrj return true;
592538fd1498Szrj return RECUR (TREE_CHAIN (t), want_rval);
592638fd1498Szrj }
592738fd1498Szrj
592838fd1498Szrj case TRUNC_DIV_EXPR:
592938fd1498Szrj case CEIL_DIV_EXPR:
593038fd1498Szrj case FLOOR_DIV_EXPR:
593138fd1498Szrj case ROUND_DIV_EXPR:
593238fd1498Szrj case TRUNC_MOD_EXPR:
593338fd1498Szrj case CEIL_MOD_EXPR:
593438fd1498Szrj case ROUND_MOD_EXPR:
593538fd1498Szrj {
593638fd1498Szrj tree denom = TREE_OPERAND (t, 1);
593738fd1498Szrj if (!RECUR (denom, rval))
593838fd1498Szrj return false;
593938fd1498Szrj /* We can't call cxx_eval_outermost_constant_expr on an expression
594038fd1498Szrj that hasn't been through instantiate_non_dependent_expr yet. */
594138fd1498Szrj if (!processing_template_decl)
594238fd1498Szrj denom = cxx_eval_outermost_constant_expr (denom, true);
594338fd1498Szrj if (integer_zerop (denom))
594438fd1498Szrj {
594538fd1498Szrj if (flags & tf_error)
594638fd1498Szrj error ("division by zero is not a constant expression");
594738fd1498Szrj return false;
594838fd1498Szrj }
594938fd1498Szrj else
595038fd1498Szrj {
595138fd1498Szrj want_rval = true;
595238fd1498Szrj return RECUR (TREE_OPERAND (t, 0), want_rval);
595338fd1498Szrj }
595438fd1498Szrj }
595538fd1498Szrj
595638fd1498Szrj case COMPOUND_EXPR:
595738fd1498Szrj {
595838fd1498Szrj /* check_return_expr sometimes wraps a TARGET_EXPR in a
595938fd1498Szrj COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
596038fd1498Szrj introduced by build_call_a. */
596138fd1498Szrj tree op0 = TREE_OPERAND (t, 0);
596238fd1498Szrj tree op1 = TREE_OPERAND (t, 1);
596338fd1498Szrj STRIP_NOPS (op1);
596438fd1498Szrj if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
596538fd1498Szrj || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
596638fd1498Szrj return RECUR (op0, want_rval);
596738fd1498Szrj else
596838fd1498Szrj goto binary;
596938fd1498Szrj }
597038fd1498Szrj
597138fd1498Szrj /* If the first operand is the non-short-circuit constant, look at
597238fd1498Szrj the second operand; otherwise we only care about the first one for
597338fd1498Szrj potentiality. */
597438fd1498Szrj case TRUTH_AND_EXPR:
597538fd1498Szrj case TRUTH_ANDIF_EXPR:
597638fd1498Szrj tmp = boolean_true_node;
597738fd1498Szrj goto truth;
597838fd1498Szrj case TRUTH_OR_EXPR:
597938fd1498Szrj case TRUTH_ORIF_EXPR:
598038fd1498Szrj tmp = boolean_false_node;
598138fd1498Szrj truth:
598238fd1498Szrj {
598338fd1498Szrj tree op = TREE_OPERAND (t, 0);
598438fd1498Szrj if (!RECUR (op, rval))
598538fd1498Szrj return false;
598638fd1498Szrj if (!processing_template_decl)
598738fd1498Szrj op = cxx_eval_outermost_constant_expr (op, true);
598838fd1498Szrj if (tree_int_cst_equal (op, tmp))
598938fd1498Szrj return RECUR (TREE_OPERAND (t, 1), rval);
599038fd1498Szrj else
599138fd1498Szrj return true;
599238fd1498Szrj }
599338fd1498Szrj
599438fd1498Szrj case PLUS_EXPR:
599538fd1498Szrj case MULT_EXPR:
599638fd1498Szrj case POINTER_PLUS_EXPR:
599738fd1498Szrj case RDIV_EXPR:
599838fd1498Szrj case EXACT_DIV_EXPR:
599938fd1498Szrj case MIN_EXPR:
600038fd1498Szrj case MAX_EXPR:
600138fd1498Szrj case LSHIFT_EXPR:
600238fd1498Szrj case RSHIFT_EXPR:
600338fd1498Szrj case LROTATE_EXPR:
600438fd1498Szrj case RROTATE_EXPR:
600538fd1498Szrj case BIT_IOR_EXPR:
600638fd1498Szrj case BIT_XOR_EXPR:
600738fd1498Szrj case BIT_AND_EXPR:
600838fd1498Szrj case TRUTH_XOR_EXPR:
600938fd1498Szrj case UNORDERED_EXPR:
601038fd1498Szrj case ORDERED_EXPR:
601138fd1498Szrj case UNLT_EXPR:
601238fd1498Szrj case UNLE_EXPR:
601338fd1498Szrj case UNGT_EXPR:
601438fd1498Szrj case UNGE_EXPR:
601538fd1498Szrj case UNEQ_EXPR:
601638fd1498Szrj case LTGT_EXPR:
601738fd1498Szrj case RANGE_EXPR:
601838fd1498Szrj case COMPLEX_EXPR:
601938fd1498Szrj want_rval = true;
602038fd1498Szrj /* Fall through. */
602138fd1498Szrj case ARRAY_REF:
602238fd1498Szrj case ARRAY_RANGE_REF:
602338fd1498Szrj case MEMBER_REF:
602438fd1498Szrj case DOTSTAR_EXPR:
602538fd1498Szrj case MEM_REF:
602638fd1498Szrj case BINARY_LEFT_FOLD_EXPR:
602738fd1498Szrj case BINARY_RIGHT_FOLD_EXPR:
602838fd1498Szrj binary:
602938fd1498Szrj for (i = 0; i < 2; ++i)
603038fd1498Szrj if (!RECUR (TREE_OPERAND (t, i), want_rval))
603138fd1498Szrj return false;
603238fd1498Szrj return true;
603338fd1498Szrj
603438fd1498Szrj case FMA_EXPR:
603538fd1498Szrj case VEC_PERM_EXPR:
603638fd1498Szrj for (i = 0; i < 3; ++i)
603738fd1498Szrj if (!RECUR (TREE_OPERAND (t, i), true))
603838fd1498Szrj return false;
603938fd1498Szrj return true;
604038fd1498Szrj
604138fd1498Szrj case COND_EXPR:
604238fd1498Szrj if (COND_EXPR_IS_VEC_DELETE (t))
604338fd1498Szrj {
604438fd1498Szrj if (flags & tf_error)
604538fd1498Szrj error_at (loc, "%<delete[]%> is not a constant expression");
604638fd1498Szrj return false;
604738fd1498Szrj }
604838fd1498Szrj /* Fall through. */
604938fd1498Szrj case IF_STMT:
605038fd1498Szrj case VEC_COND_EXPR:
605138fd1498Szrj /* If the condition is a known constant, we know which of the legs we
605238fd1498Szrj care about; otherwise we only require that the condition and
605338fd1498Szrj either of the legs be potentially constant. */
605438fd1498Szrj tmp = TREE_OPERAND (t, 0);
605538fd1498Szrj if (!RECUR (tmp, rval))
605638fd1498Szrj return false;
605738fd1498Szrj if (!processing_template_decl)
605838fd1498Szrj tmp = cxx_eval_outermost_constant_expr (tmp, true);
605938fd1498Szrj if (integer_zerop (tmp))
606038fd1498Szrj return RECUR (TREE_OPERAND (t, 2), want_rval);
606138fd1498Szrj else if (TREE_CODE (tmp) == INTEGER_CST)
606238fd1498Szrj return RECUR (TREE_OPERAND (t, 1), want_rval);
606338fd1498Szrj for (i = 1; i < 3; ++i)
606438fd1498Szrj if (potential_constant_expression_1 (TREE_OPERAND (t, i),
606538fd1498Szrj want_rval, strict, now, tf_none))
606638fd1498Szrj return true;
606738fd1498Szrj if (flags & tf_error)
606838fd1498Szrj error_at (loc, "expression %qE is not a constant expression", t);
606938fd1498Szrj return false;
607038fd1498Szrj
607138fd1498Szrj case VEC_INIT_EXPR:
607238fd1498Szrj if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
607338fd1498Szrj return true;
607438fd1498Szrj if (flags & tf_error)
607538fd1498Szrj {
607638fd1498Szrj error_at (loc, "non-constant array initialization");
607738fd1498Szrj diagnose_non_constexpr_vec_init (t);
607838fd1498Szrj }
607938fd1498Szrj return false;
608038fd1498Szrj
608138fd1498Szrj case TYPE_DECL:
608238fd1498Szrj case TAG_DEFN:
608338fd1498Szrj /* We can see these in statement-expressions. */
608438fd1498Szrj return true;
608538fd1498Szrj
608638fd1498Szrj case CLEANUP_STMT:
608738fd1498Szrj case EMPTY_CLASS_EXPR:
608838fd1498Szrj case PREDICT_EXPR:
608938fd1498Szrj return false;
609038fd1498Szrj
609138fd1498Szrj case GOTO_EXPR:
609238fd1498Szrj {
609338fd1498Szrj tree *target = &TREE_OPERAND (t, 0);
609438fd1498Szrj /* Gotos representing break and continue are OK. */
609538fd1498Szrj if (breaks (target) || continues (target))
609638fd1498Szrj return true;
609738fd1498Szrj if (flags & tf_error)
609838fd1498Szrj error_at (loc, "%<goto%> is not a constant expression");
609938fd1498Szrj return false;
610038fd1498Szrj }
610138fd1498Szrj
610238fd1498Szrj case ANNOTATE_EXPR:
610338fd1498Szrj return RECUR (TREE_OPERAND (t, 0), rval);
610438fd1498Szrj
610538fd1498Szrj default:
610638fd1498Szrj if (objc_is_property_ref (t))
610738fd1498Szrj return false;
610838fd1498Szrj
610938fd1498Szrj sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
611038fd1498Szrj gcc_unreachable ();
611138fd1498Szrj return false;
611238fd1498Szrj }
611338fd1498Szrj #undef RECUR
611438fd1498Szrj }
611538fd1498Szrj
611638fd1498Szrj /* The main entry point to the above. */
611738fd1498Szrj
611838fd1498Szrj bool
potential_constant_expression(tree t)611938fd1498Szrj potential_constant_expression (tree t)
612038fd1498Szrj {
612138fd1498Szrj return potential_constant_expression_1 (t, false, true, false, tf_none);
612238fd1498Szrj }
612338fd1498Szrj
612438fd1498Szrj /* As above, but require a constant rvalue. */
612538fd1498Szrj
612638fd1498Szrj bool
potential_rvalue_constant_expression(tree t)612738fd1498Szrj potential_rvalue_constant_expression (tree t)
612838fd1498Szrj {
612938fd1498Szrj return potential_constant_expression_1 (t, true, true, false, tf_none);
613038fd1498Szrj }
613138fd1498Szrj
613238fd1498Szrj /* Like above, but complain about non-constant expressions. */
613338fd1498Szrj
613438fd1498Szrj bool
require_potential_constant_expression(tree t)613538fd1498Szrj require_potential_constant_expression (tree t)
613638fd1498Szrj {
613738fd1498Szrj return potential_constant_expression_1 (t, false, true, false,
613838fd1498Szrj tf_warning_or_error);
613938fd1498Szrj }
614038fd1498Szrj
614138fd1498Szrj /* Cross product of the above. */
614238fd1498Szrj
614338fd1498Szrj bool
require_potential_rvalue_constant_expression(tree t)614438fd1498Szrj require_potential_rvalue_constant_expression (tree t)
614538fd1498Szrj {
614638fd1498Szrj return potential_constant_expression_1 (t, true, true, false,
614738fd1498Szrj tf_warning_or_error);
614838fd1498Szrj }
614938fd1498Szrj
615038fd1498Szrj /* Like above, but don't consider PARM_DECL a potential_constant_expression. */
615138fd1498Szrj
615238fd1498Szrj bool
require_rvalue_constant_expression(tree t)615338fd1498Szrj require_rvalue_constant_expression (tree t)
615438fd1498Szrj {
615538fd1498Szrj return potential_constant_expression_1 (t, true, true, true,
615638fd1498Szrj tf_warning_or_error);
615738fd1498Szrj }
615838fd1498Szrj
615938fd1498Szrj /* Like potential_constant_expression, but don't consider possible constexpr
616038fd1498Szrj substitution of the current function. That is, PARM_DECL qualifies under
616138fd1498Szrj potential_constant_expression, but not here.
616238fd1498Szrj
616338fd1498Szrj This is basically what you can check when any actual constant values might
616438fd1498Szrj be value-dependent. */
616538fd1498Szrj
616638fd1498Szrj bool
is_constant_expression(tree t)616738fd1498Szrj is_constant_expression (tree t)
616838fd1498Szrj {
616938fd1498Szrj return potential_constant_expression_1 (t, false, true, true, tf_none);
617038fd1498Szrj }
617138fd1498Szrj
617238fd1498Szrj /* Like above, but complain about non-constant expressions. */
617338fd1498Szrj
617438fd1498Szrj bool
require_constant_expression(tree t)617538fd1498Szrj require_constant_expression (tree t)
617638fd1498Szrj {
617738fd1498Szrj return potential_constant_expression_1 (t, false, true, true,
617838fd1498Szrj tf_warning_or_error);
617938fd1498Szrj }
618038fd1498Szrj
618138fd1498Szrj /* Like is_constant_expression, but allow const variables that are not allowed
618238fd1498Szrj under constexpr rules. */
618338fd1498Szrj
618438fd1498Szrj bool
is_static_init_expression(tree t)618538fd1498Szrj is_static_init_expression (tree t)
618638fd1498Szrj {
618738fd1498Szrj return potential_constant_expression_1 (t, false, false, true, tf_none);
618838fd1498Szrj }
618938fd1498Szrj
619038fd1498Szrj /* Returns true if T is a potential constant expression that is not
619138fd1498Szrj instantiation-dependent, and therefore a candidate for constant folding even
619238fd1498Szrj in a template. */
619338fd1498Szrj
619438fd1498Szrj bool
is_nondependent_constant_expression(tree t)619538fd1498Szrj is_nondependent_constant_expression (tree t)
619638fd1498Szrj {
619738fd1498Szrj return (!type_unknown_p (t)
619838fd1498Szrj && !BRACE_ENCLOSED_INITIALIZER_P (t)
619938fd1498Szrj && is_constant_expression (t)
620038fd1498Szrj && !instantiation_dependent_expression_p (t));
620138fd1498Szrj }
620238fd1498Szrj
620338fd1498Szrj /* Returns true if T is a potential static initializer expression that is not
620438fd1498Szrj instantiation-dependent. */
620538fd1498Szrj
620638fd1498Szrj bool
is_nondependent_static_init_expression(tree t)620738fd1498Szrj is_nondependent_static_init_expression (tree t)
620838fd1498Szrj {
620938fd1498Szrj return (!type_unknown_p (t)
621038fd1498Szrj && !BRACE_ENCLOSED_INITIALIZER_P (t)
621138fd1498Szrj && is_static_init_expression (t)
621238fd1498Szrj && !instantiation_dependent_expression_p (t));
621338fd1498Szrj }
621438fd1498Szrj
621538fd1498Szrj /* Finalize constexpr processing after parsing. */
621638fd1498Szrj
621738fd1498Szrj void
fini_constexpr(void)621838fd1498Szrj fini_constexpr (void)
621938fd1498Szrj {
622038fd1498Szrj /* The contexpr call and fundef copies tables are no longer needed. */
622138fd1498Szrj constexpr_call_table = NULL;
622238fd1498Szrj fundef_copies_table = NULL;
622338fd1498Szrj }
622438fd1498Szrj
622538fd1498Szrj #include "gt-cp-constexpr.h"
6226