File: | build/gcc/vec.h |
Warning: | line 827, column 3 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Perform -*- C++ -*- constant expression evaluation, including calls to | ||||||
2 | constexpr functions. These routines are used both during actual parsing | ||||||
3 | and during the instantiation of template functions. | ||||||
4 | |||||||
5 | Copyright (C) 1998-2021 Free Software Foundation, Inc. | ||||||
6 | |||||||
7 | This file is part of GCC. | ||||||
8 | |||||||
9 | GCC is free software; you can redistribute it and/or modify it | ||||||
10 | under the terms of the GNU General Public License as published by | ||||||
11 | the Free Software Foundation; either version 3, or (at your option) | ||||||
12 | any later version. | ||||||
13 | |||||||
14 | GCC is distributed in the hope that it will be useful, but | ||||||
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||||
17 | General Public License for more details. | ||||||
18 | |||||||
19 | You should have received a copy of the GNU General Public License | ||||||
20 | along with GCC; see the file COPYING3. If not see | ||||||
21 | <http://www.gnu.org/licenses/>. */ | ||||||
22 | |||||||
23 | #include "config.h" | ||||||
24 | #include "system.h" | ||||||
25 | #include "coretypes.h" | ||||||
26 | #include "cp-tree.h" | ||||||
27 | #include "varasm.h" | ||||||
28 | #include "c-family/c-objc.h" | ||||||
29 | #include "tree-iterator.h" | ||||||
30 | #include "gimplify.h" | ||||||
31 | #include "builtins.h" | ||||||
32 | #include "tree-inline.h" | ||||||
33 | #include "ubsan.h" | ||||||
34 | #include "gimple-fold.h" | ||||||
35 | #include "timevar.h" | ||||||
36 | #include "fold-const-call.h" | ||||||
37 | #include "stor-layout.h" | ||||||
38 | |||||||
39 | static bool verify_constant (tree, bool, bool *, bool *); | ||||||
40 | #define VERIFY_CONSTANT(X)do { if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0) \ | ||||||
41 | do { \ | ||||||
42 | if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \ | ||||||
43 | return t; \ | ||||||
44 | } while (0) | ||||||
45 | |||||||
46 | static HOST_WIDE_INTlong find_array_ctor_elt (tree ary, tree dindex, | ||||||
47 | bool insert = false); | ||||||
48 | |||||||
49 | /* Returns true iff FUN is an instantiation of a constexpr function | ||||||
50 | template or a defaulted constexpr function. */ | ||||||
51 | |||||||
52 | bool | ||||||
53 | is_instantiation_of_constexpr (tree fun) | ||||||
54 | { | ||||||
55 | return ((DECL_TEMPLOID_INSTANTIATION (fun)(((((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 55, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 55, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 55, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 55, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info) && !(((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 55, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) | ||||||
56 | && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun))((contains_struct_check (((tree_check2 (((((enum tree_code) ( ((struct tree_template_info*)(tree_check (((((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__, (TEMPLATE_INFO))))->tmpl)->base.code ) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast <union tree_node *> ((((tree_check ((((struct tree_template_info *)(tree_check (((((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__, (TEMPLATE_INFO))))->tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__, (TEMPLATE_DECL))))))))->result : ((struct tree_template_info*)(tree_check (((((contains_struct_check ( (template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__, (TEMPLATE_INFO))))->tmpl)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 56, __FUNCTION__))->decl_common.lang_flag_8)) | ||||||
57 | || (DECL_DEFAULTED_FN (fun)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 57, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun)) , (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 57, __FUNCTION__))->decl_common.lang_specific); if (!((( enum tree_code) (fun)->base.code) == FUNCTION_DECL || (((enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ( (struct tree_template_decl *)(const_cast<union tree_node * > ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 57, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 57, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 57, __FUNCTION__); <->u.fn; })->defaulted_p) | ||||||
58 | && DECL_DECLARED_CONSTEXPR_P (fun)((contains_struct_check (((tree_check2 (((((enum tree_code) ( fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 58, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun)) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 58, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 58, __FUNCTION__))->decl_common.lang_flag_8))); | ||||||
59 | } | ||||||
60 | |||||||
61 | /* Return true if T is a literal type. */ | ||||||
62 | |||||||
63 | bool | ||||||
64 | literal_type_p (tree t) | ||||||
65 | { | ||||||
66 | if (SCALAR_TYPE_P (t)((((enum tree_code) (t)->base.code) == OFFSET_TYPE) || ((enum tree_code) (t)->base.code) == ENUMERAL_TYPE || ((((enum tree_code ) (t)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (t) ->base.code) == INTEGER_TYPE) || ((enum tree_code) (t)-> base.code) == REAL_TYPE || ((enum tree_code) (t)->base.code ) == COMPLEX_TYPE) || (((enum tree_code) (t)->base.code) == POINTER_TYPE) || (((enum tree_code) (t)->base.code) == RECORD_TYPE && (((tree_class_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 66, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 66, __FUNCTION__))->type_common.lang_flag_2))) || (((enum tree_code) (t)->base.code) == NULLPTR_TYPE)) | ||||||
67 | || VECTOR_TYPE_P (t)(((enum tree_code) (t)->base.code) == VECTOR_TYPE) | ||||||
68 | || TYPE_REF_P (t)(((enum tree_code) (t)->base.code) == REFERENCE_TYPE) | ||||||
69 | || (VOID_TYPE_P (t)(((enum tree_code) (t)->base.code) == VOID_TYPE) && cxx_dialect >= cxx14)) | ||||||
70 | return true; | ||||||
71 | if (CLASS_TYPE_P (t)(((((enum tree_code) (t)->base.code)) == RECORD_TYPE || (( (enum tree_code) (t)->base.code)) == UNION_TYPE) && ((tree_class_check ((t), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 71, __FUNCTION__))->type_common.lang_flag_5))) | ||||||
72 | { | ||||||
73 | t = complete_type (t); | ||||||
74 | gcc_assert (COMPLETE_TYPE_P (t) || errorcount)((void)(!((((tree_class_check ((t), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 74, __FUNCTION__))->type_common.size) != (tree) nullptr) || (global_dc)->diagnostic_count[(int) (DK_ERROR)]) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 74, __FUNCTION__), 0 : 0)); | ||||||
75 | return CLASSTYPE_LITERAL_P (t)((((tree_class_check ((t), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 75, __FUNCTION__))->type_with_lang_specific.lang_specific ))->is_literal); | ||||||
76 | } | ||||||
77 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_TYPE) | ||||||
78 | return literal_type_p (strip_array_types (t)); | ||||||
79 | return false; | ||||||
80 | } | ||||||
81 | |||||||
82 | /* If DECL is a variable declared `constexpr', require its type | ||||||
83 | be literal. Return error_mark_node if we give an error, the | ||||||
84 | DECL otherwise. */ | ||||||
85 | |||||||
86 | tree | ||||||
87 | ensure_literal_type_for_constexpr_object (tree decl) | ||||||
88 | { | ||||||
89 | tree type = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 89, __FUNCTION__))->typed.type); | ||||||
90 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) | ||||||
91 | && (DECL_DECLARED_CONSTEXPR_P (decl)((contains_struct_check (((tree_check2 (((((enum tree_code) ( decl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((decl ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 91, __FUNCTION__, (TEMPLATE_DECL))))))))->result : decl) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 91, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 91, __FUNCTION__))->decl_common.lang_flag_8) | ||||||
92 | || var_in_constexpr_fn (decl)) | ||||||
93 | && !processing_template_declscope_chain->x_processing_template_decl) | ||||||
94 | { | ||||||
95 | tree stype = strip_array_types (type); | ||||||
96 | if (CLASS_TYPE_P (stype)(((((enum tree_code) (stype)->base.code)) == RECORD_TYPE || (((enum tree_code) (stype)->base.code)) == UNION_TYPE) && ((tree_class_check ((stype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 96, __FUNCTION__))->type_common.lang_flag_5)) && !COMPLETE_TYPE_P (complete_type (stype))(((tree_class_check ((complete_type (stype)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 96, __FUNCTION__))->type_common.size) != (tree) nullptr)) | ||||||
97 | /* Don't complain here, we'll complain about incompleteness | ||||||
98 | when we try to initialize the variable. */; | ||||||
99 | else if (!literal_type_p (type)) | ||||||
100 | { | ||||||
101 | if (DECL_DECLARED_CONSTEXPR_P (decl)((contains_struct_check (((tree_check2 (((((enum tree_code) ( decl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((decl ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 101, __FUNCTION__, (TEMPLATE_DECL))))))))->result : decl )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 101, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 101, __FUNCTION__))->decl_common.lang_flag_8)) | ||||||
102 | { | ||||||
103 | auto_diagnostic_group d; | ||||||
104 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 104, __FUNCTION__))->decl_minimal.locus), | ||||||
105 | "the type %qT of %<constexpr%> variable %qD " | ||||||
106 | "is not literal", type, decl); | ||||||
107 | explain_non_literal_class (type); | ||||||
108 | decl = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
109 | } | ||||||
110 | else | ||||||
111 | { | ||||||
112 | if (!is_instantiation_of_constexpr (current_function_decl)) | ||||||
113 | { | ||||||
114 | auto_diagnostic_group d; | ||||||
115 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 115, __FUNCTION__))->decl_minimal.locus), | ||||||
116 | "variable %qD of non-literal type %qT in " | ||||||
117 | "%<constexpr%> function", decl, type); | ||||||
118 | explain_non_literal_class (type); | ||||||
119 | decl = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
120 | } | ||||||
121 | cp_function_chain((cfun + 0)->language)->invalid_constexpr = true; | ||||||
122 | } | ||||||
123 | } | ||||||
124 | else if (DECL_DECLARED_CONSTEXPR_P (decl)((contains_struct_check (((tree_check2 (((((enum tree_code) ( decl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((decl ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 124, __FUNCTION__, (TEMPLATE_DECL))))))))->result : decl )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 124, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 124, __FUNCTION__))->decl_common.lang_flag_8) | ||||||
125 | && variably_modified_type_p (type, NULL_TREE(tree) nullptr)) | ||||||
126 | { | ||||||
127 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 127, __FUNCTION__))->decl_minimal.locus), | ||||||
128 | "%<constexpr%> variable %qD has variably-modified " | ||||||
129 | "type %qT", decl, type); | ||||||
130 | decl = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
131 | } | ||||||
132 | } | ||||||
133 | return decl; | ||||||
134 | } | ||||||
135 | |||||||
136 | struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef> | ||||||
137 | { | ||||||
138 | static hashval_t hash (const constexpr_fundef *); | ||||||
139 | static bool equal (const constexpr_fundef *, const constexpr_fundef *); | ||||||
140 | }; | ||||||
141 | |||||||
142 | /* This table holds all constexpr function definitions seen in | ||||||
143 | the current translation unit. */ | ||||||
144 | |||||||
145 | static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table; | ||||||
146 | |||||||
147 | /* Utility function used for managing the constexpr function table. | ||||||
148 | Return true if the entries pointed to by P and Q are for the | ||||||
149 | same constexpr function. */ | ||||||
150 | |||||||
151 | inline bool | ||||||
152 | constexpr_fundef_hasher::equal (const constexpr_fundef *lhs, | ||||||
153 | const constexpr_fundef *rhs) | ||||||
154 | { | ||||||
155 | return lhs->decl == rhs->decl; | ||||||
156 | } | ||||||
157 | |||||||
158 | /* Utility function used for managing the constexpr function table. | ||||||
159 | Return a hash value for the entry pointed to by Q. */ | ||||||
160 | |||||||
161 | inline hashval_t | ||||||
162 | constexpr_fundef_hasher::hash (const constexpr_fundef *fundef) | ||||||
163 | { | ||||||
164 | return DECL_UID (fundef->decl)((contains_struct_check ((fundef->decl), (TS_DECL_MINIMAL) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 164, __FUNCTION__))->decl_minimal.uid); | ||||||
165 | } | ||||||
166 | |||||||
167 | /* Return a previously saved definition of function FUN. */ | ||||||
168 | |||||||
169 | constexpr_fundef * | ||||||
170 | retrieve_constexpr_fundef (tree fun) | ||||||
171 | { | ||||||
172 | if (constexpr_fundef_table == NULLnullptr) | ||||||
173 | return NULLnullptr; | ||||||
174 | |||||||
175 | constexpr_fundef fundef = { fun, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr }; | ||||||
176 | return constexpr_fundef_table->find (&fundef); | ||||||
177 | } | ||||||
178 | |||||||
179 | /* Check whether the parameter and return types of FUN are valid for a | ||||||
180 | constexpr function, and complain if COMPLAIN. */ | ||||||
181 | |||||||
182 | bool | ||||||
183 | is_valid_constexpr_fn (tree fun, bool complain) | ||||||
184 | { | ||||||
185 | bool ret = true; | ||||||
186 | |||||||
187 | if (DECL_INHERITED_CTOR (fun)((((enum tree_code) (fun)->base.code) == FUNCTION_DECL || ( ((enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) && ((tree_check (((((enum tree_code ) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) ? __extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 187, __FUNCTION__); <->u.fn; })->context : (tree ) nullptr) | ||||||
188 | && TREE_CODE (fun)((enum tree_code) (fun)->base.code) == TEMPLATE_DECL) | ||||||
189 | { | ||||||
190 | ret = false; | ||||||
191 | if (complain) | ||||||
192 | error ("inherited constructor %qD is not %<constexpr%>", | ||||||
193 | DECL_INHERITED_CTOR (fun)((((enum tree_code) (fun)->base.code) == FUNCTION_DECL || ( ((enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) && ((tree_check (((((enum tree_code ) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) ? __extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 193, __FUNCTION__); <->u.fn; })->context : (tree ) nullptr)); | ||||||
194 | } | ||||||
195 | else | ||||||
196 | { | ||||||
197 | for (tree parm = FUNCTION_FIRST_USER_PARM (fun)skip_artificial_parms_for ((fun), ((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 197, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments )); | ||||||
198 | parm != NULL_TREE(tree) nullptr; parm = TREE_CHAIN (parm)((contains_struct_check ((parm), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 198, __FUNCTION__))->common.chain)) | ||||||
199 | if (!literal_type_p (TREE_TYPE (parm)((contains_struct_check ((parm), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 199, __FUNCTION__))->typed.type))) | ||||||
200 | { | ||||||
201 | ret = false; | ||||||
202 | if (complain) | ||||||
203 | { | ||||||
204 | auto_diagnostic_group d; | ||||||
205 | error ("invalid type for parameter %d of %<constexpr%> " | ||||||
206 | "function %q+#D", DECL_PARM_INDEX (parm)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check ((parm), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 206, __FUNCTION__))->decl_common.lang_specific); if (((enum tree_code) (parm)->base.code) != PARM_DECL || lt->u.base .selector != lds_parm) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 206, __FUNCTION__); <->u.parm; })->index), fun); | ||||||
207 | explain_non_literal_class (TREE_TYPE (parm)((contains_struct_check ((parm), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 207, __FUNCTION__))->typed.type)); | ||||||
208 | } | ||||||
209 | } | ||||||
210 | } | ||||||
211 | |||||||
212 | if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))(((enum tree_code) ((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]))->base.code) == RECORD_TYPE && (((( tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name) && (tree_code_type [(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name))) && ((tree_check ((((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name) && (tree_code_type [(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__))->type_common.name)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 212, __FUNCTION__, (IDENTIFIER_NODE)))->base.protected_flag )) && cxx_dialect < cxx17) | ||||||
213 | { | ||||||
214 | ret = false; | ||||||
215 | if (complain) | ||||||
216 | inform (DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 216, __FUNCTION__))->decl_minimal.locus), | ||||||
217 | "lambdas are implicitly %<constexpr%> only in C++17 and later"); | ||||||
218 | } | ||||||
219 | else if (!DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 219, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 219, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
220 | { | ||||||
221 | tree rettype = TREE_TYPE (TREE_TYPE (fun))((contains_struct_check ((((contains_struct_check ((fun), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 221, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 221, __FUNCTION__))->typed.type); | ||||||
222 | if (!literal_type_p (rettype)) | ||||||
223 | { | ||||||
224 | ret = false; | ||||||
225 | if (complain) | ||||||
226 | { | ||||||
227 | auto_diagnostic_group d; | ||||||
228 | error ("invalid return type %qT of %<constexpr%> function %q+D", | ||||||
229 | rettype, fun); | ||||||
230 | explain_non_literal_class (rettype); | ||||||
231 | } | ||||||
232 | } | ||||||
233 | |||||||
234 | /* C++14 DR 1684 removed this restriction. */ | ||||||
235 | if (cxx_dialect < cxx14 | ||||||
236 | && DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)(((enum tree_code) (((contains_struct_check ((fun), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 236, __FUNCTION__))->typed.type))->base.code) == METHOD_TYPE ) | ||||||
237 | && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun))((((tree_class_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 237, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 237, __FUNCTION__))->type_with_lang_specific.lang_specific ))->is_literal)) | ||||||
238 | { | ||||||
239 | ret = false; | ||||||
240 | if (complain) | ||||||
241 | { | ||||||
242 | auto_diagnostic_group d; | ||||||
243 | if (pedwarn (DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 243, __FUNCTION__))->decl_minimal.locus), OPT_Wpedantic, | ||||||
244 | "enclosing class of %<constexpr%> non-static" | ||||||
245 | " member function %q+#D is not a literal type", | ||||||
246 | fun)) | ||||||
247 | explain_non_literal_class (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 247, __FUNCTION__))->decl_minimal.context)); | ||||||
248 | } | ||||||
249 | } | ||||||
250 | } | ||||||
251 | else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun))((((tree_class_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 251, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 251, __FUNCTION__))->type_with_lang_specific.lang_specific ))->vbases)) | ||||||
252 | { | ||||||
253 | ret = false; | ||||||
254 | if (complain) | ||||||
255 | error ("%q#T has virtual base classes", DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 255, __FUNCTION__))->decl_minimal.context)); | ||||||
256 | } | ||||||
257 | |||||||
258 | return ret; | ||||||
259 | } | ||||||
260 | |||||||
261 | /* Subroutine of build_data_member_initialization. MEMBER is a COMPONENT_REF | ||||||
262 | for a member of an anonymous aggregate, INIT is the initializer for that | ||||||
263 | member, and VEC_OUTER is the vector of constructor elements for the class | ||||||
264 | whose constructor we are processing. Add the initializer to the vector | ||||||
265 | and return true to indicate success. */ | ||||||
266 | |||||||
267 | static bool | ||||||
268 | build_anon_member_initialization (tree member, tree init, | ||||||
269 | vec<constructor_elt, va_gc> **vec_outer) | ||||||
270 | { | ||||||
271 | /* MEMBER presents the relevant fields from the inside out, but we need | ||||||
272 | to build up the initializer from the outside in so that we can reuse | ||||||
273 | previously built CONSTRUCTORs if this is, say, the second field in an | ||||||
274 | anonymous struct. So we use a vec as a stack. */ | ||||||
275 | auto_vec<tree, 2> fields; | ||||||
276 | do | ||||||
277 | { | ||||||
278 | fields.safe_push (TREE_OPERAND (member, 1)(*((const_cast<tree*> (tree_operand_check ((member), (1 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 278, __FUNCTION__)))))); | ||||||
279 | member = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 279, __FUNCTION__))))); | ||||||
280 | } | ||||||
281 | while (ANON_AGGR_TYPE_P (TREE_TYPE (member))((((((enum tree_code) (((contains_struct_check ((member), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 281, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((member), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 281, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((member ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 281, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 281, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((member), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 281, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 281, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr) | ||||||
282 | && TREE_CODE (member)((enum tree_code) (member)->base.code) == COMPONENT_REF); | ||||||
283 | |||||||
284 | /* VEC has the constructor elements vector for the context of FIELD. | ||||||
285 | If FIELD is an anonymous aggregate, we will push inside it. */ | ||||||
286 | vec<constructor_elt, va_gc> **vec = vec_outer; | ||||||
287 | tree field; | ||||||
288 | while (field = fields.pop(), | ||||||
289 | ANON_AGGR_TYPE_P (TREE_TYPE (field))((((((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 289, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 289, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((field ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 289, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 289, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((field), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 289, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 289, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) | ||||||
290 | { | ||||||
291 | tree ctor; | ||||||
292 | /* If there is already an outer constructor entry for the anonymous | ||||||
293 | aggregate FIELD, use it; otherwise, insert one. */ | ||||||
294 | if (vec_safe_is_empty (*vec) | ||||||
295 | || (*vec)->last().index != field) | ||||||
296 | { | ||||||
297 | ctor = build_constructor (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 297, __FUNCTION__))->typed.type), NULLnullptr); | ||||||
298 | CONSTRUCTOR_APPEND_ELT (*vec, field, ctor)do { constructor_elt _ce___ = {field, ctor}; vec_safe_push (( *vec), _ce___); } while (0); | ||||||
299 | } | ||||||
300 | else | ||||||
301 | ctor = (*vec)->last().value; | ||||||
302 | vec = &CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 302, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
303 | } | ||||||
304 | |||||||
305 | /* Now we're at the innermost field, the one that isn't an anonymous | ||||||
306 | aggregate. Add its initializer to the CONSTRUCTOR and we're done. */ | ||||||
307 | gcc_assert (fields.is_empty())((void)(!(fields.is_empty()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 307, __FUNCTION__), 0 : 0)); | ||||||
308 | CONSTRUCTOR_APPEND_ELT (*vec, field, init)do { constructor_elt _ce___ = {field, init}; vec_safe_push (( *vec), _ce___); } while (0); | ||||||
309 | |||||||
310 | return true; | ||||||
311 | } | ||||||
312 | |||||||
313 | /* Subroutine of build_constexpr_constructor_member_initializers. | ||||||
314 | The expression tree T represents a data member initialization | ||||||
315 | in a (constexpr) constructor definition. Build a pairing of | ||||||
316 | the data member with its initializer, and prepend that pair | ||||||
317 | to the existing initialization pair INITS. */ | ||||||
318 | |||||||
319 | static bool | ||||||
320 | build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec) | ||||||
321 | { | ||||||
322 | tree member, init; | ||||||
323 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CLEANUP_POINT_EXPR) | ||||||
324 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 324, __FUNCTION__))))); | ||||||
325 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == EXPR_STMT) | ||||||
326 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 326, __FUNCTION__))))); | ||||||
327 | if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
328 | return false; | ||||||
329 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == STATEMENT_LIST) | ||||||
330 | { | ||||||
331 | tree_stmt_iterator i; | ||||||
332 | for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) | ||||||
333 | { | ||||||
334 | if (! build_data_member_initialization (tsi_stmt (i), vec)) | ||||||
335 | return false; | ||||||
336 | } | ||||||
337 | return true; | ||||||
338 | } | ||||||
339 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CLEANUP_STMT) | ||||||
340 | { | ||||||
341 | /* We can't see a CLEANUP_STMT in a constructor for a literal class, | ||||||
342 | but we can in a constexpr constructor for a non-literal class. Just | ||||||
343 | ignore it; either all the initialization will be constant, in which | ||||||
344 | case the cleanup can't run, or it can't be constexpr. | ||||||
345 | Still recurse into CLEANUP_BODY. */ | ||||||
346 | return build_data_member_initialization (CLEANUP_BODY (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 346, __FUNCTION__, (CLEANUP_STMT)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 346, __FUNCTION__))))), vec); | ||||||
347 | } | ||||||
348 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CONVERT_EXPR) | ||||||
349 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 349, __FUNCTION__))))); | ||||||
350 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == INIT_EXPR | ||||||
351 | /* vptr initialization shows up as a MODIFY_EXPR. In C++14 we only | ||||||
352 | use what this function builds for cx_check_missing_mem_inits, and | ||||||
353 | assignment in the ctor body doesn't count. */ | ||||||
354 | || (cxx_dialect < cxx14 && TREE_CODE (t)((enum tree_code) (t)->base.code) == MODIFY_EXPR)) | ||||||
355 | { | ||||||
356 | member = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 356, __FUNCTION__))))); | ||||||
357 | init = break_out_target_exprs (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 357, __FUNCTION__)))))); | ||||||
358 | } | ||||||
359 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR) | ||||||
360 | { | ||||||
361 | tree fn = get_callee_fndecl (t); | ||||||
362 | if (!fn || !DECL_CONSTRUCTOR_P (fn)((tree_check (((((enum tree_code) (fn)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fn), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 362, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fn)) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 362, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
363 | /* We're only interested in calls to subobject constructors. */ | ||||||
364 | return true; | ||||||
365 | member = CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 365, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 365, __FUNCTION__))))); | ||||||
366 | /* We don't use build_cplus_new here because it complains about | ||||||
367 | abstract bases. Leaving the call unwrapped means that it has the | ||||||
368 | wrong type, but cxx_eval_constant_expression doesn't care. */ | ||||||
369 | init = break_out_target_exprs (t); | ||||||
370 | } | ||||||
371 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == BIND_EXPR) | ||||||
372 | return build_data_member_initialization (BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 372, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 372, __FUNCTION__)))))), vec); | ||||||
373 | else | ||||||
374 | /* Don't add anything else to the CONSTRUCTOR. */ | ||||||
375 | return true; | ||||||
376 | if (INDIRECT_REF_P (member)(((enum tree_code) (member)->base.code) == INDIRECT_REF)) | ||||||
377 | member = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 377, __FUNCTION__))))); | ||||||
378 | if (TREE_CODE (member)((enum tree_code) (member)->base.code) == NOP_EXPR) | ||||||
379 | { | ||||||
380 | tree op = member; | ||||||
381 | STRIP_NOPS (op)(op) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((op))))); | ||||||
382 | if (TREE_CODE (op)((enum tree_code) (op)->base.code) == ADDR_EXPR) | ||||||
383 | { | ||||||
384 | gcc_assert (same_type_ignoring_top_level_qualifiers_p((void)(!(same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 385, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 385, __FUNCTION__))->typed.type), ((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__))->typed.type))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__), 0 : 0)) | ||||||
385 | (TREE_TYPE (TREE_TYPE (op)),((void)(!(same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 385, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 385, __FUNCTION__))->typed.type), ((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__))->typed.type))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__), 0 : 0)) | ||||||
386 | TREE_TYPE (TREE_TYPE (member))))((void)(!(same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 385, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 385, __FUNCTION__))->typed.type), ((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__))->typed.type))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 386, __FUNCTION__), 0 : 0)); | ||||||
387 | /* Initializing a cv-qualified member; we need to look through | ||||||
388 | the const_cast. */ | ||||||
389 | member = op; | ||||||
390 | } | ||||||
391 | else if (op == current_class_ptr(*((cfun + 0) && ((cfun + 0)->language) ? &((cfun + 0)->language)->x_current_class_ptr : &scope_chain ->x_current_class_ptr)) | ||||||
392 | && (same_type_ignoring_top_level_qualifiers_p | ||||||
393 | (TREE_TYPE (TREE_TYPE (member))((contains_struct_check ((((contains_struct_check ((member), ( TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 393, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 393, __FUNCTION__))->typed.type), | ||||||
394 | current_class_typescope_chain->class_type))) | ||||||
395 | /* Delegating constructor. */ | ||||||
396 | member = op; | ||||||
397 | else | ||||||
398 | { | ||||||
399 | /* This is an initializer for an empty base; keep it for now so | ||||||
400 | we can check it in cxx_eval_bare_aggregate. */ | ||||||
401 | gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))))((void)(!(is_empty_class (((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 401, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 401, __FUNCTION__))->typed.type))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 401, __FUNCTION__), 0 : 0)); | ||||||
402 | } | ||||||
403 | } | ||||||
404 | if (TREE_CODE (member)((enum tree_code) (member)->base.code) == ADDR_EXPR) | ||||||
405 | member = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 405, __FUNCTION__))))); | ||||||
406 | if (TREE_CODE (member)((enum tree_code) (member)->base.code) == COMPONENT_REF) | ||||||
407 | { | ||||||
408 | tree aggr = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 408, __FUNCTION__))))); | ||||||
409 | if (TREE_CODE (aggr)((enum tree_code) (aggr)->base.code) == VAR_DECL) | ||||||
410 | /* Initializing a local variable, don't add anything. */ | ||||||
411 | return true; | ||||||
412 | if (TREE_CODE (aggr)((enum tree_code) (aggr)->base.code) != COMPONENT_REF) | ||||||
413 | /* Normal member initialization. */ | ||||||
414 | member = TREE_OPERAND (member, 1)(*((const_cast<tree*> (tree_operand_check ((member), (1 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 414, __FUNCTION__))))); | ||||||
415 | else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr))((((((enum tree_code) (((contains_struct_check ((aggr), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 415, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((aggr), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 415, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((aggr ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 415, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 415, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((aggr), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 415, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 415, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) | ||||||
416 | /* Initializing a member of an anonymous union. */ | ||||||
417 | return build_anon_member_initialization (member, init, vec); | ||||||
418 | else | ||||||
419 | /* We're initializing a vtable pointer in a base. Leave it as | ||||||
420 | COMPONENT_REF so we remember the path to get to the vfield. */ | ||||||
421 | gcc_assert (TREE_TYPE (member) == vtbl_ptr_type_node)((void)(!(((contains_struct_check ((member), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 421, __FUNCTION__))->typed.type) == cp_global_trees[CPTI_VTBL_PTR_TYPE ]) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 421, __FUNCTION__), 0 : 0)); | ||||||
422 | } | ||||||
423 | |||||||
424 | /* Value-initialization can produce multiple initializers for the | ||||||
425 | same field; use the last one. */ | ||||||
426 | if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member) | ||||||
427 | (*vec)->last().value = init; | ||||||
428 | else | ||||||
429 | CONSTRUCTOR_APPEND_ELT (*vec, member, init)do { constructor_elt _ce___ = {member, init}; vec_safe_push ( (*vec), _ce___); } while (0); | ||||||
430 | return true; | ||||||
431 | } | ||||||
432 | |||||||
433 | /* Subroutine of check_constexpr_ctor_body_1 and constexpr_fn_retval. | ||||||
434 | In C++11 mode checks that the TYPE_DECLs in the BIND_EXPR_VARS of a | ||||||
435 | BIND_EXPR conform to 7.1.5/3/4 on typedef and alias declarations. */ | ||||||
436 | |||||||
437 | static bool | ||||||
438 | check_constexpr_bind_expr_vars (tree t) | ||||||
439 | { | ||||||
440 | gcc_assert (TREE_CODE (t) == BIND_EXPR)((void)(!(((enum tree_code) (t)->base.code) == BIND_EXPR) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 440, __FUNCTION__), 0 : 0)); | ||||||
441 | |||||||
442 | for (tree var = BIND_EXPR_VARS (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 442, __FUNCTION__, (BIND_EXPR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 442, __FUNCTION__)))))); var; var = DECL_CHAIN (var)(((contains_struct_check (((contains_struct_check ((var), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 442, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 442, __FUNCTION__))->common.chain))) | ||||||
443 | if (TREE_CODE (var)((enum tree_code) (var)->base.code) == TYPE_DECL | ||||||
444 | && DECL_IMPLICIT_TYPEDEF_P (var)(((enum tree_code) (var)->base.code) == TYPE_DECL && ((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 444, __FUNCTION__))->decl_common.lang_flag_2)) | ||||||
445 | && !LAMBDA_TYPE_P (TREE_TYPE (var))(((enum tree_code) (((contains_struct_check ((var), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && ((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name) && (tree_code_type [(int) (((enum tree_code) (((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name))) && ((tree_check ((((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name) && (tree_code_type [(int) (((enum tree_code) (((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__))->type_common.name)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 445, __FUNCTION__, (IDENTIFIER_NODE)))->base.protected_flag ))) | ||||||
446 | return false; | ||||||
447 | return true; | ||||||
448 | } | ||||||
449 | |||||||
450 | /* Subroutine of check_constexpr_ctor_body. */ | ||||||
451 | |||||||
452 | static bool | ||||||
453 | check_constexpr_ctor_body_1 (tree last, tree list) | ||||||
454 | { | ||||||
455 | switch (TREE_CODE (list)((enum tree_code) (list)->base.code)) | ||||||
456 | { | ||||||
457 | case DECL_EXPR: | ||||||
458 | if (TREE_CODE (DECL_EXPR_DECL (list))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((tree_check ((list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 458, __FUNCTION__, (DECL_EXPR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 458, __FUNCTION__))))))->base.code) == USING_DECL | ||||||
459 | || TREE_CODE (DECL_EXPR_DECL (list))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((tree_check ((list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 459, __FUNCTION__, (DECL_EXPR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 459, __FUNCTION__))))))->base.code) == TYPE_DECL) | ||||||
460 | return true; | ||||||
461 | return false; | ||||||
462 | |||||||
463 | case CLEANUP_POINT_EXPR: | ||||||
464 | return check_constexpr_ctor_body (last, TREE_OPERAND (list, 0)(*((const_cast<tree*> (tree_operand_check ((list), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 464, __FUNCTION__))))), | ||||||
465 | /*complain=*/false); | ||||||
466 | |||||||
467 | case BIND_EXPR: | ||||||
468 | if (!check_constexpr_bind_expr_vars (list) | ||||||
469 | || !check_constexpr_ctor_body (last, BIND_EXPR_BODY (list)((*((const_cast<tree*> (tree_operand_check (((tree_check ((list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 469, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 469, __FUNCTION__)))))), | ||||||
470 | /*complain=*/false)) | ||||||
471 | return false; | ||||||
472 | return true; | ||||||
473 | |||||||
474 | case USING_STMT: | ||||||
475 | case STATIC_ASSERT: | ||||||
476 | case DEBUG_BEGIN_STMT: | ||||||
477 | return true; | ||||||
478 | |||||||
479 | default: | ||||||
480 | return false; | ||||||
481 | } | ||||||
482 | } | ||||||
483 | |||||||
484 | /* Make sure that there are no statements after LAST in the constructor | ||||||
485 | body represented by LIST. */ | ||||||
486 | |||||||
487 | bool | ||||||
488 | check_constexpr_ctor_body (tree last, tree list, bool complain) | ||||||
489 | { | ||||||
490 | /* C++14 doesn't require a constexpr ctor to have an empty body. */ | ||||||
491 | if (cxx_dialect >= cxx14) | ||||||
492 | return true; | ||||||
493 | |||||||
494 | bool ok = true; | ||||||
495 | if (TREE_CODE (list)((enum tree_code) (list)->base.code) == STATEMENT_LIST) | ||||||
496 | { | ||||||
497 | tree_stmt_iterator i = tsi_last (list); | ||||||
498 | for (; !tsi_end_p (i); tsi_prev (&i)) | ||||||
499 | { | ||||||
500 | tree t = tsi_stmt (i); | ||||||
501 | if (t == last) | ||||||
502 | break; | ||||||
503 | if (!check_constexpr_ctor_body_1 (last, t)) | ||||||
504 | { | ||||||
505 | ok = false; | ||||||
506 | break; | ||||||
507 | } | ||||||
508 | } | ||||||
509 | } | ||||||
510 | else if (list != last | ||||||
511 | && !check_constexpr_ctor_body_1 (last, list)) | ||||||
512 | ok = false; | ||||||
513 | if (!ok) | ||||||
514 | { | ||||||
515 | if (complain) | ||||||
516 | error ("%<constexpr%> constructor does not have empty body"); | ||||||
517 | DECL_DECLARED_CONSTEXPR_P (current_function_decl)((contains_struct_check (((tree_check2 (((((enum tree_code) ( current_function_decl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> (( ((tree_check ((current_function_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 517, __FUNCTION__, (TEMPLATE_DECL))))))))->result : current_function_decl )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 517, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 517, __FUNCTION__))->decl_common.lang_flag_8) = false; | ||||||
518 | } | ||||||
519 | return ok; | ||||||
520 | } | ||||||
521 | |||||||
522 | /* V is a vector of constructor elements built up for the base and member | ||||||
523 | initializers of a constructor for TYPE. They need to be in increasing | ||||||
524 | offset order, which they might not be yet if TYPE has a primary base | ||||||
525 | which is not first in the base-clause or a vptr and at least one base | ||||||
526 | all of which are non-primary. */ | ||||||
527 | |||||||
528 | static vec<constructor_elt, va_gc> * | ||||||
529 | sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v) | ||||||
530 | { | ||||||
531 | tree pri = CLASSTYPE_PRIMARY_BINFO (type)((((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 531, __FUNCTION__))->type_with_lang_specific.lang_specific ))->primary_base); | ||||||
532 | tree field_type; | ||||||
533 | unsigned i; | ||||||
534 | constructor_elt *ce; | ||||||
535 | |||||||
536 | if (pri) | ||||||
537 | field_type = BINFO_TYPE (pri)((contains_struct_check (((tree_check ((pri), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 537, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 537, __FUNCTION__))->typed.type); | ||||||
538 | else if (TYPE_CONTAINS_VPTR_P (type)((((tree_not_check2 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 538, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) || ((((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 538, __FUNCTION__))->type_with_lang_specific.lang_specific ))->vbases))) | ||||||
539 | field_type = vtbl_ptr_type_nodecp_global_trees[CPTI_VTBL_PTR_TYPE]; | ||||||
540 | else | ||||||
541 | return v; | ||||||
542 | |||||||
543 | /* Find the element for the primary base or vptr and move it to the | ||||||
544 | beginning of the vec. */ | ||||||
545 | for (i = 0; vec_safe_iterate (v, i, &ce); ++i) | ||||||
546 | if (TREE_TYPE (ce->index)((contains_struct_check ((ce->index), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 546, __FUNCTION__))->typed.type) == field_type) | ||||||
547 | break; | ||||||
548 | |||||||
549 | if (i > 0 && i < vec_safe_length (v)) | ||||||
550 | { | ||||||
551 | vec<constructor_elt, va_gc> &vref = *v; | ||||||
552 | constructor_elt elt = vref[i]; | ||||||
553 | for (; i > 0; --i) | ||||||
554 | vref[i] = vref[i-1]; | ||||||
555 | vref[0] = elt; | ||||||
556 | } | ||||||
557 | |||||||
558 | return v; | ||||||
559 | } | ||||||
560 | |||||||
561 | /* Build compile-time evalable representations of member-initializer list | ||||||
562 | for a constexpr constructor. */ | ||||||
563 | |||||||
564 | static tree | ||||||
565 | build_constexpr_constructor_member_initializers (tree type, tree body) | ||||||
566 | { | ||||||
567 | vec<constructor_elt, va_gc> *vec = NULLnullptr; | ||||||
568 | bool ok = true; | ||||||
569 | while (true) | ||||||
570 | switch (TREE_CODE (body)((enum tree_code) (body)->base.code)) | ||||||
571 | { | ||||||
572 | case MUST_NOT_THROW_EXPR: | ||||||
573 | case EH_SPEC_BLOCK: | ||||||
574 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 574, __FUNCTION__))))); | ||||||
575 | break; | ||||||
576 | |||||||
577 | case STATEMENT_LIST: | ||||||
578 | for (tree_stmt_iterator i = tsi_start (body); | ||||||
579 | !tsi_end_p (i); tsi_next (&i)) | ||||||
580 | { | ||||||
581 | body = tsi_stmt (i); | ||||||
582 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == BIND_EXPR) | ||||||
583 | break; | ||||||
584 | } | ||||||
585 | break; | ||||||
586 | |||||||
587 | case BIND_EXPR: | ||||||
588 | body = BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 588, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 588, __FUNCTION__)))))); | ||||||
589 | goto found; | ||||||
590 | |||||||
591 | default: | ||||||
592 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 592, __FUNCTION__)); | ||||||
593 | } | ||||||
594 | found: | ||||||
595 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == TRY_BLOCK) | ||||||
596 | { | ||||||
597 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 597, __FUNCTION__))))); | ||||||
598 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == BIND_EXPR) | ||||||
599 | body = BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 599, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 599, __FUNCTION__)))))); | ||||||
600 | } | ||||||
601 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == CLEANUP_POINT_EXPR) | ||||||
602 | { | ||||||
603 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 603, __FUNCTION__))))); | ||||||
604 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == EXPR_STMT) | ||||||
605 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 605, __FUNCTION__))))); | ||||||
606 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == INIT_EXPR | ||||||
607 | && (same_type_ignoring_top_level_qualifiers_p | ||||||
608 | (TREE_TYPE (TREE_OPERAND (body, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 608, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 608, __FUNCTION__))->typed.type), | ||||||
609 | current_class_typescope_chain->class_type))) | ||||||
610 | { | ||||||
611 | /* Trivial copy. */ | ||||||
612 | return TREE_OPERAND (body, 1)(*((const_cast<tree*> (tree_operand_check ((body), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 612, __FUNCTION__))))); | ||||||
613 | } | ||||||
614 | ok = build_data_member_initialization (body, &vec); | ||||||
615 | } | ||||||
616 | else if (TREE_CODE (body)((enum tree_code) (body)->base.code) == STATEMENT_LIST) | ||||||
617 | { | ||||||
618 | tree_stmt_iterator i; | ||||||
619 | for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i)) | ||||||
620 | { | ||||||
621 | ok = build_data_member_initialization (tsi_stmt (i), &vec); | ||||||
622 | if (!ok) | ||||||
623 | break; | ||||||
624 | } | ||||||
625 | } | ||||||
626 | else if (EXPR_P (body)((tree_code_type[(int) (((enum tree_code) (body)->base.code ))]) >= tcc_reference && (tree_code_type[(int) ((( enum tree_code) (body)->base.code))]) <= tcc_expression )) | ||||||
627 | ok = build_data_member_initialization (body, &vec); | ||||||
628 | else | ||||||
629 | gcc_assert (errorcount > 0)((void)(!((global_dc)->diagnostic_count[(int) (DK_ERROR)] > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 629, __FUNCTION__), 0 : 0)); | ||||||
630 | if (ok) | ||||||
631 | { | ||||||
632 | if (vec_safe_length (vec) > 0) | ||||||
633 | { | ||||||
634 | /* In a delegating constructor, return the target. */ | ||||||
635 | constructor_elt *ce = &(*vec)[0]; | ||||||
636 | if (ce->index == current_class_ptr(*((cfun + 0) && ((cfun + 0)->language) ? &((cfun + 0)->language)->x_current_class_ptr : &scope_chain ->x_current_class_ptr))) | ||||||
637 | { | ||||||
638 | body = ce->value; | ||||||
639 | vec_free (vec); | ||||||
640 | return body; | ||||||
641 | } | ||||||
642 | } | ||||||
643 | vec = sort_constexpr_mem_initializers (type, vec); | ||||||
644 | return build_constructor (type, vec); | ||||||
645 | } | ||||||
646 | else | ||||||
647 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
648 | } | ||||||
649 | |||||||
650 | /* We have an expression tree T that represents a call, either CALL_EXPR | ||||||
651 | or AGGR_INIT_EXPR. If the call is lexically to a named function, | ||||||
652 | retrun the _DECL for that function. */ | ||||||
653 | |||||||
654 | static tree | ||||||
655 | get_function_named_in_call (tree t) | ||||||
656 | { | ||||||
657 | tree fun = cp_get_callee (t); | ||||||
658 | if (fun && TREE_CODE (fun)((enum tree_code) (fun)->base.code) == ADDR_EXPR | ||||||
659 | && TREE_CODE (TREE_OPERAND (fun, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((fun), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 659, __FUNCTION__))))))->base.code) == FUNCTION_DECL) | ||||||
660 | fun = TREE_OPERAND (fun, 0)(*((const_cast<tree*> (tree_operand_check ((fun), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 660, __FUNCTION__))))); | ||||||
661 | return fun; | ||||||
662 | } | ||||||
663 | |||||||
664 | /* Subroutine of check_constexpr_fundef. BODY is the body of a function | ||||||
665 | declared to be constexpr, or a sub-statement thereof. Returns the | ||||||
666 | return value if suitable, error_mark_node for a statement not allowed in | ||||||
667 | a constexpr function, or NULL_TREE if no return value was found. */ | ||||||
668 | |||||||
669 | tree | ||||||
670 | constexpr_fn_retval (tree body) | ||||||
671 | { | ||||||
672 | switch (TREE_CODE (body)((enum tree_code) (body)->base.code)) | ||||||
673 | { | ||||||
674 | case STATEMENT_LIST: | ||||||
675 | { | ||||||
676 | tree_stmt_iterator i; | ||||||
677 | tree expr = NULL_TREE(tree) nullptr; | ||||||
678 | for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i)) | ||||||
679 | { | ||||||
680 | tree s = constexpr_fn_retval (tsi_stmt (i)); | ||||||
681 | if (s == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
682 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
683 | else if (s == NULL_TREE(tree) nullptr) | ||||||
684 | /* Keep iterating. */; | ||||||
685 | else if (expr) | ||||||
686 | /* Multiple return statements. */ | ||||||
687 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
688 | else | ||||||
689 | expr = s; | ||||||
690 | } | ||||||
691 | return expr; | ||||||
692 | } | ||||||
693 | |||||||
694 | case RETURN_EXPR: | ||||||
695 | return break_out_target_exprs (TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 695, __FUNCTION__)))))); | ||||||
696 | |||||||
697 | case DECL_EXPR: | ||||||
698 | { | ||||||
699 | tree decl = DECL_EXPR_DECL (body)(*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 699, __FUNCTION__, (DECL_EXPR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 699, __FUNCTION__))))); | ||||||
700 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == USING_DECL | ||||||
701 | /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */ | ||||||
702 | || DECL_ARTIFICIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 702, __FUNCTION__))->decl_common.artificial_flag)) | ||||||
703 | return NULL_TREE(tree) nullptr; | ||||||
704 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
705 | } | ||||||
706 | |||||||
707 | case CLEANUP_POINT_EXPR: | ||||||
708 | return constexpr_fn_retval (TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 708, __FUNCTION__)))))); | ||||||
709 | |||||||
710 | case BIND_EXPR: | ||||||
711 | if (!check_constexpr_bind_expr_vars (body)) | ||||||
712 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
713 | return constexpr_fn_retval (BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 713, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 713, __FUNCTION__))))))); | ||||||
714 | |||||||
715 | case USING_STMT: | ||||||
716 | case DEBUG_BEGIN_STMT: | ||||||
717 | return NULL_TREE(tree) nullptr; | ||||||
718 | |||||||
719 | case CALL_EXPR: | ||||||
720 | { | ||||||
721 | tree fun = get_function_named_in_call (body); | ||||||
722 | if (fun != NULL_TREE(tree) nullptr | ||||||
723 | && fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE)) | ||||||
724 | return NULL_TREE(tree) nullptr; | ||||||
725 | } | ||||||
726 | /* Fallthru. */ | ||||||
727 | |||||||
728 | default: | ||||||
729 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
730 | } | ||||||
731 | } | ||||||
732 | |||||||
733 | /* Subroutine of check_constexpr_fundef. BODY is the DECL_SAVED_TREE of | ||||||
734 | FUN; do the necessary transformations to turn it into a single expression | ||||||
735 | that we can store in the hash table. */ | ||||||
736 | |||||||
737 | static tree | ||||||
738 | massage_constexpr_body (tree fun, tree body) | ||||||
739 | { | ||||||
740 | if (DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 740, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 740, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
741 | body = build_constexpr_constructor_member_initializers | ||||||
742 | (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 742, __FUNCTION__))->decl_minimal.context), body); | ||||||
743 | else if (cxx_dialect < cxx14) | ||||||
744 | { | ||||||
745 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == EH_SPEC_BLOCK) | ||||||
746 | body = EH_SPEC_STMTS (body)(*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 746, __FUNCTION__, (EH_SPEC_BLOCK)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 746, __FUNCTION__))))); | ||||||
747 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == MUST_NOT_THROW_EXPR) | ||||||
748 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 748, __FUNCTION__))))); | ||||||
749 | body = constexpr_fn_retval (body); | ||||||
750 | } | ||||||
751 | return body; | ||||||
752 | } | ||||||
753 | |||||||
754 | /* CTYPE is a type constructed from BODY. Return true if some | ||||||
755 | bases/fields are uninitialized, and complain if COMPLAIN. */ | ||||||
756 | |||||||
757 | static bool | ||||||
758 | cx_check_missing_mem_inits (tree ctype, tree body, bool complain) | ||||||
759 | { | ||||||
760 | /* We allow uninitialized bases/fields in C++20. */ | ||||||
761 | if (cxx_dialect >= cxx20) | ||||||
762 | return false; | ||||||
763 | |||||||
764 | unsigned nelts = 0; | ||||||
765 | |||||||
766 | if (body) | ||||||
767 | { | ||||||
768 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) != CONSTRUCTOR) | ||||||
769 | return false; | ||||||
770 | nelts = CONSTRUCTOR_NELTS (body)(vec_safe_length (((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 770, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))); | ||||||
771 | } | ||||||
772 | tree field = TYPE_FIELDS (ctype)((tree_check3 ((ctype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 772, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); | ||||||
773 | |||||||
774 | if (TREE_CODE (ctype)((enum tree_code) (ctype)->base.code) == UNION_TYPE) | ||||||
775 | { | ||||||
776 | if (nelts == 0 && next_initializable_field (field)) | ||||||
777 | { | ||||||
778 | if (complain) | ||||||
779 | error ("%<constexpr%> constructor for union %qT must " | ||||||
780 | "initialize exactly one non-static data member", ctype); | ||||||
781 | return true; | ||||||
782 | } | ||||||
783 | return false; | ||||||
784 | } | ||||||
785 | |||||||
786 | /* Iterate over the CONSTRUCTOR, checking any missing fields don't | ||||||
787 | need an explicit initialization. */ | ||||||
788 | bool bad = false; | ||||||
789 | for (unsigned i = 0; i <= nelts; ++i) | ||||||
790 | { | ||||||
791 | tree index = NULL_TREE(tree) nullptr; | ||||||
792 | if (i < nelts) | ||||||
793 | { | ||||||
794 | index = CONSTRUCTOR_ELT (body, i)(&(*((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 794, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[i ])->index; | ||||||
795 | /* Skip base and vtable inits. */ | ||||||
796 | if (TREE_CODE (index)((enum tree_code) (index)->base.code) != FIELD_DECL | ||||||
797 | || DECL_ARTIFICIAL (index)((contains_struct_check ((index), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 797, __FUNCTION__))->decl_common.artificial_flag)) | ||||||
798 | continue; | ||||||
799 | } | ||||||
800 | |||||||
801 | for (; field != index; field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 801, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 801, __FUNCTION__))->common.chain))) | ||||||
802 | { | ||||||
803 | tree ftype; | ||||||
804 | if (TREE_CODE (field)((enum tree_code) (field)->base.code) != FIELD_DECL) | ||||||
805 | continue; | ||||||
806 | if (DECL_UNNAMED_BIT_FIELD (field)((((contains_struct_check (((tree_check ((field), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 806, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 806, __FUNCTION__))->decl_common.lang_flag_4) == 1) && !((contains_struct_check ((field), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 806, __FUNCTION__))->decl_minimal.name))) | ||||||
807 | continue; | ||||||
808 | if (DECL_ARTIFICIAL (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 808, __FUNCTION__))->decl_common.artificial_flag)) | ||||||
809 | continue; | ||||||
810 | if (ANON_AGGR_TYPE_P (TREE_TYPE (field))((((((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 810, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 810, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((field ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 810, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 810, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((field), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 810, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 810, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) | ||||||
811 | { | ||||||
812 | /* Recurse to check the anonymous aggregate member. */ | ||||||
813 | bad |= cx_check_missing_mem_inits | ||||||
814 | (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 814, __FUNCTION__))->typed.type), NULL_TREE(tree) nullptr, complain); | ||||||
815 | if (bad && !complain) | ||||||
816 | return true; | ||||||
817 | continue; | ||||||
818 | } | ||||||
819 | ftype = TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 819, __FUNCTION__))->typed.type); | ||||||
820 | if (!ftype || !TYPE_P (ftype)(tree_code_type[(int) (((enum tree_code) (ftype)->base.code ))] == tcc_type) || !COMPLETE_TYPE_P (ftype)(((tree_class_check ((ftype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 820, __FUNCTION__))->type_common.size) != (tree) nullptr )) | ||||||
821 | /* A flexible array can't be intialized here, so don't complain | ||||||
822 | that it isn't. */ | ||||||
823 | continue; | ||||||
824 | if (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 824, __FUNCTION__))->decl_common.size) && integer_zerop (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 824, __FUNCTION__))->decl_common.size))) | ||||||
825 | /* An empty field doesn't need an initializer. */ | ||||||
826 | continue; | ||||||
827 | ftype = strip_array_types (ftype); | ||||||
828 | if (type_has_constexpr_default_constructor (ftype)) | ||||||
829 | { | ||||||
830 | /* It's OK to skip a member with a trivial constexpr ctor. | ||||||
831 | A constexpr ctor that isn't trivial should have been | ||||||
832 | added in by now. */ | ||||||
833 | gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype)((void)(!(!((((tree_class_check ((ftype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 833, __FUNCTION__))->type_with_lang_specific.lang_specific ))->has_complex_dflt) || (global_dc)->diagnostic_count[ (int) (DK_ERROR)] != 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 834, __FUNCTION__), 0 : 0)) | ||||||
834 | || errorcount != 0)((void)(!(!((((tree_class_check ((ftype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 833, __FUNCTION__))->type_with_lang_specific.lang_specific ))->has_complex_dflt) || (global_dc)->diagnostic_count[ (int) (DK_ERROR)] != 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 834, __FUNCTION__), 0 : 0)); | ||||||
835 | continue; | ||||||
836 | } | ||||||
837 | if (!complain) | ||||||
838 | return true; | ||||||
839 | auto_diagnostic_group d; | ||||||
840 | error ("member %qD must be initialized by mem-initializer " | ||||||
841 | "in %<constexpr%> constructor", field); | ||||||
842 | inform (DECL_SOURCE_LOCATION (field)((contains_struct_check ((field), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 842, __FUNCTION__))->decl_minimal.locus), "declared here"); | ||||||
843 | bad = true; | ||||||
844 | } | ||||||
845 | if (field == NULL_TREE(tree) nullptr) | ||||||
846 | break; | ||||||
847 | |||||||
848 | if (ANON_AGGR_TYPE_P (TREE_TYPE (index))((((((enum tree_code) (((contains_struct_check ((index), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 848, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((index), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 848, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((index ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 848, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 848, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((index), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 848, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 848, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) | ||||||
849 | { | ||||||
850 | /* Check the anonymous aggregate initializer is valid. */ | ||||||
851 | bad |= cx_check_missing_mem_inits | ||||||
852 | (TREE_TYPE (index)((contains_struct_check ((index), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 852, __FUNCTION__))->typed.type), CONSTRUCTOR_ELT (body, i)(&(*((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 852, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[i ])->value, complain); | ||||||
853 | if (bad && !complain) | ||||||
854 | return true; | ||||||
855 | } | ||||||
856 | field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 856, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 856, __FUNCTION__))->common.chain)); | ||||||
857 | } | ||||||
858 | |||||||
859 | return bad; | ||||||
860 | } | ||||||
861 | |||||||
862 | /* We are processing the definition of the constexpr function FUN. | ||||||
863 | Check that its body fulfills the apropriate requirements and | ||||||
864 | enter it in the constexpr function definition table. */ | ||||||
865 | |||||||
866 | void | ||||||
867 | maybe_save_constexpr_fundef (tree fun) | ||||||
868 | { | ||||||
869 | if (processing_template_declscope_chain->x_processing_template_decl | ||||||
870 | || !DECL_DECLARED_CONSTEXPR_P (fun)((contains_struct_check (((tree_check2 (((((enum tree_code) ( fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 870, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 870, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 870, __FUNCTION__))->decl_common.lang_flag_8) | ||||||
871 | || cp_function_chain((cfun + 0)->language)->invalid_constexpr | ||||||
872 | || DECL_CLONED_FUNCTION_P (fun)(((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__))->decl_minimal.name) && ((!(( tree_not_check2 (((tree_check ((((contains_struct_check ((fun ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & ((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1)) && !((((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_CTOR_IDENTIFIER]) || (((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 872, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_DTOR_IDENTIFIER])))) | ||||||
873 | return; | ||||||
874 | |||||||
875 | if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun)((((((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info) && !(((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) || (__extension__ ({ struct lang_decl *lt = ( (contains_struct_check (((((enum tree_code) (fun)->base.code ) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast <union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 875, __FUNCTION__); <->u.fn; })->defaulted_p)))) | ||||||
876 | return; | ||||||
877 | |||||||
878 | tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun)((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 878, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree )); | ||||||
879 | if (massaged == NULL_TREE(tree) nullptr || massaged == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
880 | { | ||||||
881 | if (!DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 881, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 881, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
882 | error ("body of %<constexpr%> function %qD not a return-statement", | ||||||
883 | fun); | ||||||
884 | return; | ||||||
885 | } | ||||||
886 | |||||||
887 | bool potential = potential_rvalue_constant_expression (massaged); | ||||||
888 | if (!potential && !DECL_GENERATED_P (fun)((((((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info) && !(((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) || (__extension__ ({ struct lang_decl *lt = ( (contains_struct_check (((((enum tree_code) (fun)->base.code ) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast <union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 888, __FUNCTION__); <->u.fn; })->defaulted_p))) | ||||||
889 | require_potential_rvalue_constant_expression (massaged); | ||||||
890 | |||||||
891 | if (DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 891, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 891, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) | ||||||
892 | && cx_check_missing_mem_inits (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 892, __FUNCTION__))->decl_minimal.context), | ||||||
893 | massaged, !DECL_GENERATED_P (fun)((((((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info) && !(((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) || (__extension__ ({ struct lang_decl *lt = ( (contains_struct_check (((((enum tree_code) (fun)->base.code ) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast <union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 893, __FUNCTION__); <->u.fn; })->defaulted_p)))) | ||||||
894 | potential = false; | ||||||
895 | |||||||
896 | if (!potential && !DECL_GENERATED_P (fun)((((((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info) && !(((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) || (__extension__ ({ struct lang_decl *lt = ( (contains_struct_check (((((enum tree_code) (fun)->base.code ) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast <union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 896, __FUNCTION__); <->u.fn; })->defaulted_p))) | ||||||
897 | return; | ||||||
898 | |||||||
899 | constexpr_fundef entry = {fun, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr}; | ||||||
900 | bool clear_ctx = false; | ||||||
901 | if (DECL_RESULT (fun)((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 901, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ) && DECL_CONTEXT (DECL_RESULT (fun))((contains_struct_check ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 901, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 901, __FUNCTION__))->decl_minimal.context) == NULL_TREE(tree) nullptr) | ||||||
902 | { | ||||||
903 | clear_ctx = true; | ||||||
904 | DECL_CONTEXT (DECL_RESULT (fun))((contains_struct_check ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 904, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 904, __FUNCTION__))->decl_minimal.context) = fun; | ||||||
905 | } | ||||||
906 | tree saved_fn = current_function_decl; | ||||||
907 | current_function_decl = fun; | ||||||
908 | entry.body = copy_fn (entry.decl, entry.parms, entry.result); | ||||||
909 | current_function_decl = saved_fn; | ||||||
910 | if (clear_ctx) | ||||||
911 | DECL_CONTEXT (DECL_RESULT (entry.decl))((contains_struct_check ((((tree_check ((entry.decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 911, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 911, __FUNCTION__))->decl_minimal.context) = NULL_TREE(tree) nullptr; | ||||||
912 | if (!potential) | ||||||
913 | /* For a template instantiation, we want to remember the pre-generic body | ||||||
914 | for explain_invalid_constexpr_fn, but do tell cxx_eval_call_expression | ||||||
915 | that it doesn't need to bother trying to expand the function. */ | ||||||
916 | entry.result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
917 | |||||||
918 | register_constexpr_fundef (entry); | ||||||
919 | } | ||||||
920 | |||||||
921 | /* BODY is a validated and massaged definition of a constexpr | ||||||
922 | function. Register it in the hash table. */ | ||||||
923 | |||||||
924 | void | ||||||
925 | register_constexpr_fundef (const constexpr_fundef &value) | ||||||
926 | { | ||||||
927 | /* Create the constexpr function table if necessary. */ | ||||||
928 | if (constexpr_fundef_table == NULLnullptr) | ||||||
929 | constexpr_fundef_table | ||||||
930 | = hash_table<constexpr_fundef_hasher>::create_ggc (101); | ||||||
931 | |||||||
932 | constexpr_fundef **slot = constexpr_fundef_table->find_slot | ||||||
933 | (const_cast<constexpr_fundef *> (&value), INSERT); | ||||||
934 | |||||||
935 | gcc_assert (*slot == NULL)((void)(!(*slot == nullptr) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 935, __FUNCTION__), 0 : 0)); | ||||||
936 | *slot = ggc_alloc<constexpr_fundef> (); | ||||||
937 | **slot = value; | ||||||
938 | } | ||||||
939 | |||||||
940 | /* FUN is a non-constexpr function called in a context that requires a | ||||||
941 | constant expression. If it comes from a constexpr template, explain why | ||||||
942 | the instantiation isn't constexpr. */ | ||||||
943 | |||||||
944 | void | ||||||
945 | explain_invalid_constexpr_fn (tree fun) | ||||||
946 | { | ||||||
947 | static hash_set<tree> *diagnosed; | ||||||
948 | tree body; | ||||||
949 | location_t save_loc; | ||||||
950 | /* Only diagnose defaulted functions, lambdas, or instantiations. */ | ||||||
951 | if (!DECL_DEFAULTED_FN (fun)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 951, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 951, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 951, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 951, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 951, __FUNCTION__); <->u.fn; })->defaulted_p) | ||||||
952 | && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))(((enum tree_code) ((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]))->base.code) == RECORD_TYPE && (((( tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name) && (tree_code_type [(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name))) && ((tree_check ((((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name) && (tree_code_type [(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__))->type_common.name)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 952, __FUNCTION__, (IDENTIFIER_NODE)))->base.protected_flag )) | ||||||
953 | && !is_instantiation_of_constexpr (fun)) | ||||||
954 | { | ||||||
955 | inform (DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 955, __FUNCTION__))->decl_minimal.locus), "%qD declared here", fun); | ||||||
956 | return; | ||||||
957 | } | ||||||
958 | if (diagnosed == NULLnullptr) | ||||||
959 | diagnosed = new hash_set<tree>; | ||||||
960 | if (diagnosed->add (fun)) | ||||||
961 | /* Already explained. */ | ||||||
962 | return; | ||||||
963 | |||||||
964 | save_loc = input_location; | ||||||
965 | if (!lambda_static_thunk_p (fun)) | ||||||
966 | { | ||||||
967 | /* Diagnostics should completely ignore the static thunk, so leave | ||||||
968 | input_location set to our caller's location. */ | ||||||
969 | input_location = DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 969, __FUNCTION__))->decl_minimal.locus); | ||||||
970 | inform (input_location, | ||||||
971 | "%qD is not usable as a %<constexpr%> function because:", fun); | ||||||
972 | } | ||||||
973 | /* First check the declaration. */ | ||||||
974 | if (is_valid_constexpr_fn (fun, true)) | ||||||
975 | { | ||||||
976 | /* Then if it's OK, the body. */ | ||||||
977 | if (!DECL_DECLARED_CONSTEXPR_P (fun)((contains_struct_check (((tree_check2 (((((enum tree_code) ( fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 977, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 977, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 977, __FUNCTION__))->decl_common.lang_flag_8) | ||||||
978 | && DECL_DEFAULTED_FN (fun)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 978, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 978, __FUNCTION__))->decl_common.lang_specific); if (!(( (enum tree_code) (fun)->base.code) == FUNCTION_DECL || ((( enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 978, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 978, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 978, __FUNCTION__); <->u.fn; })->defaulted_p)) | ||||||
979 | explain_implicit_non_constexpr (fun); | ||||||
980 | else | ||||||
981 | { | ||||||
982 | if (constexpr_fundef *fd = retrieve_constexpr_fundef (fun)) | ||||||
983 | body = fd->body; | ||||||
984 | else | ||||||
985 | body = DECL_SAVED_TREE (fun)((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 985, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ); | ||||||
986 | body = massage_constexpr_body (fun, body); | ||||||
987 | require_potential_rvalue_constant_expression (body); | ||||||
988 | if (DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 988, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 988, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
989 | cx_check_missing_mem_inits (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 989, __FUNCTION__))->decl_minimal.context), body, true); | ||||||
990 | } | ||||||
991 | } | ||||||
992 | input_location = save_loc; | ||||||
993 | } | ||||||
994 | |||||||
995 | /* Objects of this type represent calls to constexpr functions | ||||||
996 | along with the bindings of parameters to their arguments, for | ||||||
997 | the purpose of compile time evaluation. */ | ||||||
998 | |||||||
999 | struct GTY((for_user)) constexpr_call { | ||||||
1000 | /* Description of the constexpr function definition. */ | ||||||
1001 | constexpr_fundef *fundef; | ||||||
1002 | /* Parameter bindings environment. A TREE_VEC of arguments. */ | ||||||
1003 | tree bindings; | ||||||
1004 | /* Result of the call. | ||||||
1005 | NULL means the call is being evaluated. | ||||||
1006 | error_mark_node means that the evaluation was erroneous; | ||||||
1007 | otherwise, the actuall value of the call. */ | ||||||
1008 | tree result; | ||||||
1009 | /* The hash of this call; we remember it here to avoid having to | ||||||
1010 | recalculate it when expanding the hash table. */ | ||||||
1011 | hashval_t hash; | ||||||
1012 | /* Whether __builtin_is_constant_evaluated() should evaluate to true. */ | ||||||
1013 | bool manifestly_const_eval; | ||||||
1014 | }; | ||||||
1015 | |||||||
1016 | struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call> | ||||||
1017 | { | ||||||
1018 | static hashval_t hash (constexpr_call *); | ||||||
1019 | static bool equal (constexpr_call *, constexpr_call *); | ||||||
1020 | }; | ||||||
1021 | |||||||
1022 | enum constexpr_switch_state { | ||||||
1023 | /* Used when processing a switch for the first time by cxx_eval_switch_expr | ||||||
1024 | and default: label for that switch has not been seen yet. */ | ||||||
1025 | css_default_not_seen, | ||||||
1026 | /* Used when processing a switch for the first time by cxx_eval_switch_expr | ||||||
1027 | and default: label for that switch has been seen already. */ | ||||||
1028 | css_default_seen, | ||||||
1029 | /* Used when processing a switch for the second time by | ||||||
1030 | cxx_eval_switch_expr, where default: label should match. */ | ||||||
1031 | css_default_processing | ||||||
1032 | }; | ||||||
1033 | |||||||
1034 | /* The constexpr expansion context part which needs one instance per | ||||||
1035 | cxx_eval_outermost_constant_expr invocation. VALUES is a map of values of | ||||||
1036 | variables initialized within the expression. */ | ||||||
1037 | |||||||
1038 | struct constexpr_global_ctx { | ||||||
1039 | /* Values for any temporaries or local variables within the | ||||||
1040 | constant-expression. */ | ||||||
1041 | hash_map<tree,tree> values; | ||||||
1042 | /* Number of cxx_eval_constant_expression calls (except skipped ones, | ||||||
1043 | on simple constants or location wrappers) encountered during current | ||||||
1044 | cxx_eval_outermost_constant_expr call. */ | ||||||
1045 | HOST_WIDE_INTlong constexpr_ops_count; | ||||||
1046 | /* Heap VAR_DECLs created during the evaluation of the outermost constant | ||||||
1047 | expression. */ | ||||||
1048 | auto_vec<tree, 16> heap_vars; | ||||||
1049 | /* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */ | ||||||
1050 | vec<tree> *cleanups; | ||||||
1051 | /* Number of heap VAR_DECL deallocations. */ | ||||||
1052 | unsigned heap_dealloc_count; | ||||||
1053 | /* Constructor. */ | ||||||
1054 | constexpr_global_ctx () | ||||||
1055 | : constexpr_ops_count (0), cleanups (NULLnullptr), heap_dealloc_count (0) {} | ||||||
1056 | }; | ||||||
1057 | |||||||
1058 | /* The constexpr expansion context. CALL is the current function | ||||||
1059 | expansion, CTOR is the current aggregate initializer, OBJECT is the | ||||||
1060 | object being initialized by CTOR, either a VAR_DECL or a _REF. */ | ||||||
1061 | |||||||
1062 | struct constexpr_ctx { | ||||||
1063 | /* The part of the context that needs to be unique to the whole | ||||||
1064 | cxx_eval_outermost_constant_expr invocation. */ | ||||||
1065 | constexpr_global_ctx *global; | ||||||
1066 | /* The innermost call we're evaluating. */ | ||||||
1067 | constexpr_call *call; | ||||||
1068 | /* SAVE_EXPRs and TARGET_EXPR_SLOT vars of TARGET_EXPRs that we've seen | ||||||
1069 | within the current LOOP_EXPR. NULL if we aren't inside a loop. */ | ||||||
1070 | vec<tree> *save_exprs; | ||||||
1071 | /* The CONSTRUCTOR we're currently building up for an aggregate | ||||||
1072 | initializer. */ | ||||||
1073 | tree ctor; | ||||||
1074 | /* The object we're building the CONSTRUCTOR for. */ | ||||||
1075 | tree object; | ||||||
1076 | /* If inside SWITCH_EXPR. */ | ||||||
1077 | constexpr_switch_state *css_state; | ||||||
1078 | /* The aggregate initialization context inside which this one is nested. This | ||||||
1079 | is used by lookup_placeholder to resolve PLACEHOLDER_EXPRs. */ | ||||||
1080 | const constexpr_ctx *parent; | ||||||
1081 | |||||||
1082 | /* Whether we should error on a non-constant expression or fail quietly. | ||||||
1083 | This flag needs to be here, but some of the others could move to global | ||||||
1084 | if they get larger than a word. */ | ||||||
1085 | bool quiet; | ||||||
1086 | /* Whether we are strictly conforming to constant expression rules or | ||||||
1087 | trying harder to get a constant value. */ | ||||||
1088 | bool strict; | ||||||
1089 | /* Whether __builtin_is_constant_evaluated () should be true. */ | ||||||
1090 | bool manifestly_const_eval; | ||||||
1091 | }; | ||||||
1092 | |||||||
1093 | /* This internal flag controls whether we should avoid doing anything during | ||||||
1094 | constexpr evaluation that would cause extra DECL_UID generation, such as | ||||||
1095 | template instantiation and function body copying. */ | ||||||
1096 | |||||||
1097 | static bool uid_sensitive_constexpr_evaluation_value; | ||||||
1098 | |||||||
1099 | /* An internal counter that keeps track of the number of times | ||||||
1100 | uid_sensitive_constexpr_evaluation_p returned true. */ | ||||||
1101 | |||||||
1102 | static unsigned uid_sensitive_constexpr_evaluation_true_counter; | ||||||
1103 | |||||||
1104 | /* The accessor for uid_sensitive_constexpr_evaluation_value which also | ||||||
1105 | increments the corresponding counter. */ | ||||||
1106 | |||||||
1107 | static bool | ||||||
1108 | uid_sensitive_constexpr_evaluation_p () | ||||||
1109 | { | ||||||
1110 | if (uid_sensitive_constexpr_evaluation_value) | ||||||
1111 | { | ||||||
1112 | ++uid_sensitive_constexpr_evaluation_true_counter; | ||||||
1113 | return true; | ||||||
1114 | } | ||||||
1115 | else | ||||||
1116 | return false; | ||||||
1117 | } | ||||||
1118 | |||||||
1119 | /* The default constructor for uid_sensitive_constexpr_evaluation_sentinel | ||||||
1120 | enables the internal flag for uid_sensitive_constexpr_evaluation_p | ||||||
1121 | during the lifetime of the sentinel object. Upon its destruction, the | ||||||
1122 | previous value of uid_sensitive_constexpr_evaluation_p is restored. */ | ||||||
1123 | |||||||
1124 | uid_sensitive_constexpr_evaluation_sentinel | ||||||
1125 | ::uid_sensitive_constexpr_evaluation_sentinel () | ||||||
1126 | : ovr (uid_sensitive_constexpr_evaluation_value, true) | ||||||
1127 | { | ||||||
1128 | } | ||||||
1129 | |||||||
1130 | /* The default constructor for uid_sensitive_constexpr_evaluation_checker | ||||||
1131 | records the current number of times that uid_sensitive_constexpr_evaluation_p | ||||||
1132 | has been called and returned true. */ | ||||||
1133 | |||||||
1134 | uid_sensitive_constexpr_evaluation_checker | ||||||
1135 | ::uid_sensitive_constexpr_evaluation_checker () | ||||||
1136 | : saved_counter (uid_sensitive_constexpr_evaluation_true_counter) | ||||||
1137 | { | ||||||
1138 | } | ||||||
1139 | |||||||
1140 | /* Returns true iff uid_sensitive_constexpr_evaluation_p is true, and | ||||||
1141 | some constexpr evaluation was restricted due to u_s_c_e_p being called | ||||||
1142 | and returning true during the lifetime of this checker object. */ | ||||||
1143 | |||||||
1144 | bool | ||||||
1145 | uid_sensitive_constexpr_evaluation_checker::evaluation_restricted_p () const | ||||||
1146 | { | ||||||
1147 | return (uid_sensitive_constexpr_evaluation_value | ||||||
1148 | && saved_counter != uid_sensitive_constexpr_evaluation_true_counter); | ||||||
1149 | } | ||||||
1150 | |||||||
1151 | |||||||
1152 | /* A table of all constexpr calls that have been evaluated by the | ||||||
1153 | compiler in this translation unit. */ | ||||||
1154 | |||||||
1155 | static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table; | ||||||
1156 | |||||||
1157 | static tree cxx_eval_constant_expression (const constexpr_ctx *, tree, | ||||||
1158 | bool, bool *, bool *, tree * = NULLnullptr); | ||||||
1159 | |||||||
1160 | /* Compute a hash value for a constexpr call representation. */ | ||||||
1161 | |||||||
1162 | inline hashval_t | ||||||
1163 | constexpr_call_hasher::hash (constexpr_call *info) | ||||||
1164 | { | ||||||
1165 | return info->hash; | ||||||
1166 | } | ||||||
1167 | |||||||
1168 | /* Return true if the objects pointed to by P and Q represent calls | ||||||
1169 | to the same constexpr function with the same arguments. | ||||||
1170 | Otherwise, return false. */ | ||||||
1171 | |||||||
1172 | bool | ||||||
1173 | constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs) | ||||||
1174 | { | ||||||
1175 | if (lhs == rhs) | ||||||
1176 | return true; | ||||||
1177 | if (lhs->hash != rhs->hash) | ||||||
1178 | return false; | ||||||
1179 | if (lhs->manifestly_const_eval != rhs->manifestly_const_eval) | ||||||
1180 | return false; | ||||||
1181 | if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef)) | ||||||
1182 | return false; | ||||||
1183 | return cp_tree_equal (lhs->bindings, rhs->bindings); | ||||||
1184 | } | ||||||
1185 | |||||||
1186 | /* Initialize the constexpr call table, if needed. */ | ||||||
1187 | |||||||
1188 | static void | ||||||
1189 | maybe_initialize_constexpr_call_table (void) | ||||||
1190 | { | ||||||
1191 | if (constexpr_call_table == NULLnullptr) | ||||||
1192 | constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101); | ||||||
1193 | } | ||||||
1194 | |||||||
1195 | /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when | ||||||
1196 | a function happens to get called recursively, we unshare the callee | ||||||
1197 | function's body and evaluate this unshared copy instead of evaluating the | ||||||
1198 | original body. | ||||||
1199 | |||||||
1200 | FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function | ||||||
1201 | copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map | ||||||
1202 | that's keyed off of the original FUNCTION_DECL and whose value is a | ||||||
1203 | TREE_LIST of this function's unused copies awaiting reuse. | ||||||
1204 | |||||||
1205 | This is not GC-deletable to avoid GC affecting UID generation. */ | ||||||
1206 | |||||||
1207 | static GTY(()) decl_tree_map *fundef_copies_table; | ||||||
1208 | |||||||
1209 | /* Reuse a copy or create a new unshared copy of the function FUN. | ||||||
1210 | Return this copy. We use a TREE_LIST whose PURPOSE is body, VALUE | ||||||
1211 | is parms, TYPE is result. */ | ||||||
1212 | |||||||
1213 | static tree | ||||||
1214 | get_fundef_copy (constexpr_fundef *fundef) | ||||||
1215 | { | ||||||
1216 | tree copy; | ||||||
1217 | bool existed; | ||||||
1218 | tree *slot = &(hash_map_safe_get_or_insert<hm_ggc> | ||||||
1219 | (fundef_copies_table, fundef->decl, &existed, 127)); | ||||||
1220 | |||||||
1221 | if (!existed) | ||||||
1222 | { | ||||||
1223 | /* There is no cached function available, or in use. We can use | ||||||
1224 | the function directly. That the slot is now created records | ||||||
1225 | that this function is now in use. */ | ||||||
1226 | copy = build_tree_list (fundef->body, fundef->parms); | ||||||
1227 | TREE_TYPE (copy)((contains_struct_check ((copy), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1227, __FUNCTION__))->typed.type) = fundef->result; | ||||||
1228 | } | ||||||
1229 | else if (*slot == NULL_TREE(tree) nullptr) | ||||||
1230 | { | ||||||
1231 | if (uid_sensitive_constexpr_evaluation_p ()) | ||||||
1232 | return NULL_TREE(tree) nullptr; | ||||||
1233 | |||||||
1234 | /* We've already used the function itself, so make a copy. */ | ||||||
1235 | copy = build_tree_list (NULLnullptr, NULLnullptr); | ||||||
1236 | tree saved_body = DECL_SAVED_TREE (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1236, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ); | ||||||
1237 | tree saved_parms = DECL_ARGUMENTS (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1237, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ); | ||||||
1238 | tree saved_result = DECL_RESULT (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1238, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ); | ||||||
1239 | tree saved_fn = current_function_decl; | ||||||
1240 | DECL_SAVED_TREE (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1240, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ) = fundef->body; | ||||||
1241 | DECL_ARGUMENTS (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1241, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ) = fundef->parms; | ||||||
1242 | DECL_RESULT (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1242, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ) = fundef->result; | ||||||
1243 | current_function_decl = fundef->decl; | ||||||
1244 | TREE_PURPOSE (copy)((tree_check ((copy), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1244, __FUNCTION__, (TREE_LIST)))->list.purpose) = copy_fn (fundef->decl, TREE_VALUE (copy)((tree_check ((copy), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1244, __FUNCTION__, (TREE_LIST)))->list.value), | ||||||
1245 | TREE_TYPE (copy)((contains_struct_check ((copy), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1245, __FUNCTION__))->typed.type)); | ||||||
1246 | current_function_decl = saved_fn; | ||||||
1247 | DECL_RESULT (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1247, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ) = saved_result; | ||||||
1248 | DECL_ARGUMENTS (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1248, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ) = saved_parms; | ||||||
1249 | DECL_SAVED_TREE (fundef->decl)((tree_check ((fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1249, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ) = saved_body; | ||||||
1250 | } | ||||||
1251 | else | ||||||
1252 | { | ||||||
1253 | /* We have a cached function available. */ | ||||||
1254 | copy = *slot; | ||||||
1255 | *slot = TREE_CHAIN (copy)((contains_struct_check ((copy), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1255, __FUNCTION__))->common.chain); | ||||||
1256 | } | ||||||
1257 | |||||||
1258 | return copy; | ||||||
1259 | } | ||||||
1260 | |||||||
1261 | /* Save the copy COPY of function FUN for later reuse by | ||||||
1262 | get_fundef_copy(). By construction, there will always be an entry | ||||||
1263 | to find. */ | ||||||
1264 | |||||||
1265 | static void | ||||||
1266 | save_fundef_copy (tree fun, tree copy) | ||||||
1267 | { | ||||||
1268 | tree *slot = fundef_copies_table->get (fun); | ||||||
1269 | TREE_CHAIN (copy)((contains_struct_check ((copy), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1269, __FUNCTION__))->common.chain) = *slot; | ||||||
1270 | *slot = copy; | ||||||
1271 | } | ||||||
1272 | |||||||
1273 | /* We have an expression tree T that represents a call, either CALL_EXPR | ||||||
1274 | or AGGR_INIT_EXPR. Return the Nth argument. */ | ||||||
1275 | |||||||
1276 | static inline tree | ||||||
1277 | get_nth_callarg (tree t, int n) | ||||||
1278 | { | ||||||
1279 | switch (TREE_CODE (t)((enum tree_code) (t)->base.code)) | ||||||
1280 | { | ||||||
1281 | case CALL_EXPR: | ||||||
1282 | return CALL_EXPR_ARG (t, n)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1282, __FUNCTION__, (CALL_EXPR)))), ((n) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1282, __FUNCTION__))))); | ||||||
1283 | |||||||
1284 | case AGGR_INIT_EXPR: | ||||||
1285 | return AGGR_INIT_EXPR_ARG (t, n)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1285, __FUNCTION__, (AGGR_INIT_EXPR)))), ((n) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1285, __FUNCTION__))))); | ||||||
1286 | |||||||
1287 | default: | ||||||
1288 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1288, __FUNCTION__)); | ||||||
1289 | return NULLnullptr; | ||||||
1290 | } | ||||||
1291 | } | ||||||
1292 | |||||||
1293 | /* Attempt to evaluate T which represents a call to a builtin function. | ||||||
1294 | We assume here that all builtin functions evaluate to scalar types | ||||||
1295 | represented by _CST nodes. */ | ||||||
1296 | |||||||
1297 | static tree | ||||||
1298 | cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, | ||||||
1299 | bool lval, | ||||||
1300 | bool *non_constant_p, bool *overflow_p) | ||||||
1301 | { | ||||||
1302 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1302, __FUNCTION__))->exp.operands[0]), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1302, __FUNCTION__)))) - 3); | ||||||
1303 | tree *args = (tree *) alloca (nargs * sizeof (tree))__builtin_alloca(nargs * sizeof (tree)); | ||||||
1304 | tree new_call; | ||||||
1305 | int i; | ||||||
1306 | |||||||
1307 | /* Don't fold __builtin_constant_p within a constexpr function. */ | ||||||
1308 | bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun)(((enum tree_code) (fun)->base.code) == FUNCTION_DECL && ((built_in_class) (tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1308, __FUNCTION__, (FUNCTION_DECL)))->function_decl.built_in_class ) == BUILT_IN_NORMAL && DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P ); | ||||||
1309 | |||||||
1310 | /* If we aren't requiring a constant expression, defer __builtin_constant_p | ||||||
1311 | in a constexpr function until we have values for the parameters. */ | ||||||
1312 | if (bi_const_p | ||||||
1313 | && !ctx->manifestly_const_eval | ||||||
1314 | && current_function_decl | ||||||
1315 | && DECL_DECLARED_CONSTEXPR_P (current_function_decl)((contains_struct_check (((tree_check2 (((((enum tree_code) ( current_function_decl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> (( ((tree_check ((current_function_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1315, __FUNCTION__, (TEMPLATE_DECL))))))))->result : current_function_decl )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1315, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1315, __FUNCTION__))->decl_common.lang_flag_8)) | ||||||
1316 | { | ||||||
1317 | *non_constant_p = true; | ||||||
1318 | return t; | ||||||
1319 | } | ||||||
1320 | |||||||
1321 | /* For __builtin_is_constant_evaluated, defer it if not | ||||||
1322 | ctx->manifestly_const_eval, otherwise fold it to true. */ | ||||||
1323 | if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED, | ||||||
1324 | BUILT_IN_FRONTEND)) | ||||||
1325 | { | ||||||
1326 | if (!ctx->manifestly_const_eval) | ||||||
1327 | { | ||||||
1328 | *non_constant_p = true; | ||||||
1329 | return t; | ||||||
1330 | } | ||||||
1331 | return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE]; | ||||||
1332 | } | ||||||
1333 | |||||||
1334 | if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND)) | ||||||
1335 | { | ||||||
1336 | temp_override<tree> ovr (current_function_decl); | ||||||
1337 | if (ctx->call && ctx->call->fundef) | ||||||
1338 | current_function_decl = ctx->call->fundef->decl; | ||||||
1339 | return fold_builtin_source_location (EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0))); | ||||||
1340 | } | ||||||
1341 | |||||||
1342 | int strops = 0; | ||||||
1343 | int strret = 0; | ||||||
1344 | if (fndecl_built_in_p (fun, BUILT_IN_NORMAL)) | ||||||
1345 | switch (DECL_FUNCTION_CODE (fun)) | ||||||
1346 | { | ||||||
1347 | case BUILT_IN_STRLEN: | ||||||
1348 | case BUILT_IN_STRNLEN: | ||||||
1349 | strops = 1; | ||||||
1350 | break; | ||||||
1351 | case BUILT_IN_MEMCHR: | ||||||
1352 | case BUILT_IN_STRCHR: | ||||||
1353 | case BUILT_IN_STRRCHR: | ||||||
1354 | strops = 1; | ||||||
1355 | strret = 1; | ||||||
1356 | break; | ||||||
1357 | case BUILT_IN_MEMCMP: | ||||||
1358 | case BUILT_IN_STRCMP: | ||||||
1359 | strops = 2; | ||||||
1360 | break; | ||||||
1361 | case BUILT_IN_STRSTR: | ||||||
1362 | strops = 2; | ||||||
1363 | strret = 1; | ||||||
1364 | break; | ||||||
1365 | case BUILT_IN_ASAN_POINTER_COMPARE: | ||||||
1366 | case BUILT_IN_ASAN_POINTER_SUBTRACT: | ||||||
1367 | /* These builtins shall be ignored during constant expression | ||||||
1368 | evaluation. */ | ||||||
1369 | return void_nodeglobal_trees[TI_VOID]; | ||||||
1370 | default: | ||||||
1371 | break; | ||||||
1372 | } | ||||||
1373 | |||||||
1374 | /* Be permissive for arguments to built-ins; __builtin_constant_p should | ||||||
1375 | return constant false for a non-constant argument. */ | ||||||
1376 | constexpr_ctx new_ctx = *ctx; | ||||||
1377 | new_ctx.quiet = true; | ||||||
1378 | for (i = 0; i < nargs; ++i) | ||||||
1379 | { | ||||||
1380 | tree arg = CALL_EXPR_ARG (t, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1380, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1380, __FUNCTION__))))); | ||||||
1381 | tree oarg = arg; | ||||||
1382 | |||||||
1383 | /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since | ||||||
1384 | expand_builtin doesn't know how to look in the values table. */ | ||||||
1385 | bool strop = i < strops; | ||||||
1386 | if (strop) | ||||||
1387 | { | ||||||
1388 | STRIP_NOPS (arg)(arg) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((arg))))); | ||||||
1389 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == ADDR_EXPR) | ||||||
1390 | arg = TREE_OPERAND (arg, 0)(*((const_cast<tree*> (tree_operand_check ((arg), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1390, __FUNCTION__))))); | ||||||
1391 | else | ||||||
1392 | strop = false; | ||||||
1393 | } | ||||||
1394 | |||||||
1395 | /* If builtin_valid_in_constant_expr_p is true, | ||||||
1396 | potential_constant_expression_1 has not recursed into the arguments | ||||||
1397 | of the builtin, verify it here. */ | ||||||
1398 | if (!builtin_valid_in_constant_expr_p (fun) | ||||||
1399 | || potential_constant_expression (arg)) | ||||||
1400 | { | ||||||
1401 | bool dummy1 = false, dummy2 = false; | ||||||
1402 | arg = cxx_eval_constant_expression (&new_ctx, arg, false, | ||||||
1403 | &dummy1, &dummy2); | ||||||
1404 | } | ||||||
1405 | |||||||
1406 | if (bi_const_p) | ||||||
1407 | /* For __builtin_constant_p, fold all expressions with constant values | ||||||
1408 | even if they aren't C++ constant-expressions. */ | ||||||
1409 | arg = cp_fold_rvalue (arg); | ||||||
1410 | else if (strop) | ||||||
1411 | { | ||||||
1412 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == CONSTRUCTOR) | ||||||
1413 | arg = braced_lists_to_strings (TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1413, __FUNCTION__))->typed.type), arg); | ||||||
1414 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == STRING_CST) | ||||||
1415 | arg = build_address (arg); | ||||||
1416 | else | ||||||
1417 | arg = oarg; | ||||||
1418 | } | ||||||
1419 | |||||||
1420 | args[i] = arg; | ||||||
1421 | } | ||||||
1422 | |||||||
1423 | bool save_ffbcp = force_folding_builtin_constant_p; | ||||||
1424 | force_folding_builtin_constant_p |= ctx->manifestly_const_eval; | ||||||
1425 | tree save_cur_fn = current_function_decl; | ||||||
1426 | /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */ | ||||||
1427 | if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION) | ||||||
1428 | && ctx->call | ||||||
1429 | && ctx->call->fundef) | ||||||
1430 | current_function_decl = ctx->call->fundef->decl; | ||||||
1431 | new_call = fold_builtin_call_array (EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)), TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1431, __FUNCTION__))->typed.type), | ||||||
1432 | CALL_EXPR_FN (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1432, __FUNCTION__, (CALL_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1432, __FUNCTION__))))), nargs, args); | ||||||
1433 | current_function_decl = save_cur_fn; | ||||||
1434 | force_folding_builtin_constant_p = save_ffbcp; | ||||||
1435 | if (new_call == NULLnullptr) | ||||||
1436 | { | ||||||
1437 | if (!*non_constant_p && !ctx->quiet) | ||||||
1438 | { | ||||||
1439 | /* Do not allow__builtin_unreachable in constexpr function. | ||||||
1440 | The __builtin_unreachable call with BUILTINS_LOCATION | ||||||
1441 | comes from cp_maybe_instrument_return. */ | ||||||
1442 | if (fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE) | ||||||
1443 | && EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)) == BUILTINS_LOCATION((location_t) 1)) | ||||||
1444 | error ("%<constexpr%> call flows off the end of the function"); | ||||||
1445 | else | ||||||
1446 | { | ||||||
1447 | new_call = build_call_array_loc (EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)), TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1447, __FUNCTION__))->typed.type), | ||||||
1448 | CALL_EXPR_FN (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1448, __FUNCTION__, (CALL_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1448, __FUNCTION__))))), nargs, args); | ||||||
1449 | error ("%q+E is not a constant expression", new_call); | ||||||
1450 | } | ||||||
1451 | } | ||||||
1452 | *non_constant_p = true; | ||||||
1453 | return t; | ||||||
1454 | } | ||||||
1455 | |||||||
1456 | if (!potential_constant_expression (new_call)) | ||||||
1457 | { | ||||||
1458 | if (!*non_constant_p && !ctx->quiet) | ||||||
1459 | error ("%q+E is not a constant expression", new_call); | ||||||
1460 | *non_constant_p = true; | ||||||
1461 | return t; | ||||||
1462 | } | ||||||
1463 | |||||||
1464 | if (strret) | ||||||
1465 | { | ||||||
1466 | /* memchr returns a pointer into the first argument, but we replaced the | ||||||
1467 | argument above with a STRING_CST; put it back it now. */ | ||||||
1468 | tree op = CALL_EXPR_ARG (t, strret-1)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1468, __FUNCTION__, (CALL_EXPR)))), ((strret-1) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1468, __FUNCTION__))))); | ||||||
1469 | STRIP_NOPS (new_call)(new_call) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((new_call))))); | ||||||
1470 | if (TREE_CODE (new_call)((enum tree_code) (new_call)->base.code) == POINTER_PLUS_EXPR) | ||||||
1471 | TREE_OPERAND (new_call, 0)(*((const_cast<tree*> (tree_operand_check ((new_call), ( 0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1471, __FUNCTION__))))) = op; | ||||||
1472 | else if (TREE_CODE (new_call)((enum tree_code) (new_call)->base.code) == ADDR_EXPR) | ||||||
1473 | new_call = op; | ||||||
1474 | } | ||||||
1475 | |||||||
1476 | return cxx_eval_constant_expression (&new_ctx, new_call, lval, | ||||||
1477 | non_constant_p, overflow_p); | ||||||
1478 | } | ||||||
1479 | |||||||
1480 | /* TEMP is the constant value of a temporary object of type TYPE. Adjust | ||||||
1481 | the type of the value to match. */ | ||||||
1482 | |||||||
1483 | static tree | ||||||
1484 | adjust_temp_type (tree type, tree temp) | ||||||
1485 | { | ||||||
1486 | if (same_type_p (TREE_TYPE (temp), type)comptypes ((((contains_struct_check ((temp), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1486, __FUNCTION__))->typed.type)), (type), 0)) | ||||||
1487 | return temp; | ||||||
1488 | /* Avoid wrapping an aggregate value in a NOP_EXPR. */ | ||||||
1489 | if (TREE_CODE (temp)((enum tree_code) (temp)->base.code) == CONSTRUCTOR) | ||||||
1490 | { | ||||||
1491 | /* build_constructor wouldn't retain various CONSTRUCTOR flags. */ | ||||||
1492 | tree t = copy_node (temp); | ||||||
1493 | TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1493, __FUNCTION__))->typed.type) = type; | ||||||
1494 | return t; | ||||||
1495 | } | ||||||
1496 | if (TREE_CODE (temp)((enum tree_code) (temp)->base.code) == EMPTY_CLASS_EXPR) | ||||||
1497 | return build0 (EMPTY_CLASS_EXPR, type); | ||||||
1498 | gcc_assert (scalarish_type_p (type))((void)(!(scalarish_type_p (type)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1498, __FUNCTION__), 0 : 0)); | ||||||
1499 | /* Now we know we're dealing with a scalar, and a prvalue of non-class | ||||||
1500 | type is cv-unqualified. */ | ||||||
1501 | return cp_fold_convert (cv_unqualified (type), temp); | ||||||
1502 | } | ||||||
1503 | |||||||
1504 | /* If T is a CONSTRUCTOR, return an unshared copy of T and any | ||||||
1505 | sub-CONSTRUCTORs. Otherwise return T. | ||||||
1506 | |||||||
1507 | We use this whenever we initialize an object as a whole, whether it's a | ||||||
1508 | parameter, a local variable, or a subobject, so that subsequent | ||||||
1509 | modifications don't affect other places where it was used. */ | ||||||
1510 | |||||||
1511 | tree | ||||||
1512 | unshare_constructor (tree t MEM_STAT_DECL) | ||||||
1513 | { | ||||||
1514 | if (!t || TREE_CODE (t)((enum tree_code) (t)->base.code) != CONSTRUCTOR) | ||||||
1515 | return t; | ||||||
1516 | auto_vec <tree*, 4> ptrs; | ||||||
1517 | ptrs.safe_push (&t); | ||||||
1518 | while (!ptrs.is_empty ()) | ||||||
1519 | { | ||||||
1520 | tree *p = ptrs.pop (); | ||||||
1521 | tree n = copy_node (*p PASS_MEM_STAT); | ||||||
1522 | CONSTRUCTOR_ELTS (n)((tree_check ((n), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1522, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts) = vec_safe_copy (CONSTRUCTOR_ELTS (*p)((tree_check ((*p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1522, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts) PASS_MEM_STAT); | ||||||
1523 | *p = n; | ||||||
1524 | vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (n)((tree_check ((n), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1524, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
1525 | constructor_elt *ce; | ||||||
1526 | for (HOST_WIDE_INTlong i = 0; vec_safe_iterate (v, i, &ce); ++i) | ||||||
1527 | if (ce->value && TREE_CODE (ce->value)((enum tree_code) (ce->value)->base.code) == CONSTRUCTOR) | ||||||
1528 | ptrs.safe_push (&ce->value); | ||||||
1529 | } | ||||||
1530 | return t; | ||||||
1531 | } | ||||||
1532 | |||||||
1533 | /* If T is a CONSTRUCTOR, ggc_free T and any sub-CONSTRUCTORs. */ | ||||||
1534 | |||||||
1535 | static void | ||||||
1536 | free_constructor (tree t) | ||||||
1537 | { | ||||||
1538 | if (!t || TREE_CODE (t)((enum tree_code) (t)->base.code) != CONSTRUCTOR) | ||||||
1539 | return; | ||||||
1540 | releasing_vec ctors; | ||||||
1541 | vec_safe_push (ctors, t); | ||||||
1542 | while (!ctors->is_empty ()) | ||||||
1543 | { | ||||||
1544 | tree c = ctors->pop (); | ||||||
1545 | if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (c)((tree_check ((c), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1545, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)) | ||||||
1546 | { | ||||||
1547 | constructor_elt *ce; | ||||||
1548 | for (HOST_WIDE_INTlong i = 0; vec_safe_iterate (elts, i, &ce); ++i) | ||||||
1549 | if (TREE_CODE (ce->value)((enum tree_code) (ce->value)->base.code) == CONSTRUCTOR) | ||||||
1550 | vec_safe_push (ctors, ce->value); | ||||||
1551 | ggc_free (elts); | ||||||
1552 | } | ||||||
1553 | ggc_free (c); | ||||||
1554 | } | ||||||
1555 | } | ||||||
1556 | |||||||
1557 | /* Subroutine of cxx_eval_call_expression. | ||||||
1558 | We are processing a call expression (either CALL_EXPR or | ||||||
1559 | AGGR_INIT_EXPR) in the context of CTX. Evaluate | ||||||
1560 | all arguments and bind their values to correspondings | ||||||
1561 | parameters, making up the NEW_CALL context. */ | ||||||
1562 | |||||||
1563 | static void | ||||||
1564 | cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, | ||||||
1565 | constexpr_call *new_call, | ||||||
1566 | bool *non_constant_p, bool *overflow_p, | ||||||
1567 | bool *non_constant_args) | ||||||
1568 | { | ||||||
1569 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1569, __FUNCTION__))->exp.operands[0]), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1569, __FUNCTION__)))) - 3); | ||||||
1570 | tree fun = new_call->fundef->decl; | ||||||
1571 | tree parms = new_call->fundef->parms; | ||||||
1572 | int i; | ||||||
1573 | /* We don't record ellipsis args below. */ | ||||||
1574 | int nparms = list_length (parms); | ||||||
1575 | int nbinds = nargs < nparms ? nargs : nparms; | ||||||
1576 | tree binds = new_call->bindings = make_tree_vec (nbinds); | ||||||
1577 | for (i = 0; i < nargs; ++i) | ||||||
1578 | { | ||||||
1579 | tree x, arg; | ||||||
1580 | tree type = parms ? TREE_TYPE (parms)((contains_struct_check ((parms), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1580, __FUNCTION__))->typed.type) : void_type_nodeglobal_trees[TI_VOID_TYPE]; | ||||||
1581 | x = get_nth_callarg (t, i); | ||||||
1582 | /* For member function, the first argument is a pointer to the implied | ||||||
1583 | object. For a constructor, it might still be a dummy object, in | ||||||
1584 | which case we get the real argument from ctx. */ | ||||||
1585 | if (i == 0 && DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1585, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1585, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) | ||||||
1586 | && is_dummy_object (x)) | ||||||
1587 | { | ||||||
1588 | x = ctx->object; | ||||||
1589 | x = build_address (x); | ||||||
1590 | } | ||||||
1591 | if (TREE_ADDRESSABLE (type)((type)->base.addressable_flag)) | ||||||
1592 | /* Undo convert_for_arg_passing work here. */ | ||||||
1593 | x = convert_from_reference (x); | ||||||
1594 | /* Normally we would strip a TARGET_EXPR in an initialization context | ||||||
1595 | such as this, but here we do the elision differently: we keep the | ||||||
1596 | TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */ | ||||||
1597 | arg = cxx_eval_constant_expression (ctx, x, /*lval=*/false, | ||||||
1598 | non_constant_p, overflow_p); | ||||||
1599 | /* Don't VERIFY_CONSTANT here. */ | ||||||
1600 | if (*non_constant_p && ctx->quiet) | ||||||
1601 | return; | ||||||
1602 | /* Just discard ellipsis args after checking their constantitude. */ | ||||||
1603 | if (!parms) | ||||||
1604 | continue; | ||||||
1605 | |||||||
1606 | if (!*non_constant_p) | ||||||
1607 | { | ||||||
1608 | /* Make sure the binding has the same type as the parm. But | ||||||
1609 | only for constant args. */ | ||||||
1610 | if (!TYPE_REF_P (type)(((enum tree_code) (type)->base.code) == REFERENCE_TYPE)) | ||||||
1611 | arg = adjust_temp_type (type, arg); | ||||||
1612 | if (!TREE_CONSTANT (arg)((non_type_check ((arg), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1612, __FUNCTION__))->base.constant_flag)) | ||||||
1613 | *non_constant_args = true; | ||||||
1614 | else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)(((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1614, __FUNCTION__))->type_common.lang_flag_4))) | ||||||
1615 | /* The destructor needs to see any modifications the callee makes | ||||||
1616 | to the argument. */ | ||||||
1617 | *non_constant_args = true; | ||||||
1618 | |||||||
1619 | /* For virtual calls, adjust the this argument, so that it is | ||||||
1620 | the object on which the method is called, rather than | ||||||
1621 | one of its bases. */ | ||||||
1622 | if (i == 0 && DECL_VIRTUAL_P (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1622, __FUNCTION__))->decl_common.virtual_flag)) | ||||||
1623 | { | ||||||
1624 | tree addr = arg; | ||||||
1625 | STRIP_NOPS (addr)(addr) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((addr))))); | ||||||
1626 | if (TREE_CODE (addr)((enum tree_code) (addr)->base.code) == ADDR_EXPR) | ||||||
1627 | { | ||||||
1628 | tree obj = TREE_OPERAND (addr, 0)(*((const_cast<tree*> (tree_operand_check ((addr), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1628, __FUNCTION__))))); | ||||||
1629 | while (TREE_CODE (obj)((enum tree_code) (obj)->base.code) == COMPONENT_REF | ||||||
1630 | && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1))((contains_struct_check (((tree_check (((*((const_cast<tree *> (tree_operand_check ((obj), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1630, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1630, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1630, __FUNCTION__))->decl_common.lang_flag_6) | ||||||
1631 | && !same_type_ignoring_top_level_qualifiers_p | ||||||
1632 | (TREE_TYPE (obj)((contains_struct_check ((obj), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1632, __FUNCTION__))->typed.type), DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1632, __FUNCTION__))->decl_minimal.context))) | ||||||
1633 | obj = TREE_OPERAND (obj, 0)(*((const_cast<tree*> (tree_operand_check ((obj), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1633, __FUNCTION__))))); | ||||||
1634 | if (obj != TREE_OPERAND (addr, 0)(*((const_cast<tree*> (tree_operand_check ((addr), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1634, __FUNCTION__)))))) | ||||||
1635 | arg = build_fold_addr_expr_with_type (obj,build_fold_addr_expr_with_type_loc (((location_t) 0), (obj), ( (contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1636, __FUNCTION__))->typed.type)) | ||||||
1636 | TREE_TYPE (arg))build_fold_addr_expr_with_type_loc (((location_t) 0), (obj), ( (contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1636, __FUNCTION__))->typed.type)); | ||||||
1637 | } | ||||||
1638 | } | ||||||
1639 | TREE_VEC_ELT (binds, i)(*((const_cast<tree *> (tree_vec_elt_check ((binds), (i ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1639, __FUNCTION__))))) = arg; | ||||||
1640 | } | ||||||
1641 | parms = TREE_CHAIN (parms)((contains_struct_check ((parms), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1641, __FUNCTION__))->common.chain); | ||||||
1642 | } | ||||||
1643 | } | ||||||
1644 | |||||||
1645 | /* Variables and functions to manage constexpr call expansion context. | ||||||
1646 | These do not need to be marked for PCH or GC. */ | ||||||
1647 | |||||||
1648 | /* FIXME remember and print actual constant arguments. */ | ||||||
1649 | static vec<tree> call_stack; | ||||||
1650 | static int call_stack_tick; | ||||||
1651 | static int last_cx_error_tick; | ||||||
1652 | |||||||
1653 | static int | ||||||
1654 | push_cx_call_context (tree call) | ||||||
1655 | { | ||||||
1656 | ++call_stack_tick; | ||||||
1657 | if (!EXPR_HAS_LOCATION (call)(((IS_ADHOC_LOC (((((call)) && ((tree_code_type[(int) (((enum tree_code) ((call))->base.code))]) >= tcc_reference && (tree_code_type[(int) (((enum tree_code) ((call)) ->base.code))]) <= tcc_expression)) ? (call)->exp.locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table , ((((call)) && ((tree_code_type[(int) (((enum tree_code ) ((call))->base.code))]) >= tcc_reference && ( tree_code_type[(int) (((enum tree_code) ((call))->base.code ))]) <= tcc_expression)) ? (call)->exp.locus : ((location_t ) 0))) : (((((call)) && ((tree_code_type[(int) (((enum tree_code) ((call))->base.code))]) >= tcc_reference && (tree_code_type[(int) (((enum tree_code) ((call))->base.code ))]) <= tcc_expression)) ? (call)->exp.locus : ((location_t ) 0)))) != ((location_t) 0))) | ||||||
1658 | SET_EXPR_LOCATION (call, input_location)(expr_check (((call)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1658, __FUNCTION__))->exp.locus = (input_location); | ||||||
1659 | call_stack.safe_push (call); | ||||||
1660 | int len = call_stack.length (); | ||||||
1661 | if (len > max_constexpr_depthglobal_options.x_max_constexpr_depth) | ||||||
1662 | return false; | ||||||
1663 | return len; | ||||||
1664 | } | ||||||
1665 | |||||||
1666 | static void | ||||||
1667 | pop_cx_call_context (void) | ||||||
1668 | { | ||||||
1669 | ++call_stack_tick; | ||||||
1670 | call_stack.pop (); | ||||||
1671 | } | ||||||
1672 | |||||||
1673 | vec<tree> | ||||||
1674 | cx_error_context (void) | ||||||
1675 | { | ||||||
1676 | vec<tree> r = vNULL; | ||||||
1677 | if (call_stack_tick != last_cx_error_tick | ||||||
1678 | && !call_stack.is_empty ()) | ||||||
1679 | r = call_stack; | ||||||
1680 | last_cx_error_tick = call_stack_tick; | ||||||
1681 | return r; | ||||||
1682 | } | ||||||
1683 | |||||||
1684 | /* Evaluate a call T to a GCC internal function when possible and return | ||||||
1685 | the evaluated result or, under the control of CTX, give an error, set | ||||||
1686 | NON_CONSTANT_P, and return the unevaluated call T otherwise. */ | ||||||
1687 | |||||||
1688 | static tree | ||||||
1689 | cxx_eval_internal_function (const constexpr_ctx *ctx, tree t, | ||||||
1690 | bool lval, | ||||||
1691 | bool *non_constant_p, bool *overflow_p) | ||||||
1692 | { | ||||||
1693 | enum tree_code opcode = ERROR_MARK; | ||||||
1694 | |||||||
1695 | switch (CALL_EXPR_IFN (t)((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1695, __FUNCTION__, (CALL_EXPR)))->base.u.ifn)) | ||||||
1696 | { | ||||||
1697 | case IFN_UBSAN_NULL: | ||||||
1698 | case IFN_UBSAN_BOUNDS: | ||||||
1699 | case IFN_UBSAN_VPTR: | ||||||
1700 | case IFN_FALLTHROUGH: | ||||||
1701 | return void_nodeglobal_trees[TI_VOID]; | ||||||
1702 | |||||||
1703 | case IFN_ADD_OVERFLOW: | ||||||
1704 | opcode = PLUS_EXPR; | ||||||
1705 | break; | ||||||
1706 | case IFN_SUB_OVERFLOW: | ||||||
1707 | opcode = MINUS_EXPR; | ||||||
1708 | break; | ||||||
1709 | case IFN_MUL_OVERFLOW: | ||||||
1710 | opcode = MULT_EXPR; | ||||||
1711 | break; | ||||||
1712 | |||||||
1713 | case IFN_LAUNDER: | ||||||
1714 | return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1714, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1714, __FUNCTION__))))), | ||||||
1715 | false, non_constant_p, overflow_p); | ||||||
1716 | |||||||
1717 | case IFN_VEC_CONVERT: | ||||||
1718 | { | ||||||
1719 | tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1719, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1719, __FUNCTION__))))), | ||||||
1720 | false, non_constant_p, | ||||||
1721 | overflow_p); | ||||||
1722 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == VECTOR_CST) | ||||||
1723 | return fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1723, __FUNCTION__))->typed.type), arg); | ||||||
1724 | else | ||||||
1725 | { | ||||||
1726 | *non_constant_p = true; | ||||||
1727 | return t; | ||||||
1728 | } | ||||||
1729 | } | ||||||
1730 | |||||||
1731 | default: | ||||||
1732 | if (!ctx->quiet) | ||||||
1733 | error_at (cp_expr_loc_or_input_loc (t), | ||||||
1734 | "call to internal function %qE", t); | ||||||
1735 | *non_constant_p = true; | ||||||
1736 | return t; | ||||||
1737 | } | ||||||
1738 | |||||||
1739 | /* Evaluate constant arguments using OPCODE and return a complex | ||||||
1740 | number containing the result and the overflow bit. */ | ||||||
1741 | tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1741, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1741, __FUNCTION__))))), lval, | ||||||
1742 | non_constant_p, overflow_p); | ||||||
1743 | tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1743, __FUNCTION__, (CALL_EXPR)))), ((1) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1743, __FUNCTION__))))), lval, | ||||||
1744 | non_constant_p, overflow_p); | ||||||
1745 | |||||||
1746 | if (TREE_CODE (arg0)((enum tree_code) (arg0)->base.code) == INTEGER_CST && TREE_CODE (arg1)((enum tree_code) (arg1)->base.code) == INTEGER_CST) | ||||||
1747 | { | ||||||
1748 | location_t loc = cp_expr_loc_or_input_loc (t); | ||||||
1749 | tree type = TREE_TYPE (TREE_TYPE (t))((contains_struct_check ((((contains_struct_check ((t), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1749, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1749, __FUNCTION__))->typed.type); | ||||||
1750 | tree result = fold_binary_loc (loc, opcode, type, | ||||||
1751 | fold_convert_loc (loc, type, arg0), | ||||||
1752 | fold_convert_loc (loc, type, arg1)); | ||||||
1753 | tree ovf | ||||||
1754 | = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1)); | ||||||
1755 | /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */ | ||||||
1756 | if (TREE_OVERFLOW (result)((tree_class_check ((result), (tcc_constant), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1756, __FUNCTION__))->base.public_flag)) | ||||||
1757 | TREE_OVERFLOW (result)((tree_class_check ((result), (tcc_constant), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1757, __FUNCTION__))->base.public_flag) = 0; | ||||||
1758 | |||||||
1759 | return build_complex (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1759, __FUNCTION__))->typed.type), result, ovf); | ||||||
1760 | } | ||||||
1761 | |||||||
1762 | *non_constant_p = true; | ||||||
1763 | return t; | ||||||
1764 | } | ||||||
1765 | |||||||
1766 | /* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates. */ | ||||||
1767 | |||||||
1768 | static void | ||||||
1769 | clear_no_implicit_zero (tree ctor) | ||||||
1770 | { | ||||||
1771 | if (CONSTRUCTOR_NO_CLEARING (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1771, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) | ||||||
1772 | { | ||||||
1773 | CONSTRUCTOR_NO_CLEARING (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1773, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = false; | ||||||
1774 | tree elt; unsigned HOST_WIDE_INTlong idx; | ||||||
1775 | FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), idx, elt)for (idx = 0; (idx >= vec_safe_length (((tree_check ((ctor ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1775, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : ((elt = (*(((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1775, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) [idx].value), true); (idx)++) | ||||||
1776 | if (TREE_CODE (elt)((enum tree_code) (elt)->base.code) == CONSTRUCTOR) | ||||||
1777 | clear_no_implicit_zero (elt); | ||||||
1778 | } | ||||||
1779 | } | ||||||
1780 | |||||||
1781 | /* Complain about a const object OBJ being modified in a constant expression. | ||||||
1782 | EXPR is the MODIFY_EXPR expression performing the modification. */ | ||||||
1783 | |||||||
1784 | static void | ||||||
1785 | modifying_const_object_error (tree expr, tree obj) | ||||||
1786 | { | ||||||
1787 | location_t loc = cp_expr_loc_or_input_loc (expr); | ||||||
1788 | auto_diagnostic_group d; | ||||||
1789 | error_at (loc, "modifying a const object %qE is not allowed in " | ||||||
1790 | "a constant expression", TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1790, __FUNCTION__)))))); | ||||||
1791 | inform (location_of (obj), "originally declared %<const%> here"); | ||||||
1792 | } | ||||||
1793 | |||||||
1794 | /* Return true if FNDECL is a replaceable global allocation function that | ||||||
1795 | should be useable during constant expression evaluation. */ | ||||||
1796 | |||||||
1797 | static inline bool | ||||||
1798 | cxx_replaceable_global_alloc_fn (tree fndecl) | ||||||
1799 | { | ||||||
1800 | return (cxx_dialect >= cxx20 | ||||||
1801 | && IDENTIFIER_NEWDEL_OP_P (DECL_NAME (fndecl))(((((tree_not_check2 (((tree_check ((((contains_struct_check ( (fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & (!((tree_not_check2 (((tree_check ((((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1))) && ((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fndecl), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1801, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) & OVL_OP_FLAG_ALLOC) | ||||||
1802 | && CP_DECL_CONTEXT (fndecl)(!(! (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1802, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1802, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1802, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]) == global_namespacecp_global_trees[CPTI_GLOBAL] | ||||||
1803 | && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)(((tree_check ((fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1803, __FUNCTION__, (FUNCTION_DECL)))->function_decl.decl_type == OPERATOR_NEW) && ((tree_check ((fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1803, __FUNCTION__, (FUNCTION_DECL)))->function_decl.replaceable_operator )) | ||||||
1804 | || DECL_IS_OPERATOR_DELETE_P (fndecl)((tree_check ((fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1804, __FUNCTION__, (FUNCTION_DECL)))->function_decl.decl_type == OPERATOR_DELETE))); | ||||||
1805 | } | ||||||
1806 | |||||||
1807 | /* Return true if FNDECL is a placement new function that should be | ||||||
1808 | useable during constant expression evaluation of std::construct_at. */ | ||||||
1809 | |||||||
1810 | static inline bool | ||||||
1811 | cxx_placement_new_fn (tree fndecl) | ||||||
1812 | { | ||||||
1813 | if (cxx_dialect >= cxx20 | ||||||
1814 | && IDENTIFIER_NEW_OP_P (DECL_NAME (fndecl))(((((tree_not_check2 (((tree_check ((((contains_struct_check ( (fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & (!((tree_not_check2 (((tree_check ((((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1))) && (((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fndecl), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1814, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) & (OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE) ) == OVL_OP_FLAG_ALLOC) | ||||||
1815 | && CP_DECL_CONTEXT (fndecl)(!(! (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1815, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1815, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1815, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]) == global_namespacecp_global_trees[CPTI_GLOBAL] | ||||||
1816 | && !DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)(((tree_check ((fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1816, __FUNCTION__, (FUNCTION_DECL)))->function_decl.decl_type == OPERATOR_NEW) && ((tree_check ((fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1816, __FUNCTION__, (FUNCTION_DECL)))->function_decl.replaceable_operator )) | ||||||
1817 | && TREE_CODE (TREE_TYPE (fndecl))((enum tree_code) (((contains_struct_check ((fndecl), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1817, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE) | ||||||
1818 | { | ||||||
1819 | tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))((contains_struct_check ((((tree_check2 ((((contains_struct_check ((fndecl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1819, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1819, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values)), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1819, __FUNCTION__))->common.chain); | ||||||
1820 | if (TREE_VALUE (first_arg)((tree_check ((first_arg), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1820, __FUNCTION__, (TREE_LIST)))->list.value) == ptr_type_nodeglobal_trees[TI_PTR_TYPE] | ||||||
1821 | && TREE_CHAIN (first_arg)((contains_struct_check ((first_arg), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1821, __FUNCTION__))->common.chain) == void_list_nodeglobal_trees[TI_VOID_LIST_NODE]) | ||||||
1822 | return true; | ||||||
1823 | } | ||||||
1824 | return false; | ||||||
1825 | } | ||||||
1826 | |||||||
1827 | /* Return true if FNDECL is std::construct_at. */ | ||||||
1828 | |||||||
1829 | static inline bool | ||||||
1830 | is_std_construct_at (tree fndecl) | ||||||
1831 | { | ||||||
1832 | if (!decl_in_std_namespace_p (fndecl)) | ||||||
1833 | return false; | ||||||
1834 | |||||||
1835 | tree name = DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1835, __FUNCTION__))->decl_minimal.name); | ||||||
1836 | return name && id_equal (name, "construct_at"); | ||||||
1837 | } | ||||||
1838 | |||||||
1839 | /* Return true if FNDECL is std::allocator<T>::{,de}allocate. */ | ||||||
1840 | |||||||
1841 | static inline bool | ||||||
1842 | is_std_allocator_allocate (tree fndecl) | ||||||
1843 | { | ||||||
1844 | tree name = DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1844, __FUNCTION__))->decl_minimal.name); | ||||||
1845 | if (name == NULL_TREE(tree) nullptr | ||||||
1846 | || !(id_equal (name, "allocate") || id_equal (name, "deallocate"))) | ||||||
1847 | return false; | ||||||
1848 | |||||||
1849 | tree ctx = DECL_CONTEXT (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1849, __FUNCTION__))->decl_minimal.context); | ||||||
1850 | if (ctx == NULL_TREE(tree) nullptr || !CLASS_TYPE_P (ctx)(((((enum tree_code) (ctx)->base.code)) == RECORD_TYPE || ( ((enum tree_code) (ctx)->base.code)) == UNION_TYPE) && ((tree_class_check ((ctx), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1850, __FUNCTION__))->type_common.lang_flag_5)) || !TYPE_MAIN_DECL (ctx)((((contains_struct_check (((tree_class_check ((((tree_class_check ((ctx), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1850, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1850, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1850, __FUNCTION__))->common.chain)))) | ||||||
1851 | return false; | ||||||
1852 | |||||||
1853 | tree decl = TYPE_MAIN_DECL (ctx)((((contains_struct_check (((tree_class_check ((((tree_class_check ((ctx), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1853, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1853, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1853, __FUNCTION__))->common.chain))); | ||||||
1854 | name = DECL_NAME (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1854, __FUNCTION__))->decl_minimal.name); | ||||||
1855 | if (name == NULL_TREE(tree) nullptr || !id_equal (name, "allocator")) | ||||||
1856 | return false; | ||||||
1857 | |||||||
1858 | return decl_in_std_namespace_p (decl); | ||||||
1859 | } | ||||||
1860 | |||||||
1861 | /* Return true if FNDECL is __dynamic_cast. */ | ||||||
1862 | |||||||
1863 | static inline bool | ||||||
1864 | cxx_dynamic_cast_fn_p (tree fndecl) | ||||||
1865 | { | ||||||
1866 | return (cxx_dialect >= cxx20 | ||||||
1867 | && id_equal (DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1867, __FUNCTION__))->decl_minimal.name), "__dynamic_cast") | ||||||
1868 | && CP_DECL_CONTEXT (fndecl)(!(! (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1868, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1868, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1868, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]) == global_namespacecp_global_trees[CPTI_GLOBAL]); | ||||||
1869 | } | ||||||
1870 | |||||||
1871 | /* Often, we have an expression in the form of address + offset, e.g. | ||||||
1872 | "&_ZTV1A + 16". Extract the object from it, i.e. "_ZTV1A". */ | ||||||
1873 | |||||||
1874 | static tree | ||||||
1875 | extract_obj_from_addr_offset (tree expr) | ||||||
1876 | { | ||||||
1877 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == POINTER_PLUS_EXPR) | ||||||
1878 | expr = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1878, __FUNCTION__))))); | ||||||
1879 | STRIP_NOPS (expr)(expr) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((expr))))); | ||||||
1880 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == ADDR_EXPR) | ||||||
1881 | expr = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1881, __FUNCTION__))))); | ||||||
1882 | return expr; | ||||||
1883 | } | ||||||
1884 | |||||||
1885 | /* Given a PATH like | ||||||
1886 | |||||||
1887 | g.D.2181.D.2154.D.2102.D.2093 | ||||||
1888 | |||||||
1889 | find a component with type TYPE. Return NULL_TREE if not found, and | ||||||
1890 | error_mark_node if the component is not accessible. If STOP is non-null, | ||||||
1891 | this function will return NULL_TREE if STOP is found before TYPE. */ | ||||||
1892 | |||||||
1893 | static tree | ||||||
1894 | get_component_with_type (tree path, tree type, tree stop) | ||||||
1895 | { | ||||||
1896 | while (true) | ||||||
1897 | { | ||||||
1898 | if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path)((contains_struct_check ((path), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1898, __FUNCTION__))->typed.type), type)) | ||||||
1899 | /* Found it. */ | ||||||
1900 | return path; | ||||||
1901 | else if (stop | ||||||
1902 | && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path)((contains_struct_check ((path), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1902, __FUNCTION__))->typed.type), | ||||||
1903 | stop))) | ||||||
1904 | return NULL_TREE(tree) nullptr; | ||||||
1905 | else if (TREE_CODE (path)((enum tree_code) (path)->base.code) == COMPONENT_REF | ||||||
1906 | && DECL_FIELD_IS_BASE (TREE_OPERAND (path, 1))((contains_struct_check (((tree_check (((*((const_cast<tree *> (tree_operand_check ((path), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1906, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1906, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1906, __FUNCTION__))->decl_common.lang_flag_6)) | ||||||
1907 | { | ||||||
1908 | /* We need to check that the component we're accessing is in fact | ||||||
1909 | accessible. */ | ||||||
1910 | if (TREE_PRIVATE (TREE_OPERAND (path, 1))(((*((const_cast<tree*> (tree_operand_check ((path), (1 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1910, __FUNCTION__))))))->base.private_flag) | ||||||
1911 | || TREE_PROTECTED (TREE_OPERAND (path, 1))(((*((const_cast<tree*> (tree_operand_check ((path), (1 ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1911, __FUNCTION__))))))->base.protected_flag)) | ||||||
1912 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
1913 | path = TREE_OPERAND (path, 0)(*((const_cast<tree*> (tree_operand_check ((path), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1913, __FUNCTION__))))); | ||||||
1914 | } | ||||||
1915 | else | ||||||
1916 | return NULL_TREE(tree) nullptr; | ||||||
1917 | } | ||||||
1918 | } | ||||||
1919 | |||||||
1920 | /* Evaluate a call to __dynamic_cast (permitted by P1327R1). | ||||||
1921 | |||||||
1922 | The declaration of __dynamic_cast is: | ||||||
1923 | |||||||
1924 | void* __dynamic_cast (const void* __src_ptr, | ||||||
1925 | const __class_type_info* __src_type, | ||||||
1926 | const __class_type_info* __dst_type, | ||||||
1927 | ptrdiff_t __src2dst); | ||||||
1928 | |||||||
1929 | where src2dst has the following possible values | ||||||
1930 | |||||||
1931 | >-1: src_type is a unique public non-virtual base of dst_type | ||||||
1932 | dst_ptr + src2dst == src_ptr | ||||||
1933 | -1: unspecified relationship | ||||||
1934 | -2: src_type is not a public base of dst_type | ||||||
1935 | -3: src_type is a multiple public non-virtual base of dst_type | ||||||
1936 | |||||||
1937 | Since literal types can't have virtual bases, we only expect hint >=0, | ||||||
1938 | -2, or -3. */ | ||||||
1939 | |||||||
1940 | static tree | ||||||
1941 | cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, | ||||||
1942 | bool *non_constant_p, bool *overflow_p) | ||||||
1943 | { | ||||||
1944 | /* T will be something like | ||||||
1945 | __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8) | ||||||
1946 | dismantle it. */ | ||||||
1947 | gcc_assert (call_expr_nargs (call) == 4)((void)(!((((int)((unsigned long) (*tree_int_cst_elt_check (( (tree_class_check ((call), (tcc_vl_exp), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1947, __FUNCTION__))->exp.operands[0]), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1947, __FUNCTION__)))) - 3) == 4) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1947, __FUNCTION__), 0 : 0)); | ||||||
1948 | tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error; | ||||||
1949 | tree obj = CALL_EXPR_ARG (call, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1949, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1949, __FUNCTION__))))); | ||||||
1950 | tree type = CALL_EXPR_ARG (call, 2)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1950, __FUNCTION__, (CALL_EXPR)))), ((2) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1950, __FUNCTION__))))); | ||||||
1951 | HOST_WIDE_INTlong hint = int_cst_value (CALL_EXPR_ARG (call, 3)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1951, __FUNCTION__, (CALL_EXPR)))), ((3) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1951, __FUNCTION__)))))); | ||||||
1952 | location_t loc = cp_expr_loc_or_input_loc (call); | ||||||
1953 | |||||||
1954 | /* Get the target type of the dynamic_cast. */ | ||||||
1955 | gcc_assert (TREE_CODE (type) == ADDR_EXPR)((void)(!(((enum tree_code) (type)->base.code) == ADDR_EXPR ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1955, __FUNCTION__), 0 : 0)); | ||||||
1956 | type = TREE_OPERAND (type, 0)(*((const_cast<tree*> (tree_operand_check ((type), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1956, __FUNCTION__))))); | ||||||
1957 | type = TREE_TYPE (DECL_NAME (type))((contains_struct_check ((((contains_struct_check ((type), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1957, __FUNCTION__))->decl_minimal.name)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1957, __FUNCTION__))->typed.type); | ||||||
1958 | |||||||
1959 | /* TYPE can only be either T* or T&. We can't know which of these it | ||||||
1960 | is by looking at TYPE, but OBJ will be "(T*) x" in the first case, | ||||||
1961 | and something like "(T*)(T&)(T*) x" in the second case. */ | ||||||
1962 | bool reference_p = false; | ||||||
1963 | while (CONVERT_EXPR_P (obj)((((enum tree_code) (obj)->base.code)) == NOP_EXPR || (((enum tree_code) (obj)->base.code)) == CONVERT_EXPR) || TREE_CODE (obj)((enum tree_code) (obj)->base.code) == SAVE_EXPR) | ||||||
1964 | { | ||||||
1965 | reference_p |= TYPE_REF_P (TREE_TYPE (obj))(((enum tree_code) (((contains_struct_check ((obj), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1965, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE ); | ||||||
1966 | obj = TREE_OPERAND (obj, 0)(*((const_cast<tree*> (tree_operand_check ((obj), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1966, __FUNCTION__))))); | ||||||
1967 | } | ||||||
1968 | |||||||
1969 | /* Evaluate the object so that we know its dynamic type. */ | ||||||
1970 | obj = cxx_eval_constant_expression (ctx, obj, /*lval*/false, non_constant_p, | ||||||
1971 | overflow_p); | ||||||
1972 | if (*non_constant_p) | ||||||
1973 | return call; | ||||||
1974 | |||||||
1975 | /* We expect OBJ to be in form of &d.D.2102 when HINT == 0, | ||||||
1976 | but when HINT is > 0, it can also be something like | ||||||
1977 | &d.D.2102 + 18446744073709551608, which includes the BINFO_OFFSET. */ | ||||||
1978 | obj = extract_obj_from_addr_offset (obj); | ||||||
1979 | const tree objtype = TREE_TYPE (obj)((contains_struct_check ((obj), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1979, __FUNCTION__))->typed.type); | ||||||
1980 | /* If OBJ doesn't refer to a base field, we're done. */ | ||||||
1981 | if (tree t = (TREE_CODE (obj)((enum tree_code) (obj)->base.code) == COMPONENT_REF | ||||||
1982 | ? TREE_OPERAND (obj, 1)(*((const_cast<tree*> (tree_operand_check ((obj), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1982, __FUNCTION__))))) : obj)) | ||||||
1983 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) != FIELD_DECL || !DECL_FIELD_IS_BASE (t)((contains_struct_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1983, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 1983, __FUNCTION__))->decl_common.lang_flag_6)) | ||||||
1984 | { | ||||||
1985 | if (reference_p) | ||||||
1986 | { | ||||||
1987 | if (!ctx->quiet) | ||||||
1988 | { | ||||||
1989 | error_at (loc, "reference %<dynamic_cast%> failed"); | ||||||
1990 | inform (loc, "dynamic type %qT of its operand does " | ||||||
1991 | "not have a base class of type %qT", | ||||||
1992 | objtype, type); | ||||||
1993 | } | ||||||
1994 | *non_constant_p = true; | ||||||
1995 | } | ||||||
1996 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; | ||||||
1997 | } | ||||||
1998 | |||||||
1999 | /* [class.cdtor] When a dynamic_cast is used in a constructor ... | ||||||
2000 | or in a destructor ... if the operand of the dynamic_cast refers | ||||||
2001 | to the object under construction or destruction, this object is | ||||||
2002 | considered to be a most derived object that has the type of the | ||||||
2003 | constructor or destructor's class. */ | ||||||
2004 | tree vtable = build_vfield_ref (obj, objtype); | ||||||
2005 | vtable = cxx_eval_constant_expression (ctx, vtable, /*lval*/false, | ||||||
2006 | non_constant_p, overflow_p); | ||||||
2007 | if (*non_constant_p) | ||||||
2008 | return call; | ||||||
2009 | /* With -fsanitize=vptr, we initialize all vtable pointers to null, | ||||||
2010 | so it's possible that we got a null pointer now. */ | ||||||
2011 | if (integer_zerop (vtable)) | ||||||
2012 | { | ||||||
2013 | if (!ctx->quiet) | ||||||
2014 | error_at (loc, "virtual table pointer is used uninitialized"); | ||||||
2015 | *non_constant_p = true; | ||||||
2016 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; | ||||||
2017 | } | ||||||
2018 | /* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A. */ | ||||||
2019 | vtable = extract_obj_from_addr_offset (vtable); | ||||||
2020 | const tree mdtype = DECL_CONTEXT (vtable)((contains_struct_check ((vtable), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2020, __FUNCTION__))->decl_minimal.context); | ||||||
2021 | |||||||
2022 | /* Given dynamic_cast<T>(v), | ||||||
2023 | |||||||
2024 | [expr.dynamic.cast] If C is the class type to which T points or refers, | ||||||
2025 | the runtime check logically executes as follows: | ||||||
2026 | |||||||
2027 | If, in the most derived object pointed (referred) to by v, v points | ||||||
2028 | (refers) to a public base class subobject of a C object, and if only | ||||||
2029 | one object of type C is derived from the subobject pointed (referred) | ||||||
2030 | to by v the result points (refers) to that C object. | ||||||
2031 | |||||||
2032 | In this case, HINT >= 0 or -3. */ | ||||||
2033 | if (hint >= 0 || hint == -3) | ||||||
2034 | { | ||||||
2035 | /* Look for a component with type TYPE. */ | ||||||
2036 | tree t = get_component_with_type (obj, type, mdtype); | ||||||
2037 | /* If not accessible, give an error. */ | ||||||
2038 | if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
2039 | { | ||||||
2040 | if (reference_p) | ||||||
2041 | { | ||||||
2042 | if (!ctx->quiet) | ||||||
2043 | { | ||||||
2044 | error_at (loc, "reference %<dynamic_cast%> failed"); | ||||||
2045 | inform (loc, "static type %qT of its operand is a " | ||||||
2046 | "non-public base class of dynamic type %qT", | ||||||
2047 | objtype, type); | ||||||
2048 | |||||||
2049 | } | ||||||
2050 | *non_constant_p = true; | ||||||
2051 | } | ||||||
2052 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; | ||||||
2053 | } | ||||||
2054 | else if (t) | ||||||
2055 | /* The result points to the TYPE object. */ | ||||||
2056 | return cp_build_addr_expr (t, complain); | ||||||
2057 | /* Else, TYPE was not found, because the HINT turned out to be wrong. | ||||||
2058 | Fall through to the normal processing. */ | ||||||
2059 | } | ||||||
2060 | |||||||
2061 | /* Otherwise, if v points (refers) to a public base class subobject of the | ||||||
2062 | most derived object, and the type of the most derived object has a base | ||||||
2063 | class, of type C, that is unambiguous and public, the result points | ||||||
2064 | (refers) to the C subobject of the most derived object. | ||||||
2065 | |||||||
2066 | But it can also be an invalid case. */ | ||||||
2067 | |||||||
2068 | /* Get the most derived object. */ | ||||||
2069 | obj = get_component_with_type (obj, mdtype, NULL_TREE(tree) nullptr); | ||||||
2070 | if (obj == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
2071 | { | ||||||
2072 | if (reference_p) | ||||||
2073 | { | ||||||
2074 | if (!ctx->quiet) | ||||||
2075 | { | ||||||
2076 | error_at (loc, "reference %<dynamic_cast%> failed"); | ||||||
2077 | inform (loc, "static type %qT of its operand is a non-public" | ||||||
2078 | " base class of dynamic type %qT", objtype, mdtype); | ||||||
2079 | } | ||||||
2080 | *non_constant_p = true; | ||||||
2081 | } | ||||||
2082 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; | ||||||
2083 | } | ||||||
2084 | else | ||||||
2085 | gcc_assert (obj)((void)(!(obj) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2085, __FUNCTION__), 0 : 0)); | ||||||
2086 | |||||||
2087 | /* Check that the type of the most derived object has a base class | ||||||
2088 | of type TYPE that is unambiguous and public. */ | ||||||
2089 | base_kind b_kind; | ||||||
2090 | tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none); | ||||||
2091 | if (!binfo || binfo == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
2092 | { | ||||||
2093 | if (reference_p) | ||||||
2094 | { | ||||||
2095 | if (!ctx->quiet) | ||||||
2096 | { | ||||||
2097 | error_at (loc, "reference %<dynamic_cast%> failed"); | ||||||
2098 | if (b_kind == bk_ambig) | ||||||
2099 | inform (loc, "%qT is an ambiguous base class of dynamic " | ||||||
2100 | "type %qT of its operand", type, mdtype); | ||||||
2101 | else | ||||||
2102 | inform (loc, "dynamic type %qT of its operand does not " | ||||||
2103 | "have an unambiguous public base class %qT", | ||||||
2104 | mdtype, type); | ||||||
2105 | } | ||||||
2106 | *non_constant_p = true; | ||||||
2107 | } | ||||||
2108 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; | ||||||
2109 | } | ||||||
2110 | /* If so, return the TYPE subobject of the most derived object. */ | ||||||
2111 | obj = convert_to_base_statically (obj, binfo); | ||||||
2112 | return cp_build_addr_expr (obj, complain); | ||||||
2113 | } | ||||||
2114 | |||||||
2115 | /* Data structure used by replace_result_decl and replace_result_decl_r. */ | ||||||
2116 | |||||||
2117 | struct replace_result_decl_data | ||||||
2118 | { | ||||||
2119 | /* The RESULT_DECL we want to replace. */ | ||||||
2120 | tree decl; | ||||||
2121 | /* The replacement for DECL. */ | ||||||
2122 | tree replacement; | ||||||
2123 | /* Whether we've performed any replacements. */ | ||||||
2124 | bool changed; | ||||||
2125 | }; | ||||||
2126 | |||||||
2127 | /* Helper function for replace_result_decl, called through cp_walk_tree. */ | ||||||
2128 | |||||||
2129 | static tree | ||||||
2130 | replace_result_decl_r (tree *tp, int *walk_subtrees, void *data) | ||||||
2131 | { | ||||||
2132 | replace_result_decl_data *d = (replace_result_decl_data *) data; | ||||||
2133 | |||||||
2134 | if (*tp == d->decl) | ||||||
2135 | { | ||||||
2136 | *tp = unshare_expr (d->replacement); | ||||||
2137 | d->changed = true; | ||||||
2138 | *walk_subtrees = 0; | ||||||
2139 | } | ||||||
2140 | else if (TYPE_P (*tp)(tree_code_type[(int) (((enum tree_code) (*tp)->base.code) )] == tcc_type)) | ||||||
2141 | *walk_subtrees = 0; | ||||||
2142 | |||||||
2143 | return NULL_TREE(tree) nullptr; | ||||||
2144 | } | ||||||
2145 | |||||||
2146 | /* Replace every occurrence of DECL, a RESULT_DECL, with (an unshared copy of) | ||||||
2147 | REPLACEMENT within the reduced constant expression *TP. Returns true iff a | ||||||
2148 | replacement was performed. */ | ||||||
2149 | |||||||
2150 | static bool | ||||||
2151 | replace_result_decl (tree *tp, tree decl, tree replacement) | ||||||
2152 | { | ||||||
2153 | gcc_checking_assert (TREE_CODE (decl) == RESULT_DECL((void)(!(((enum tree_code) (decl)->base.code) == RESULT_DECL && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__))->typed.type), ((contains_struct_check ((replacement), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__))->typed.type)))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__), 0 : 0)) | ||||||
2154 | && (same_type_ignoring_top_level_qualifiers_p((void)(!(((enum tree_code) (decl)->base.code) == RESULT_DECL && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__))->typed.type), ((contains_struct_check ((replacement), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__))->typed.type)))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__), 0 : 0)) | ||||||
2155 | (TREE_TYPE (decl), TREE_TYPE (replacement))))((void)(!(((enum tree_code) (decl)->base.code) == RESULT_DECL && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__))->typed.type), ((contains_struct_check ((replacement), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__))->typed.type)))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2155, __FUNCTION__), 0 : 0)); | ||||||
2156 | replace_result_decl_data data = { decl, replacement, false }; | ||||||
2157 | cp_walk_tree_without_duplicates (tp, replace_result_decl_r, &data)walk_tree_without_duplicates_1 (tp, replace_result_decl_r, & data, cp_walk_subtrees); | ||||||
2158 | return data.changed; | ||||||
2159 | } | ||||||
2160 | |||||||
2161 | /* Evaluate the call T to virtual function thunk THUNK_FNDECL. */ | ||||||
2162 | |||||||
2163 | static tree | ||||||
2164 | cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl, | ||||||
2165 | bool lval, | ||||||
2166 | bool *non_constant_p, bool *overflow_p) | ||||||
2167 | { | ||||||
2168 | tree function = THUNK_TARGET (thunk_fndecl)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (thunk_fndecl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2168, __FUNCTION__, (TEMPLATE_DECL))))))))->result : thunk_fndecl )), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2168, __FUNCTION__))->decl_common.lang_specific); if (!( ((enum tree_code) (thunk_fndecl)->base.code) == FUNCTION_DECL || (((enum tree_code) (thunk_fndecl)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2168, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2168, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2168, __FUNCTION__); <->u.fn; })->befriending_classes ); | ||||||
2169 | |||||||
2170 | /* virtual_offset is only set in the presence of virtual bases, which make | ||||||
2171 | the class non-literal, so we don't need to handle it here. */ | ||||||
2172 | if (THUNK_VIRTUAL_OFFSET (thunk_fndecl)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check (((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__))->decl_common.lang_specific); if (!( (((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == VAR_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == FUNCTION_DECL ) || ((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == FIELD_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == CONST_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == TYPE_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == TEMPLATE_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == USING_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__, (FUNCTION_DECL))))->base.code) == CONCEPT_DECL )) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2172, __FUNCTION__); <->u.min; })->access)) | ||||||
2173 | { | ||||||
2174 | gcc_assert (!DECL_DECLARED_CONSTEXPR_P (function))((void)(!(!((contains_struct_check (((tree_check2 (((((enum tree_code ) (function)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((function ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2174, __FUNCTION__, (TEMPLATE_DECL))))))))->result : function )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2174, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2174, __FUNCTION__))->decl_common.lang_flag_8)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2174, __FUNCTION__), 0 : 0)); | ||||||
2175 | if (!ctx->quiet) | ||||||
2176 | { | ||||||
2177 | error ("call to non-%<constexpr%> function %qD", function); | ||||||
2178 | explain_invalid_constexpr_fn (function); | ||||||
2179 | } | ||||||
2180 | *non_constant_p = true; | ||||||
2181 | return t; | ||||||
2182 | } | ||||||
2183 | |||||||
2184 | tree new_call = copy_node (t); | ||||||
2185 | CALL_EXPR_FN (new_call)(*((const_cast<tree*> (tree_operand_check (((tree_check ((new_call), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2185, __FUNCTION__, (CALL_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2185, __FUNCTION__))))) = function; | ||||||
2186 | TREE_TYPE (new_call)((contains_struct_check ((new_call), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2186, __FUNCTION__))->typed.type) = TREE_TYPE (TREE_TYPE (function))((contains_struct_check ((((contains_struct_check ((function) , (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2186, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2186, __FUNCTION__))->typed.type); | ||||||
2187 | |||||||
2188 | tree offset = size_int (THUNK_FIXED_OFFSET (thunk_fndecl))size_int_kind ((((contains_struct_check ((__extension__ ({ __typeof (thunk_fndecl) const __t = (thunk_fndecl); if (((enum tree_code ) (__t)->base.code) != FUNCTION_DECL || !__t->decl_common .lang_specific || !__t->decl_common.lang_specific->u.fn .thunk_p) tree_check_failed (__t, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2188, __FUNCTION__, 0); __t; })), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2188, __FUNCTION__))->decl_common.lang_specific)->u.fn .u5.fixed_offset), stk_sizetype); | ||||||
2189 | |||||||
2190 | if (DECL_THIS_THUNK_P (thunk_fndecl)((((enum tree_code) (thunk_fndecl)->base.code) == FUNCTION_DECL && ((contains_struct_check ((thunk_fndecl), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__))->decl_common.lang_specific) && __extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (thunk_fndecl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__, (TEMPLATE_DECL))))))))->result : thunk_fndecl )), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__))->decl_common.lang_specific); if (!( ((enum tree_code) (thunk_fndecl)->base.code) == FUNCTION_DECL || (((enum tree_code) (thunk_fndecl)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__); <->u.fn; })->thunk_p) && __extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (thunk_fndecl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__, (TEMPLATE_DECL))))))))->result : thunk_fndecl )), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__))->decl_common.lang_specific); if (!( ((enum tree_code) (thunk_fndecl)->base.code) == FUNCTION_DECL || (((enum tree_code) (thunk_fndecl)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2190, __FUNCTION__); <->u.fn; })->this_thunk_p)) | ||||||
2191 | { | ||||||
2192 | /* 'this'-adjusting thunk. */ | ||||||
2193 | tree this_arg = CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2193, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2193, __FUNCTION__))))); | ||||||
2194 | this_arg = build2 (POINTER_PLUS_EXPR, TREE_TYPE (this_arg)((contains_struct_check ((this_arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2194, __FUNCTION__))->typed.type), | ||||||
2195 | this_arg, offset); | ||||||
2196 | CALL_EXPR_ARG (new_call, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((new_call), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2196, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2196, __FUNCTION__))))) = this_arg; | ||||||
2197 | } | ||||||
2198 | else | ||||||
2199 | /* Return-adjusting thunk. */ | ||||||
2200 | new_call = build2 (POINTER_PLUS_EXPR, TREE_TYPE (new_call)((contains_struct_check ((new_call), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2200, __FUNCTION__))->typed.type), | ||||||
2201 | new_call, offset); | ||||||
2202 | |||||||
2203 | return cxx_eval_constant_expression (ctx, new_call, lval, | ||||||
2204 | non_constant_p, overflow_p); | ||||||
2205 | } | ||||||
2206 | |||||||
2207 | /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set | ||||||
2208 | its TREE_READONLY flag according to READONLY_P. Used for constexpr | ||||||
2209 | 'tors to detect modifying const objects in a constexpr context. */ | ||||||
2210 | |||||||
2211 | static void | ||||||
2212 | cxx_set_object_constness (const constexpr_ctx *ctx, tree object, | ||||||
2213 | bool readonly_p, bool *non_constant_p, | ||||||
2214 | bool *overflow_p) | ||||||
2215 | { | ||||||
2216 | if (CLASS_TYPE_P (TREE_TYPE (object))(((((enum tree_code) (((contains_struct_check ((object), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2216, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((object), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2216, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((object ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2216, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2216, __FUNCTION__))->type_common.lang_flag_5)) | ||||||
2217 | && CP_TYPE_CONST_P (TREE_TYPE (object))((cp_type_quals (((contains_struct_check ((object), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2217, __FUNCTION__))->typed.type)) & TYPE_QUAL_CONST ) != 0)) | ||||||
2218 | { | ||||||
2219 | /* Subobjects might not be stored in ctx->global->values but we | ||||||
2220 | can get its CONSTRUCTOR by evaluating *this. */ | ||||||
2221 | tree e = cxx_eval_constant_expression (ctx, object, /*lval*/false, | ||||||
2222 | non_constant_p, overflow_p); | ||||||
2223 | if (TREE_CODE (e)((enum tree_code) (e)->base.code) == CONSTRUCTOR && !*non_constant_p) | ||||||
2224 | TREE_READONLY (e)((non_type_check ((e), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2224, __FUNCTION__))->base.readonly_flag) = readonly_p; | ||||||
2225 | } | ||||||
2226 | } | ||||||
2227 | |||||||
2228 | /* Subroutine of cxx_eval_constant_expression. | ||||||
2229 | Evaluate the call expression tree T in the context of OLD_CALL expression | ||||||
2230 | evaluation. */ | ||||||
2231 | |||||||
2232 | static tree | ||||||
2233 | cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, | ||||||
2234 | bool lval, | ||||||
2235 | bool *non_constant_p, bool *overflow_p) | ||||||
2236 | { | ||||||
2237 | /* Handle concept checks separately. */ | ||||||
2238 | if (concept_check_p (t)) | ||||||
2239 | return evaluate_concept_check (t, tf_warning_or_error); | ||||||
2240 | |||||||
2241 | location_t loc = cp_expr_loc_or_input_loc (t); | ||||||
2242 | tree fun = get_function_named_in_call (t); | ||||||
2243 | constexpr_call new_call | ||||||
2244 | = { NULLnullptr, NULLnullptr, NULLnullptr, 0, ctx->manifestly_const_eval }; | ||||||
2245 | int depth_ok; | ||||||
2246 | |||||||
2247 | if (fun == NULL_TREE(tree) nullptr) | ||||||
2248 | return cxx_eval_internal_function (ctx, t, lval, | ||||||
2249 | non_constant_p, overflow_p); | ||||||
2250 | |||||||
2251 | if (TREE_CODE (fun)((enum tree_code) (fun)->base.code) != FUNCTION_DECL) | ||||||
2252 | { | ||||||
2253 | /* Might be a constexpr function pointer. */ | ||||||
2254 | fun = cxx_eval_constant_expression (ctx, fun, | ||||||
2255 | /*lval*/false, non_constant_p, | ||||||
2256 | overflow_p); | ||||||
2257 | STRIP_NOPS (fun)(fun) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((fun))))); | ||||||
2258 | if (TREE_CODE (fun)((enum tree_code) (fun)->base.code) == ADDR_EXPR) | ||||||
2259 | fun = TREE_OPERAND (fun, 0)(*((const_cast<tree*> (tree_operand_check ((fun), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2259, __FUNCTION__))))); | ||||||
2260 | /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no | ||||||
2261 | indirection, the called expression is a pointer into the | ||||||
2262 | virtual table which should contain FDESC_EXPR. Extract the | ||||||
2263 | FUNCTION_DECL from there. */ | ||||||
2264 | else if (TARGET_VTABLE_USES_DESCRIPTORS0 | ||||||
2265 | && TREE_CODE (fun)((enum tree_code) (fun)->base.code) == POINTER_PLUS_EXPR | ||||||
2266 | && TREE_CODE (TREE_OPERAND (fun, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((fun), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2266, __FUNCTION__))))))->base.code) == ADDR_EXPR | ||||||
2267 | && TREE_CODE (TREE_OPERAND (fun, 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((fun), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2267, __FUNCTION__))))))->base.code) == INTEGER_CST) | ||||||
2268 | { | ||||||
2269 | tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((fun), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2269, __FUNCTION__)))))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2269, __FUNCTION__))))); | ||||||
2270 | if (VAR_P (d)(((enum tree_code) (d)->base.code) == VAR_DECL) | ||||||
2271 | && DECL_VTABLE_OR_VTT_P (d)((contains_struct_check (((tree_check ((d), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2271, __FUNCTION__, (VAR_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2271, __FUNCTION__))->decl_common.virtual_flag) | ||||||
2272 | && TREE_CODE (TREE_TYPE (d))((enum tree_code) (((contains_struct_check ((d), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2272, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE | ||||||
2273 | && TREE_TYPE (TREE_TYPE (d))((contains_struct_check ((((contains_struct_check ((d), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2273, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2273, __FUNCTION__))->typed.type) == vtable_entry_typecp_global_trees[CPTI_VTABLE_ENTRY_TYPE] | ||||||
2274 | && DECL_INITIAL (d)((contains_struct_check ((d), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2274, __FUNCTION__))->decl_common.initial) | ||||||
2275 | && TREE_CODE (DECL_INITIAL (d))((enum tree_code) (((contains_struct_check ((d), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2275, __FUNCTION__))->decl_common.initial))->base.code ) == CONSTRUCTOR) | ||||||
2276 | { | ||||||
2277 | tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1)(*((const_cast<tree*> (tree_operand_check ((fun), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2277, __FUNCTION__))))), | ||||||
2278 | TYPE_SIZE_UNIT (vtable_entry_type)((tree_class_check ((cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]) , (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2278, __FUNCTION__))->type_common.size_unit)); | ||||||
2279 | HOST_WIDE_INTlong idx = find_array_ctor_elt (DECL_INITIAL (d)((contains_struct_check ((d), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2279, __FUNCTION__))->decl_common.initial), i); | ||||||
2280 | if (idx >= 0) | ||||||
2281 | { | ||||||
2282 | tree fdesc | ||||||
2283 | = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d))((tree_check ((((contains_struct_check ((d), (TS_DECL_COMMON) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2283, __FUNCTION__))->decl_common.initial)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2283, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[idx].value; | ||||||
2284 | if (TREE_CODE (fdesc)((enum tree_code) (fdesc)->base.code) == FDESC_EXPR | ||||||
2285 | && integer_zerop (TREE_OPERAND (fdesc, 1)(*((const_cast<tree*> (tree_operand_check ((fdesc), (1) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2285, __FUNCTION__))))))) | ||||||
2286 | fun = TREE_OPERAND (fdesc, 0)(*((const_cast<tree*> (tree_operand_check ((fdesc), (0) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2286, __FUNCTION__))))); | ||||||
2287 | } | ||||||
2288 | } | ||||||
2289 | } | ||||||
2290 | } | ||||||
2291 | if (TREE_CODE (fun)((enum tree_code) (fun)->base.code) != FUNCTION_DECL) | ||||||
2292 | { | ||||||
2293 | if (!ctx->quiet && !*non_constant_p) | ||||||
2294 | error_at (loc, "expression %qE does not designate a %<constexpr%> " | ||||||
2295 | "function", fun); | ||||||
2296 | *non_constant_p = true; | ||||||
2297 | return t; | ||||||
2298 | } | ||||||
2299 | if (DECL_CLONED_FUNCTION_P (fun)(((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__))->decl_minimal.name) && ((!( (tree_not_check2 (((tree_check ((((contains_struct_check ((fun ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & ((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1)) && !((((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_CTOR_IDENTIFIER]) || (((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2299, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_DTOR_IDENTIFIER])))) | ||||||
2300 | fun = DECL_CLONED_FUNCTION (fun)(((contains_struct_check (((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2300, __FUNCTION__, (FUNCTION_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2300, __FUNCTION__))->decl_common.lang_specific)->u.fn .u5.cloned_function); | ||||||
2301 | |||||||
2302 | if (is_ubsan_builtin_p (fun)) | ||||||
2303 | return void_nodeglobal_trees[TI_VOID]; | ||||||
2304 | |||||||
2305 | if (fndecl_built_in_p (fun)) | ||||||
2306 | return cxx_eval_builtin_function_call (ctx, t, fun, | ||||||
2307 | lval, non_constant_p, overflow_p); | ||||||
2308 | if (DECL_THUNK_P (fun)(((enum tree_code) (fun)->base.code) == FUNCTION_DECL && ((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2308, __FUNCTION__))->decl_common.lang_specific) && __extension__ ({ struct lang_decl *lt = ((contains_struct_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2308, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2308, __FUNCTION__))->decl_common.lang_specific); if (!( ((enum tree_code) (fun)->base.code) == FUNCTION_DECL || (( (enum tree_code) (fun)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2308, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) nullptr && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2308, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2308, __FUNCTION__); <->u.fn; })->thunk_p)) | ||||||
2309 | return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p); | ||||||
2310 | if (!DECL_DECLARED_CONSTEXPR_P (fun)((contains_struct_check (((tree_check2 (((((enum tree_code) ( fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2310, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2310, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2310, __FUNCTION__))->decl_common.lang_flag_8)) | ||||||
2311 | { | ||||||
2312 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR | ||||||
2313 | && cxx_replaceable_global_alloc_fn (fun) | ||||||
2314 | && (CALL_FROM_NEW_OR_DELETE_P (t)((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2314, __FUNCTION__, (CALL_EXPR)))->base.protected_flag) | ||||||
2315 | || (ctx->call | ||||||
2316 | && ctx->call->fundef | ||||||
2317 | && is_std_allocator_allocate (ctx->call->fundef->decl)))) | ||||||
2318 | { | ||||||
2319 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2319, __FUNCTION__))->exp.operands[0]), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2319, __FUNCTION__)))) - 3); | ||||||
2320 | tree arg0 = NULL_TREE(tree) nullptr; | ||||||
2321 | for (int i = 0; i < nargs; ++i) | ||||||
2322 | { | ||||||
2323 | tree arg = CALL_EXPR_ARG (t, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2323, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2323, __FUNCTION__))))); | ||||||
2324 | arg = cxx_eval_constant_expression (ctx, arg, false, | ||||||
2325 | non_constant_p, overflow_p); | ||||||
2326 | VERIFY_CONSTANT (arg)do { if (verify_constant ((arg), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
2327 | if (i == 0) | ||||||
2328 | arg0 = arg; | ||||||
2329 | } | ||||||
2330 | gcc_assert (arg0)((void)(!(arg0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2330, __FUNCTION__), 0 : 0)); | ||||||
2331 | if (IDENTIFIER_NEW_OP_P (DECL_NAME (fun))(((((tree_not_check2 (((tree_check ((((contains_struct_check ( (fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & (!((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1))) && (((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2331, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) & (OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE) ) == OVL_OP_FLAG_ALLOC)) | ||||||
2332 | { | ||||||
2333 | tree type = build_array_type_nelts (char_type_nodeinteger_types[itk_char], | ||||||
2334 | tree_to_uhwi (arg0)); | ||||||
2335 | tree var = build_decl (loc, VAR_DECL, | ||||||
2336 | (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2336, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2336, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2336, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2336, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2336, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) | ||||||
2337 | & OVL_OP_FLAG_VEC) | ||||||
2338 | ? heap_vec_uninit_identifiercp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER] | ||||||
2339 | : heap_uninit_identifiercp_global_trees[CPTI_HEAP_UNINIT_IDENTIFIER], | ||||||
2340 | type); | ||||||
2341 | DECL_ARTIFICIAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2341, __FUNCTION__))->decl_common.artificial_flag) = 1; | ||||||
2342 | TREE_STATIC (var)((var)->base.static_flag) = 1; | ||||||
2343 | ctx->global->heap_vars.safe_push (var); | ||||||
2344 | ctx->global->values.put (var, NULL_TREE(tree) nullptr); | ||||||
2345 | return fold_convert (ptr_type_node, build_address (var))fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE] , build_address (var)); | ||||||
2346 | } | ||||||
2347 | else | ||||||
2348 | { | ||||||
2349 | STRIP_NOPS (arg0)(arg0) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((arg0))))); | ||||||
2350 | if (TREE_CODE (arg0)((enum tree_code) (arg0)->base.code) == ADDR_EXPR | ||||||
2351 | && VAR_P (TREE_OPERAND (arg0, 0))(((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((arg0), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2351, __FUNCTION__))))))->base.code) == VAR_DECL)) | ||||||
2352 | { | ||||||
2353 | tree var = TREE_OPERAND (arg0, 0)(*((const_cast<tree*> (tree_operand_check ((arg0), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2353, __FUNCTION__))))); | ||||||
2354 | if (DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2354, __FUNCTION__))->decl_minimal.name) == heap_uninit_identifiercp_global_trees[CPTI_HEAP_UNINIT_IDENTIFIER] | ||||||
2355 | || DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2355, __FUNCTION__))->decl_minimal.name) == heap_identifiercp_global_trees[CPTI_HEAP_IDENTIFIER]) | ||||||
2356 | { | ||||||
2357 | if (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2357, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2357, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2357, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2357, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2357, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) | ||||||
2358 | & OVL_OP_FLAG_VEC) | ||||||
2359 | { | ||||||
2360 | if (!ctx->quiet) | ||||||
2361 | { | ||||||
2362 | error_at (loc, "array deallocation of object " | ||||||
2363 | "allocated with non-array " | ||||||
2364 | "allocation"); | ||||||
2365 | inform (DECL_SOURCE_LOCATION (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2365, __FUNCTION__))->decl_minimal.locus), | ||||||
2366 | "allocation performed here"); | ||||||
2367 | } | ||||||
2368 | *non_constant_p = true; | ||||||
2369 | return t; | ||||||
2370 | } | ||||||
2371 | DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2371, __FUNCTION__))->decl_minimal.name) = heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]; | ||||||
2372 | ctx->global->values.remove (var); | ||||||
2373 | ctx->global->heap_dealloc_count++; | ||||||
2374 | return void_nodeglobal_trees[TI_VOID]; | ||||||
2375 | } | ||||||
2376 | else if (DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2376, __FUNCTION__))->decl_minimal.name) == heap_vec_uninit_identifiercp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER] | ||||||
2377 | || DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2377, __FUNCTION__))->decl_minimal.name) == heap_vec_identifiercp_global_trees[CPTI_HEAP_VEC_IDENTIFIER]) | ||||||
2378 | { | ||||||
2379 | if ((IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2379, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2379, __FUNCTION__, (IDENTIFIER_NODE)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2379, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2379, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2379, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) | ||||||
2380 | & OVL_OP_FLAG_VEC) == 0) | ||||||
2381 | { | ||||||
2382 | if (!ctx->quiet) | ||||||
2383 | { | ||||||
2384 | error_at (loc, "non-array deallocation of " | ||||||
2385 | "object allocated with array " | ||||||
2386 | "allocation"); | ||||||
2387 | inform (DECL_SOURCE_LOCATION (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2387, __FUNCTION__))->decl_minimal.locus), | ||||||
2388 | "allocation performed here"); | ||||||
2389 | } | ||||||
2390 | *non_constant_p = true; | ||||||
2391 | return t; | ||||||
2392 | } | ||||||
2393 | DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2393, __FUNCTION__))->decl_minimal.name) = heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]; | ||||||
2394 | ctx->global->values.remove (var); | ||||||
2395 | ctx->global->heap_dealloc_count++; | ||||||
2396 | return void_nodeglobal_trees[TI_VOID]; | ||||||
2397 | } | ||||||
2398 | else if (DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2398, __FUNCTION__))->decl_minimal.name) == heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]) | ||||||
2399 | { | ||||||
2400 | if (!ctx->quiet) | ||||||
2401 | error_at (loc, "deallocation of already deallocated " | ||||||
2402 | "storage"); | ||||||
2403 | *non_constant_p = true; | ||||||
2404 | return t; | ||||||
2405 | } | ||||||
2406 | } | ||||||
2407 | if (!ctx->quiet) | ||||||
2408 | error_at (loc, "deallocation of storage that was " | ||||||
2409 | "not previously allocated"); | ||||||
2410 | *non_constant_p = true; | ||||||
2411 | return t; | ||||||
2412 | } | ||||||
2413 | } | ||||||
2414 | /* Allow placement new in std::construct_at, just return the second | ||||||
2415 | argument. */ | ||||||
2416 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR | ||||||
2417 | && cxx_placement_new_fn (fun) | ||||||
2418 | && ctx->call | ||||||
2419 | && ctx->call->fundef | ||||||
2420 | && is_std_construct_at (ctx->call->fundef->decl)) | ||||||
2421 | { | ||||||
2422 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2422, __FUNCTION__))->exp.operands[0]), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2422, __FUNCTION__)))) - 3); | ||||||
2423 | tree arg1 = NULL_TREE(tree) nullptr; | ||||||
2424 | for (int i = 0; i < nargs; ++i) | ||||||
2425 | { | ||||||
2426 | tree arg = CALL_EXPR_ARG (t, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2426, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2426, __FUNCTION__))))); | ||||||
2427 | arg = cxx_eval_constant_expression (ctx, arg, false, | ||||||
2428 | non_constant_p, overflow_p); | ||||||
2429 | if (i == 1) | ||||||
2430 | arg1 = arg; | ||||||
2431 | else | ||||||
2432 | VERIFY_CONSTANT (arg)do { if (verify_constant ((arg), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
2433 | } | ||||||
2434 | gcc_assert (arg1)((void)(!(arg1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2434, __FUNCTION__), 0 : 0)); | ||||||
2435 | return arg1; | ||||||
2436 | } | ||||||
2437 | else if (cxx_dynamic_cast_fn_p (fun)) | ||||||
2438 | return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p); | ||||||
2439 | |||||||
2440 | if (!ctx->quiet) | ||||||
2441 | { | ||||||
2442 | if (!lambda_static_thunk_p (fun)) | ||||||
2443 | error_at (loc, "call to non-%<constexpr%> function %qD", fun); | ||||||
2444 | explain_invalid_constexpr_fn (fun); | ||||||
2445 | } | ||||||
2446 | *non_constant_p = true; | ||||||
2447 | return t; | ||||||
2448 | } | ||||||
2449 | |||||||
2450 | constexpr_ctx new_ctx = *ctx; | ||||||
2451 | if (DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2451, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2451, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) && !ctx->object | ||||||
2452 | && TREE_CODE (t)((enum tree_code) (t)->base.code) == AGGR_INIT_EXPR) | ||||||
2453 | { | ||||||
2454 | /* We want to have an initialization target for an AGGR_INIT_EXPR. | ||||||
2455 | If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */ | ||||||
2456 | new_ctx.object = AGGR_INIT_EXPR_SLOT (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2456, __FUNCTION__, (AGGR_INIT_EXPR)))), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2456, __FUNCTION__))))); | ||||||
2457 | tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2457, __FUNCTION__))->decl_minimal.context), NULLnullptr); | ||||||
2458 | CONSTRUCTOR_NO_CLEARING (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2458, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = true; | ||||||
2459 | ctx->global->values.put (new_ctx.object, ctor); | ||||||
2460 | ctx = &new_ctx; | ||||||
2461 | } | ||||||
2462 | |||||||
2463 | /* Shortcut trivial constructor/op=. */ | ||||||
2464 | if (trivial_fn_p (fun)) | ||||||
2465 | { | ||||||
2466 | tree init = NULL_TREE(tree) nullptr; | ||||||
2467 | if (call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2467, __FUNCTION__))->exp.operands[0]), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2467, __FUNCTION__)))) - 3) == 2) | ||||||
2468 | init = convert_from_reference (get_nth_callarg (t, 1)); | ||||||
2469 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == AGGR_INIT_EXPR | ||||||
2470 | && AGGR_INIT_ZERO_FIRST (t)((tree_not_check2 (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2470, __FUNCTION__, (AGGR_INIT_EXPR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2470, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) | ||||||
2471 | init = build_zero_init (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2471, __FUNCTION__))->decl_minimal.context), NULL_TREE(tree) nullptr, false); | ||||||
2472 | if (init) | ||||||
2473 | { | ||||||
2474 | tree op = get_nth_callarg (t, 0); | ||||||
2475 | if (is_dummy_object (op)) | ||||||
2476 | op = ctx->object; | ||||||
2477 | else | ||||||
2478 | op = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (op))((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2478, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2478, __FUNCTION__))->typed.type), op); | ||||||
2479 | tree set = build2 (MODIFY_EXPR, TREE_TYPE (op)((contains_struct_check ((op), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2479, __FUNCTION__))->typed.type), op, init); | ||||||
2480 | new_ctx.call = &new_call; | ||||||
2481 | return cxx_eval_constant_expression (&new_ctx, set, lval, | ||||||
2482 | non_constant_p, overflow_p); | ||||||
2483 | } | ||||||
2484 | } | ||||||
2485 | |||||||
2486 | /* We can't defer instantiating the function any longer. */ | ||||||
2487 | if (!DECL_INITIAL (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2487, __FUNCTION__))->decl_common.initial) | ||||||
2488 | && DECL_TEMPLOID_INSTANTIATION (fun)(((((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2488, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2488, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2488, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2488, __FUNCTION__))->decl_common.lang_specific) ->u. min.template_info) && !(((contains_struct_check ((fun ), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2488, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) | ||||||
2489 | && !uid_sensitive_constexpr_evaluation_p ()) | ||||||
2490 | { | ||||||
2491 | location_t save_loc = input_location; | ||||||
2492 | input_location = loc; | ||||||
2493 | ++function_depth; | ||||||
2494 | instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false); | ||||||
2495 | --function_depth; | ||||||
2496 | input_location = save_loc; | ||||||
2497 | } | ||||||
2498 | |||||||
2499 | /* If in direct recursive call, optimize definition search. */ | ||||||
2500 | if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun) | ||||||
2501 | new_call.fundef = ctx->call->fundef; | ||||||
2502 | else | ||||||
2503 | { | ||||||
2504 | new_call.fundef = retrieve_constexpr_fundef (fun); | ||||||
2505 | if (new_call.fundef == NULLnullptr || new_call.fundef->body == NULLnullptr | ||||||
2506 | || new_call.fundef->result == error_mark_nodeglobal_trees[TI_ERROR_MARK] | ||||||
2507 | || fun == current_function_decl) | ||||||
2508 | { | ||||||
2509 | if (!ctx->quiet) | ||||||
2510 | { | ||||||
2511 | /* We need to check for current_function_decl here in case we're | ||||||
2512 | being called during cp_fold_function, because at that point | ||||||
2513 | DECL_INITIAL is set properly and we have a fundef but we | ||||||
2514 | haven't lowered invisirefs yet (c++/70344). */ | ||||||
2515 | if (DECL_INITIAL (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2515, __FUNCTION__))->decl_common.initial) == error_mark_nodeglobal_trees[TI_ERROR_MARK] | ||||||
2516 | || fun == current_function_decl) | ||||||
2517 | error_at (loc, "%qD called in a constant expression before its " | ||||||
2518 | "definition is complete", fun); | ||||||
2519 | else if (DECL_INITIAL (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2519, __FUNCTION__))->decl_common.initial)) | ||||||
2520 | { | ||||||
2521 | /* The definition of fun was somehow unsuitable. But pretend | ||||||
2522 | that lambda static thunks don't exist. */ | ||||||
2523 | if (!lambda_static_thunk_p (fun)) | ||||||
2524 | error_at (loc, "%qD called in a constant expression", fun); | ||||||
2525 | explain_invalid_constexpr_fn (fun); | ||||||
2526 | } | ||||||
2527 | else | ||||||
2528 | error_at (loc, "%qD used before its definition", fun); | ||||||
2529 | } | ||||||
2530 | *non_constant_p = true; | ||||||
2531 | return t; | ||||||
2532 | } | ||||||
2533 | } | ||||||
2534 | |||||||
2535 | bool non_constant_args = false; | ||||||
2536 | cxx_bind_parameters_in_call (ctx, t, &new_call, | ||||||
2537 | non_constant_p, overflow_p, &non_constant_args); | ||||||
2538 | |||||||
2539 | /* We build up the bindings list before we know whether we already have this | ||||||
2540 | call cached. If we don't end up saving these bindings, ggc_free them when | ||||||
2541 | this function exits. */ | ||||||
2542 | class free_bindings | ||||||
2543 | { | ||||||
2544 | tree *bindings; | ||||||
2545 | public: | ||||||
2546 | free_bindings (tree &b): bindings (&b) { } | ||||||
2547 | ~free_bindings () { if (bindings) ggc_free (*bindings); } | ||||||
2548 | void preserve () { bindings = NULLnullptr; } | ||||||
2549 | } fb (new_call.bindings); | ||||||
2550 | |||||||
2551 | if (*non_constant_p) | ||||||
2552 | return t; | ||||||
2553 | |||||||
2554 | depth_ok = push_cx_call_context (t); | ||||||
2555 | |||||||
2556 | /* Remember the object we are constructing or destructing. */ | ||||||
2557 | tree new_obj = NULL_TREE(tree) nullptr; | ||||||
2558 | if (DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2558, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2558, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) || DECL_DESTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2558, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2558, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | ||||||
2559 | { | ||||||
2560 | /* In a cdtor, it should be the first `this' argument. | ||||||
2561 | At this point it has already been evaluated in the call | ||||||
2562 | to cxx_bind_parameters_in_call. */ | ||||||
2563 | new_obj = TREE_VEC_ELT (new_call.bindings, 0)(*((const_cast<tree *> (tree_vec_elt_check ((new_call.bindings ), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2563, __FUNCTION__))))); | ||||||
2564 | STRIP_NOPS (new_obj)(new_obj) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((new_obj))))); | ||||||
2565 | if (TREE_CODE (new_obj)((enum tree_code) (new_obj)->base.code) == ADDR_EXPR) | ||||||
2566 | new_obj = TREE_OPERAND (new_obj, 0)(*((const_cast<tree*> (tree_operand_check ((new_obj), ( 0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2566, __FUNCTION__))))); | ||||||
2567 | |||||||
2568 | if (ctx->call && ctx->call->fundef | ||||||
2569 | && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl)((tree_check (((((enum tree_code) (ctx->call->fundef-> decl)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((ctx-> call->fundef->decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2569, __FUNCTION__, (TEMPLATE_DECL))))))))->result : ctx ->call->fundef->decl)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2569, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
2570 | { | ||||||
2571 | tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0)(*((const_cast<tree *> (tree_vec_elt_check ((ctx->call ->bindings), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2571, __FUNCTION__))))); | ||||||
2572 | STRIP_NOPS (cur_obj)(cur_obj) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((cur_obj))))); | ||||||
2573 | if (TREE_CODE (cur_obj)((enum tree_code) (cur_obj)->base.code) == ADDR_EXPR) | ||||||
2574 | cur_obj = TREE_OPERAND (cur_obj, 0)(*((const_cast<tree*> (tree_operand_check ((cur_obj), ( 0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2574, __FUNCTION__))))); | ||||||
2575 | if (new_obj == cur_obj) | ||||||
2576 | /* We're calling the target constructor of a delegating | ||||||
2577 | constructor, or accessing a base subobject through a | ||||||
2578 | NOP_EXPR as part of a call to a base constructor, so | ||||||
2579 | there is no new (sub)object. */ | ||||||
2580 | new_obj = NULL_TREE(tree) nullptr; | ||||||
2581 | } | ||||||
2582 | } | ||||||
2583 | |||||||
2584 | tree result = NULL_TREE(tree) nullptr; | ||||||
2585 | |||||||
2586 | constexpr_call *entry = NULLnullptr; | ||||||
2587 | if (depth_ok && !non_constant_args && ctx->strict) | ||||||
2588 | { | ||||||
2589 | new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef); | ||||||
2590 | new_call.hash | ||||||
2591 | = iterative_hash_template_arg (new_call.bindings, new_call.hash); | ||||||
2592 | new_call.hash | ||||||
2593 | = iterative_hash_object (ctx->manifestly_const_eval, new_call.hash)iterative_hash (&ctx->manifestly_const_eval, sizeof (ctx ->manifestly_const_eval), new_call.hash); | ||||||
2594 | |||||||
2595 | /* If we have seen this call before, we are done. */ | ||||||
2596 | maybe_initialize_constexpr_call_table (); | ||||||
2597 | constexpr_call **slot | ||||||
2598 | = constexpr_call_table->find_slot (&new_call, INSERT); | ||||||
2599 | entry = *slot; | ||||||
2600 | if (entry == NULLnullptr) | ||||||
2601 | { | ||||||
2602 | /* Only cache up to constexpr_cache_depth to limit memory use. */ | ||||||
2603 | if (depth_ok < constexpr_cache_depthglobal_options.x_constexpr_cache_depth) | ||||||
2604 | { | ||||||
2605 | /* We need to keep a pointer to the entry, not just the slot, as | ||||||
2606 | the slot can move during evaluation of the body. */ | ||||||
2607 | *slot = entry = ggc_alloc<constexpr_call> (); | ||||||
2608 | *entry = new_call; | ||||||
2609 | fb.preserve (); | ||||||
2610 | } | ||||||
2611 | } | ||||||
2612 | /* Calls that are in progress have their result set to NULL, so that we | ||||||
2613 | can detect circular dependencies. Now that we only cache up to | ||||||
2614 | constexpr_cache_depth this won't catch circular dependencies that | ||||||
2615 | start deeper, but they'll hit the recursion or ops limit. */ | ||||||
2616 | else if (entry->result == NULLnullptr) | ||||||
2617 | { | ||||||
2618 | if (!ctx->quiet) | ||||||
2619 | error ("call has circular dependency"); | ||||||
2620 | *non_constant_p = true; | ||||||
2621 | entry->result = result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
2622 | } | ||||||
2623 | else | ||||||
2624 | result = entry->result; | ||||||
2625 | } | ||||||
2626 | |||||||
2627 | if (!depth_ok) | ||||||
2628 | { | ||||||
2629 | if (!ctx->quiet) | ||||||
2630 | error ("%<constexpr%> evaluation depth exceeds maximum of %d (use " | ||||||
2631 | "%<-fconstexpr-depth=%> to increase the maximum)", | ||||||
2632 | max_constexpr_depthglobal_options.x_max_constexpr_depth); | ||||||
2633 | *non_constant_p = true; | ||||||
2634 | result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
2635 | } | ||||||
2636 | else | ||||||
2637 | { | ||||||
2638 | bool cacheable = true; | ||||||
2639 | if (result && result != error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
2640 | /* OK */; | ||||||
2641 | else if (!DECL_SAVED_TREE (fun)((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2641, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree )) | ||||||
2642 | { | ||||||
2643 | /* When at_eof >= 2, cgraph has started throwing away | ||||||
2644 | DECL_SAVED_TREE, so fail quietly. FIXME we get here because of | ||||||
2645 | late code generation for VEC_INIT_EXPR, which needs to be | ||||||
2646 | completely reconsidered. */ | ||||||
2647 | gcc_assert (at_eof >= 2 && ctx->quiet)((void)(!(at_eof >= 2 && ctx->quiet) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2647, __FUNCTION__), 0 : 0)); | ||||||
2648 | *non_constant_p = true; | ||||||
2649 | } | ||||||
2650 | else if (tree copy = get_fundef_copy (new_call.fundef)) | ||||||
2651 | { | ||||||
2652 | tree body, parms, res; | ||||||
2653 | releasing_vec ctors; | ||||||
2654 | |||||||
2655 | /* Reuse or create a new unshared copy of this function's body. */ | ||||||
2656 | body = TREE_PURPOSE (copy)((tree_check ((copy), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2656, __FUNCTION__, (TREE_LIST)))->list.purpose); | ||||||
2657 | parms = TREE_VALUE (copy)((tree_check ((copy), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2657, __FUNCTION__, (TREE_LIST)))->list.value); | ||||||
2658 | res = TREE_TYPE (copy)((contains_struct_check ((copy), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2658, __FUNCTION__))->typed.type); | ||||||
2659 | |||||||
2660 | /* Associate the bindings with the remapped parms. */ | ||||||
2661 | tree bound = new_call.bindings; | ||||||
2662 | tree remapped = parms; | ||||||
2663 | for (int i = 0; i < TREE_VEC_LENGTH (bound)((tree_check ((bound), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2663, __FUNCTION__, (TREE_VEC)))->base.u.length); ++i) | ||||||
2664 | { | ||||||
2665 | tree arg = TREE_VEC_ELT (bound, i)(*((const_cast<tree *> (tree_vec_elt_check ((bound), (i ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2665, __FUNCTION__))))); | ||||||
2666 | if (entry) | ||||||
2667 | { | ||||||
2668 | /* Unshare args going into the hash table to separate them | ||||||
2669 | from the caller's context, for better GC and to avoid | ||||||
2670 | problems with verify_gimple. */ | ||||||
2671 | arg = unshare_expr_without_location (arg); | ||||||
2672 | TREE_VEC_ELT (bound, i)(*((const_cast<tree *> (tree_vec_elt_check ((bound), (i ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2672, __FUNCTION__))))) = arg; | ||||||
2673 | |||||||
2674 | /* And then unshare again so the callee doesn't change the | ||||||
2675 | argument values in the hash table. XXX Could we unshare | ||||||
2676 | lazily in cxx_eval_store_expression? */ | ||||||
2677 | arg = unshare_constructor (arg); | ||||||
2678 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == CONSTRUCTOR) | ||||||
2679 | vec_safe_push (ctors, arg); | ||||||
2680 | } | ||||||
2681 | ctx->global->values.put (remapped, arg); | ||||||
2682 | remapped = DECL_CHAIN (remapped)(((contains_struct_check (((contains_struct_check ((remapped) , (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2682, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2682, __FUNCTION__))->common.chain)); | ||||||
2683 | } | ||||||
2684 | /* Add the RESULT_DECL to the values map, too. */ | ||||||
2685 | gcc_assert (!DECL_BY_REFERENCE (res))((void)(!(!((tree_check3 ((res), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2685, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) )->decl_common.decl_by_reference_flag)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2685, __FUNCTION__), 0 : 0)); | ||||||
2686 | ctx->global->values.put (res, NULL_TREE(tree) nullptr); | ||||||
2687 | |||||||
2688 | /* Track the callee's evaluated SAVE_EXPRs and TARGET_EXPRs so that | ||||||
2689 | we can forget their values after the call. */ | ||||||
2690 | constexpr_ctx ctx_with_save_exprs = *ctx; | ||||||
2691 | auto_vec<tree, 10> save_exprs; | ||||||
2692 | ctx_with_save_exprs.save_exprs = &save_exprs; | ||||||
2693 | ctx_with_save_exprs.call = &new_call; | ||||||
2694 | unsigned save_heap_alloc_count = ctx->global->heap_vars.length (); | ||||||
2695 | unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count; | ||||||
2696 | |||||||
2697 | /* If this is a constexpr destructor, the object's const and volatile | ||||||
2698 | semantics are no longer in effect; see [class.dtor]p5. */ | ||||||
2699 | if (new_obj && DECL_DESTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2699, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2699, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | ||||||
2700 | cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false, | ||||||
2701 | non_constant_p, overflow_p); | ||||||
2702 | |||||||
2703 | tree jump_target = NULL_TREE(tree) nullptr; | ||||||
2704 | cxx_eval_constant_expression (&ctx_with_save_exprs, body, | ||||||
2705 | lval, non_constant_p, overflow_p, | ||||||
2706 | &jump_target); | ||||||
2707 | |||||||
2708 | if (DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2708, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2708, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
2709 | /* This can be null for a subobject constructor call, in | ||||||
2710 | which case what we care about is the initialization | ||||||
2711 | side-effects rather than the value. We could get at the | ||||||
2712 | value by evaluating *this, but we don't bother; there's | ||||||
2713 | no need to put such a call in the hash table. */ | ||||||
2714 | result = lval ? ctx->object : ctx->ctor; | ||||||
2715 | else if (VOID_TYPE_P (TREE_TYPE (res))(((enum tree_code) (((contains_struct_check ((res), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2715, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) | ||||||
2716 | result = void_nodeglobal_trees[TI_VOID]; | ||||||
2717 | else | ||||||
2718 | { | ||||||
2719 | result = *ctx->global->values.get (res); | ||||||
2720 | if (result == NULL_TREE(tree) nullptr && !*non_constant_p) | ||||||
2721 | { | ||||||
2722 | if (!ctx->quiet) | ||||||
2723 | error ("%<constexpr%> call flows off the end " | ||||||
2724 | "of the function"); | ||||||
2725 | *non_constant_p = true; | ||||||
2726 | } | ||||||
2727 | } | ||||||
2728 | |||||||
2729 | /* At this point, the object's constructor will have run, so | ||||||
2730 | the object is no longer under construction, and its possible | ||||||
2731 | 'const' semantics now apply. Make a note of this fact by | ||||||
2732 | marking the CONSTRUCTOR TREE_READONLY. */ | ||||||
2733 | if (new_obj && DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2733, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2733, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
2734 | cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true, | ||||||
2735 | non_constant_p, overflow_p); | ||||||
2736 | |||||||
2737 | /* Forget the saved values of the callee's SAVE_EXPRs and | ||||||
2738 | TARGET_EXPRs. */ | ||||||
2739 | unsigned int i; | ||||||
2740 | tree save_expr; | ||||||
2741 | FOR_EACH_VEC_ELT (save_exprs, i, save_expr)for (i = 0; (save_exprs).iterate ((i), &(save_expr)); ++( i)) | ||||||
2742 | ctx->global->values.remove (save_expr); | ||||||
2743 | |||||||
2744 | /* Remove the parms/result from the values map. Is it worth | ||||||
2745 | bothering to do this when the map itself is only live for | ||||||
2746 | one constexpr evaluation? If so, maybe also clear out | ||||||
2747 | other vars from call, maybe in BIND_EXPR handling? */ | ||||||
2748 | ctx->global->values.remove (res); | ||||||
2749 | for (tree parm = parms; parm; parm = TREE_CHAIN (parm)((contains_struct_check ((parm), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2749, __FUNCTION__))->common.chain)) | ||||||
2750 | ctx->global->values.remove (parm); | ||||||
2751 | |||||||
2752 | /* Free any parameter CONSTRUCTORs we aren't returning directly. */ | ||||||
2753 | while (!ctors->is_empty ()) | ||||||
2754 | { | ||||||
2755 | tree c = ctors->pop (); | ||||||
2756 | if (c != result) | ||||||
2757 | free_constructor (c); | ||||||
2758 | } | ||||||
2759 | |||||||
2760 | /* Make the unshared function copy we used available for re-use. */ | ||||||
2761 | save_fundef_copy (fun, copy); | ||||||
2762 | |||||||
2763 | /* If the call allocated some heap object that hasn't been | ||||||
2764 | deallocated during the call, or if it deallocated some heap | ||||||
2765 | object it has not allocated, the call isn't really stateless | ||||||
2766 | for the constexpr evaluation and should not be cached. | ||||||
2767 | It is fine if the call allocates something and deallocates it | ||||||
2768 | too. */ | ||||||
2769 | if (entry | ||||||
2770 | && (save_heap_alloc_count != ctx->global->heap_vars.length () | ||||||
2771 | || (save_heap_dealloc_count | ||||||
2772 | != ctx->global->heap_dealloc_count))) | ||||||
2773 | { | ||||||
2774 | tree heap_var; | ||||||
2775 | unsigned int i; | ||||||
2776 | if ((ctx->global->heap_vars.length () | ||||||
2777 | - ctx->global->heap_dealloc_count) | ||||||
2778 | != save_heap_alloc_count - save_heap_dealloc_count) | ||||||
2779 | cacheable = false; | ||||||
2780 | else | ||||||
2781 | FOR_EACH_VEC_ELT_FROM (ctx->global->heap_vars, i, heap_var,for (i = (save_heap_alloc_count); (ctx->global->heap_vars ).iterate ((i), &(heap_var)); ++(i)) | ||||||
2782 | save_heap_alloc_count)for (i = (save_heap_alloc_count); (ctx->global->heap_vars ).iterate ((i), &(heap_var)); ++(i)) | ||||||
2783 | if (DECL_NAME (heap_var)((contains_struct_check ((heap_var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2783, __FUNCTION__))->decl_minimal.name) != heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]) | ||||||
2784 | { | ||||||
2785 | cacheable = false; | ||||||
2786 | break; | ||||||
2787 | } | ||||||
2788 | } | ||||||
2789 | |||||||
2790 | /* Rewrite all occurrences of the function's RESULT_DECL with the | ||||||
2791 | current object under construction. */ | ||||||
2792 | if (!*non_constant_p && ctx->object | ||||||
2793 | && CLASS_TYPE_P (TREE_TYPE (res))(((((enum tree_code) (((contains_struct_check ((res), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2793, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((res), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2793, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((res ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2793, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2793, __FUNCTION__))->type_common.lang_flag_5)) | ||||||
2794 | && !is_empty_class (TREE_TYPE (res)((contains_struct_check ((res), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2794, __FUNCTION__))->typed.type))) | ||||||
2795 | if (replace_result_decl (&result, res, ctx->object)) | ||||||
2796 | cacheable = false; | ||||||
2797 | } | ||||||
2798 | else | ||||||
2799 | /* Couldn't get a function copy to evaluate. */ | ||||||
2800 | *non_constant_p = true; | ||||||
2801 | |||||||
2802 | if (result == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||||
2803 | *non_constant_p = true; | ||||||
2804 | if (*non_constant_p || *overflow_p) | ||||||
2805 | result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
2806 | else if (!result) | ||||||
2807 | result = void_nodeglobal_trees[TI_VOID]; | ||||||
2808 | if (entry) | ||||||
2809 | entry->result = cacheable ? result : error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
2810 | } | ||||||
2811 | |||||||
2812 | /* The result of a constexpr function must be completely initialized. | ||||||
2813 | |||||||
2814 | However, in C++20, a constexpr constructor doesn't necessarily have | ||||||
2815 | to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING | ||||||
2816 | in order to detect reading an unitialized object in constexpr instead | ||||||
2817 | of value-initializing it. (reduced_constant_expression_p is expected to | ||||||
2818 | take care of clearing the flag.) */ | ||||||
2819 | if (TREE_CODE (result)((enum tree_code) (result)->base.code) == CONSTRUCTOR | ||||||
2820 | && (cxx_dialect < cxx20 | ||||||
2821 | || !DECL_CONSTRUCTOR_P (fun)((tree_check (((((enum tree_code) (fun)->base.code) == TEMPLATE_DECL ? ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2821, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2821, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ))) | ||||||
2822 | clear_no_implicit_zero (result); | ||||||
2823 | |||||||
2824 | pop_cx_call_context (); | ||||||
2825 | return result; | ||||||
2826 | } | ||||||
2827 | |||||||
2828 | /* Return true if T is a valid constant initializer. If a CONSTRUCTOR | ||||||
2829 | initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be | ||||||
2830 | cleared. | ||||||
2831 | FIXME speed this up, it's taking 16% of compile time on sieve testcase. */ | ||||||
2832 | |||||||
2833 | bool | ||||||
2834 | reduced_constant_expression_p (tree t) | ||||||
2835 | { | ||||||
2836 | if (t == NULL_TREE(tree) nullptr) | ||||||
2837 | return false; | ||||||
2838 | |||||||
2839 | switch (TREE_CODE (t)((enum tree_code) (t)->base.code)) | ||||||
2840 | { | ||||||
2841 | case PTRMEM_CST: | ||||||
2842 | /* Even if we can't lower this yet, it's constant. */ | ||||||
2843 | return true; | ||||||
2844 | |||||||
2845 | case CONSTRUCTOR: | ||||||
2846 | /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */ | ||||||
2847 | tree idx, val, field; unsigned HOST_WIDE_INTlong i; | ||||||
2848 | if (CONSTRUCTOR_NO_CLEARING (t)((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2848, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) | ||||||
2849 | { | ||||||
2850 | if (TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2850, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE) | ||||||
2851 | /* An initialized vector would have a VECTOR_CST. */ | ||||||
2852 | return false; | ||||||
2853 | else if (cxx_dialect >= cxx20 | ||||||
2854 | /* An ARRAY_TYPE doesn't have any TYPE_FIELDS. */ | ||||||
2855 | && TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2855, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE) | ||||||
2856 | field = NULL_TREE(tree) nullptr; | ||||||
2857 | else if (cxx_dialect >= cxx20 | ||||||
2858 | && TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2858, __FUNCTION__))->typed.type))->base.code) == UNION_TYPE) | ||||||
2859 | { | ||||||
2860 | if (CONSTRUCTOR_NELTS (t)(vec_safe_length (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2860, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) == 0) | ||||||
2861 | /* An initialized union has a constructor element. */ | ||||||
2862 | return false; | ||||||
2863 | /* And it only initializes one member. */ | ||||||
2864 | field = NULL_TREE(tree) nullptr; | ||||||
2865 | } | ||||||
2866 | else | ||||||
2867 | field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t))((tree_check3 ((((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2867, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2867, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values)); | ||||||
2868 | } | ||||||
2869 | else | ||||||
2870 | field = NULL_TREE(tree) nullptr; | ||||||
2871 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, idx, val)for (i = 0; (i >= vec_safe_length (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2871, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : (((void) (val = (*((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2871, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].value)), (idx = (*((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2871, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].index), true); (i)++) | ||||||
2872 | { | ||||||
2873 | /* If VAL is null, we're in the middle of initializing this | ||||||
2874 | element. */ | ||||||
2875 | if (!reduced_constant_expression_p (val)) | ||||||
2876 | return false; | ||||||
2877 | /* Empty class field may or may not have an initializer. */ | ||||||
2878 | for (; field && idx != field; | ||||||
2879 | field = next_initializable_field (DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2879, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2879, __FUNCTION__))->common.chain)))) | ||||||
2880 | if (!is_really_empty_class (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2880, __FUNCTION__))->typed.type), | ||||||
2881 | /*ignore_vptr*/false)) | ||||||
2882 | return false; | ||||||
2883 | if (field) | ||||||
2884 | field = next_initializable_field (DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2884, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2884, __FUNCTION__))->common.chain))); | ||||||
2885 | } | ||||||
2886 | /* There could be a non-empty field at the end. */ | ||||||
2887 | for (; field; field = next_initializable_field (DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2887, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2887, __FUNCTION__))->common.chain)))) | ||||||
2888 | if (!is_really_empty_class (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2888, __FUNCTION__))->typed.type), /*ignore_vptr*/false)) | ||||||
2889 | return false; | ||||||
2890 | if (CONSTRUCTOR_NO_CLEARING (t)((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2890, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) | ||||||
2891 | /* All the fields are initialized. */ | ||||||
2892 | CONSTRUCTOR_NO_CLEARING (t)((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2892, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = false; | ||||||
2893 | return true; | ||||||
2894 | |||||||
2895 | default: | ||||||
2896 | /* FIXME are we calling this too much? */ | ||||||
2897 | return initializer_constant_valid_p (t, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2897, __FUNCTION__))->typed.type)) != NULL_TREE(tree) nullptr; | ||||||
2898 | } | ||||||
2899 | } | ||||||
2900 | |||||||
2901 | /* Some expressions may have constant operands but are not constant | ||||||
2902 | themselves, such as 1/0. Call this function to check for that | ||||||
2903 | condition. | ||||||
2904 | |||||||
2905 | We only call this in places that require an arithmetic constant, not in | ||||||
2906 | places where we might have a non-constant expression that can be a | ||||||
2907 | component of a constant expression, such as the address of a constexpr | ||||||
2908 | variable that might be dereferenced later. */ | ||||||
2909 | |||||||
2910 | static bool | ||||||
2911 | verify_constant (tree t, bool allow_non_constant, bool *non_constant_p, | ||||||
2912 | bool *overflow_p) | ||||||
2913 | { | ||||||
2914 | if (!*non_constant_p && !reduced_constant_expression_p (t) | ||||||
2915 | && t != void_nodeglobal_trees[TI_VOID]) | ||||||
2916 | { | ||||||
2917 | if (!allow_non_constant) | ||||||
2918 | error ("%q+E is not a constant expression", t); | ||||||
2919 | *non_constant_p = true; | ||||||
2920 | } | ||||||
2921 | if (TREE_OVERFLOW_P (t)((tree_code_type[(int) (((enum tree_code) (t)->base.code)) ] == tcc_constant) && ((tree_class_check ((t), (tcc_constant ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2921, __FUNCTION__))->base.public_flag))) | ||||||
2922 | { | ||||||
2923 | if (!allow_non_constant) | ||||||
2924 | { | ||||||
2925 | permerror (input_location, "overflow in constant expression"); | ||||||
2926 | /* If we're being permissive (and are in an enforcing | ||||||
2927 | context), ignore the overflow. */ | ||||||
2928 | if (flag_permissiveglobal_options.x_flag_permissive) | ||||||
2929 | return *non_constant_p; | ||||||
2930 | } | ||||||
2931 | *overflow_p = true; | ||||||
2932 | } | ||||||
2933 | return *non_constant_p; | ||||||
2934 | } | ||||||
2935 | |||||||
2936 | /* Check whether the shift operation with code CODE and type TYPE on LHS | ||||||
2937 | and RHS is undefined. If it is, give an error with an explanation, | ||||||
2938 | and return true; return false otherwise. */ | ||||||
2939 | |||||||
2940 | static bool | ||||||
2941 | cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx, | ||||||
2942 | enum tree_code code, tree type, tree lhs, tree rhs) | ||||||
2943 | { | ||||||
2944 | if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR) | ||||||
2945 | || TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) != INTEGER_CST | ||||||
2946 | || TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) != INTEGER_CST) | ||||||
2947 | return false; | ||||||
2948 | |||||||
2949 | tree lhstype = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2949, __FUNCTION__))->typed.type); | ||||||
2950 | unsigned HOST_WIDE_INTlong uprec = TYPE_PRECISION (TREE_TYPE (lhs))((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2950, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2950, __FUNCTION__))->type_common.precision); | ||||||
2951 | |||||||
2952 | /* [expr.shift] The behavior is undefined if the right operand | ||||||
2953 | is negative, or greater than or equal to the length in bits | ||||||
2954 | of the promoted left operand. */ | ||||||
2955 | if (tree_int_cst_sgn (rhs) == -1) | ||||||
2956 | { | ||||||
2957 | if (!ctx->quiet) | ||||||
2958 | permerror (loc, "right operand of shift expression %q+E is negative", | ||||||
2959 | build2_loc (loc, code, type, lhs, rhs)); | ||||||
2960 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); | ||||||
2961 | } | ||||||
2962 | if (compare_tree_int (rhs, uprec) >= 0) | ||||||
2963 | { | ||||||
2964 | if (!ctx->quiet) | ||||||
2965 | permerror (loc, "right operand of shift expression %q+E is greater " | ||||||
2966 | "than or equal to the precision %wu of the left operand", | ||||||
2967 | build2_loc (loc, code, type, lhs, rhs), uprec); | ||||||
2968 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); | ||||||
2969 | } | ||||||
2970 | |||||||
2971 | /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...] | ||||||
2972 | if E1 has a signed type and non-negative value, and E1x2^E2 is | ||||||
2973 | representable in the corresponding unsigned type of the result type, | ||||||
2974 | then that value, converted to the result type, is the resulting value; | ||||||
2975 | otherwise, the behavior is undefined. | ||||||
2976 | For C++20: | ||||||
2977 | The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo | ||||||
2978 | 2^N, where N is the range exponent of the type of the result. */ | ||||||
2979 | if (code == LSHIFT_EXPR | ||||||
2980 | && !TYPE_UNSIGNED (lhstype)((tree_class_check ((lhstype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 2980, __FUNCTION__))->base.u.bits.unsigned_flag) | ||||||
2981 | && cxx_dialect >= cxx11 | ||||||
2982 | && cxx_dialect < cxx20) | ||||||
2983 | { | ||||||
2984 | if (tree_int_cst_sgn (lhs) == -1) | ||||||
2985 | { | ||||||
2986 | if (!ctx->quiet) | ||||||
2987 | permerror (loc, | ||||||
2988 | "left operand of shift expression %q+E is negative", | ||||||
2989 | build2_loc (loc, code, type, lhs, rhs)); | ||||||
2990 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); | ||||||
2991 | } | ||||||
2992 | /* For signed x << y the following: | ||||||
2993 | (unsigned) x >> ((prec (lhs) - 1) - y) | ||||||
2994 | if > 1, is undefined. The right-hand side of this formula | ||||||
2995 | is the highest bit of the LHS that can be set (starting from 0), | ||||||
2996 | so that the shift doesn't overflow. We then right-shift the LHS | ||||||
2997 | to see whether any other bit is set making the original shift | ||||||
2998 | undefined -- the result is not representable in the corresponding | ||||||
2999 | unsigned type. */ | ||||||
3000 | tree t = build_int_cst (unsigned_type_nodeinteger_types[itk_unsigned_int], uprec - 1); | ||||||
3001 | t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs)fold_build2_loc (((location_t) 0), MINUS_EXPR, integer_types[ itk_unsigned_int], t, rhs ); | ||||||
3002 | tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs)fold_convert_loc (((location_t) 0), unsigned_type_for (lhstype ), lhs); | ||||||
3003 | t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t)fold_build2_loc (((location_t) 0), RSHIFT_EXPR, ((contains_struct_check ((ulhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3003, __FUNCTION__))->typed.type), ulhs, t ); | ||||||
3004 | if (tree_int_cst_lt (integer_one_nodeglobal_trees[TI_INTEGER_ONE], t)) | ||||||
3005 | { | ||||||
3006 | if (!ctx->quiet) | ||||||
3007 | permerror (loc, "shift expression %q+E overflows", | ||||||
3008 | build2_loc (loc, code, type, lhs, rhs)); | ||||||
3009 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); | ||||||
3010 | } | ||||||
3011 | } | ||||||
3012 | return false; | ||||||
3013 | } | ||||||
3014 | |||||||
3015 | /* Subroutine of cxx_eval_constant_expression. | ||||||
3016 | Attempt to reduce the unary expression tree T to a compile time value. | ||||||
3017 | If successful, return the value. Otherwise issue a diagnostic | ||||||
3018 | and return error_mark_node. */ | ||||||
3019 | |||||||
3020 | static tree | ||||||
3021 | cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t, | ||||||
3022 | bool /*lval*/, | ||||||
3023 | bool *non_constant_p, bool *overflow_p) | ||||||
3024 | { | ||||||
3025 | tree r; | ||||||
3026 | tree orig_arg = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3026, __FUNCTION__))))); | ||||||
3027 | tree arg = cxx_eval_constant_expression (ctx, orig_arg, /*lval*/false, | ||||||
3028 | non_constant_p, overflow_p); | ||||||
3029 | VERIFY_CONSTANT (arg)do { if (verify_constant ((arg), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3030 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); | ||||||
3031 | enum tree_code code = TREE_CODE (t)((enum tree_code) (t)->base.code); | ||||||
3032 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3032, __FUNCTION__))->typed.type); | ||||||
3033 | r = fold_unary_loc (loc, code, type, arg); | ||||||
3034 | if (r == NULL_TREE(tree) nullptr) | ||||||
3035 | { | ||||||
3036 | if (arg == orig_arg) | ||||||
3037 | r = t; | ||||||
3038 | else | ||||||
3039 | r = build1_loc (loc, code, type, arg); | ||||||
3040 | } | ||||||
3041 | VERIFY_CONSTANT (r)do { if (verify_constant ((r), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0); | ||||||
3042 | return r; | ||||||
3043 | } | ||||||
3044 | |||||||
3045 | /* Helper function for cxx_eval_binary_expression. Try to optimize | ||||||
3046 | original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the | ||||||
3047 | generic folding should be used. */ | ||||||
3048 | |||||||
3049 | static tree | ||||||
3050 | cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t, | ||||||
3051 | tree lhs, tree rhs, bool *non_constant_p, | ||||||
3052 | bool *overflow_p) | ||||||
3053 | { | ||||||
3054 | STRIP_NOPS (lhs)(lhs) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((lhs))))); | ||||||
3055 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) != ADDR_EXPR) | ||||||
3056 | return NULL_TREE(tree) nullptr; | ||||||
3057 | |||||||
3058 | lhs = TREE_OPERAND (lhs, 0)(*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3058, __FUNCTION__))))); | ||||||
3059 | |||||||
3060 | /* &A[i] p+ j => &A[i + j] */ | ||||||
3061 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == ARRAY_REF | ||||||
3062 | && TREE_CODE (TREE_OPERAND (lhs, 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3062, __FUNCTION__))))))->base.code) == INTEGER_CST | ||||||
3063 | && TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == INTEGER_CST | ||||||
3064 | && TYPE_SIZE_UNIT (TREE_TYPE (lhs))((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3064, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3064, __FUNCTION__))->type_common.size_unit) | ||||||
3065 | && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))((enum tree_code) (((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3065, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3065, __FUNCTION__))->type_common.size_unit))->base.code ) == INTEGER_CST) | ||||||
3066 | { | ||||||
3067 | tree orig_type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3067, __FUNCTION__))->typed.type); | ||||||
3068 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); | ||||||
3069 | tree type = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3069, __FUNCTION__))->typed.type); | ||||||
3070 | |||||||
3071 | t = fold_convert_loc (loc, ssizetypesizetype_tab[(int) stk_ssizetype], TREE_OPERAND (lhs, 1)(*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3071, __FUNCTION__)))))); | ||||||
3072 | tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3072, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3072, __FUNCTION__))->typed.type)); | ||||||
3073 | nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p, | ||||||
3074 | overflow_p); | ||||||
3075 | if (*non_constant_p) | ||||||
3076 | return NULL_TREE(tree) nullptr; | ||||||
3077 | /* Don't fold an out-of-bound access. */ | ||||||
3078 | if (!tree_int_cst_le (t, nelts)) | ||||||
3079 | return NULL_TREE(tree) nullptr; | ||||||
3080 | rhs = cp_fold_convert (ssizetypesizetype_tab[(int) stk_ssizetype], rhs); | ||||||
3081 | /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT. | ||||||
3082 | constexpr int A[1]; ... (char *)&A[0] + 1 */ | ||||||
3083 | if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetypesizetype_tab[(int) stk_sizetype], | ||||||
3084 | rhs, TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3084, __FUNCTION__))->type_common.size_unit)))) | ||||||
3085 | return NULL_TREE(tree) nullptr; | ||||||
3086 | /* Make sure to treat the second operand of POINTER_PLUS_EXPR | ||||||
3087 | as signed. */ | ||||||
3088 | rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetypesizetype_tab[(int) stk_ssizetype], rhs, | ||||||
3089 | TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3089, __FUNCTION__))->type_common.size_unit)); | ||||||
3090 | t = size_binop_loc (loc, PLUS_EXPR, rhs, t); | ||||||
3091 | t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0)(*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3091, __FUNCTION__))))), | ||||||
3092 | t, NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr); | ||||||
3093 | t = cp_build_addr_expr (t, tf_warning_or_error); | ||||||
3094 | t = cp_fold_convert (orig_type, t); | ||||||
3095 | return cxx_eval_constant_expression (ctx, t, /*lval*/false, | ||||||
3096 | non_constant_p, overflow_p); | ||||||
3097 | } | ||||||
3098 | |||||||
3099 | return NULL_TREE(tree) nullptr; | ||||||
3100 | } | ||||||
3101 | |||||||
3102 | /* Subroutine of cxx_eval_constant_expression. | ||||||
3103 | Like cxx_eval_unary_expression, except for binary expressions. */ | ||||||
3104 | |||||||
3105 | static tree | ||||||
3106 | cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, | ||||||
3107 | bool lval, | ||||||
3108 | bool *non_constant_p, bool *overflow_p) | ||||||
3109 | { | ||||||
3110 | tree r = NULL_TREE(tree) nullptr; | ||||||
3111 | tree orig_lhs = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3111, __FUNCTION__))))); | ||||||
3112 | tree orig_rhs = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3112, __FUNCTION__))))); | ||||||
3113 | tree lhs, rhs; | ||||||
3114 | lhs = cxx_eval_constant_expression (ctx, orig_lhs, /*lval*/false, | ||||||
3115 | non_constant_p, overflow_p); | ||||||
3116 | /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer | ||||||
3117 | subtraction. */ | ||||||
3118 | if (*non_constant_p) | ||||||
3119 | return t; | ||||||
3120 | rhs = cxx_eval_constant_expression (ctx, orig_rhs, /*lval*/false, | ||||||
3121 | non_constant_p, overflow_p); | ||||||
3122 | if (*non_constant_p) | ||||||
3123 | return t; | ||||||
3124 | |||||||
3125 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); | ||||||
3126 | enum tree_code code = TREE_CODE (t)((enum tree_code) (t)->base.code); | ||||||
3127 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3127, __FUNCTION__))->typed.type); | ||||||
3128 | |||||||
3129 | if (code == EQ_EXPR || code == NE_EXPR) | ||||||
3130 | { | ||||||
3131 | bool is_code_eq = (code == EQ_EXPR); | ||||||
3132 | |||||||
3133 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == PTRMEM_CST | ||||||
3134 | && TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == PTRMEM_CST) | ||||||
3135 | { | ||||||
3136 | tree lmem = PTRMEM_CST_MEMBER (lhs)(((ptrmem_cst_t)(tree_check ((lhs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3136, __FUNCTION__, (PTRMEM_CST))))->member); | ||||||
3137 | tree rmem = PTRMEM_CST_MEMBER (rhs)(((ptrmem_cst_t)(tree_check ((rhs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3137, __FUNCTION__, (PTRMEM_CST))))->member); | ||||||
3138 | bool eq; | ||||||
3139 | if (TREE_CODE (lmem)((enum tree_code) (lmem)->base.code) == TREE_CODE (rmem)((enum tree_code) (rmem)->base.code) | ||||||
3140 | && TREE_CODE (lmem)((enum tree_code) (lmem)->base.code) == FIELD_DECL | ||||||
3141 | && TREE_CODE (DECL_CONTEXT (lmem))((enum tree_code) (((contains_struct_check ((lmem), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3141, __FUNCTION__))->decl_minimal.context))->base.code ) == UNION_TYPE | ||||||
3142 | && same_type_p (DECL_CONTEXT (lmem),comptypes ((((contains_struct_check ((lmem), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3142, __FUNCTION__))->decl_minimal.context)), (((contains_struct_check ((rmem), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3143, __FUNCTION__))->decl_minimal.context)), 0) | ||||||
3143 | DECL_CONTEXT (rmem))comptypes ((((contains_struct_check ((lmem), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3142, __FUNCTION__))->decl_minimal.context)), (((contains_struct_check ((rmem), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3143, __FUNCTION__))->decl_minimal.context)), 0)) | ||||||
3144 | /* If both refer to (possibly different) members of the same union | ||||||
3145 | (12.3), they compare equal. */ | ||||||
3146 | eq = true; | ||||||
3147 | else | ||||||
3148 | eq = cp_tree_equal (lhs, rhs); | ||||||
3149 | r = constant_boolean_node (eq == is_code_eq, type); | ||||||
3150 | } | ||||||
3151 | else if ((TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == PTRMEM_CST | ||||||
3152 | || TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == PTRMEM_CST) | ||||||
3153 | && (null_member_pointer_value_p (lhs) | ||||||
3154 | || null_member_pointer_value_p (rhs))) | ||||||
3155 | r = constant_boolean_node (!is_code_eq, type); | ||||||
3156 | else if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == PTRMEM_CST) | ||||||
3157 | lhs = cplus_expand_constant (lhs); | ||||||
3158 | else if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == PTRMEM_CST) | ||||||
3159 | rhs = cplus_expand_constant (rhs); | ||||||
3160 | } | ||||||
3161 | if (code == POINTER_PLUS_EXPR && !*non_constant_p | ||||||
3162 | && integer_zerop (lhs) && !integer_zerop (rhs)) | ||||||
3163 | { | ||||||
3164 | if (!ctx->quiet) | ||||||
3165 | error ("arithmetic involving a null pointer in %qE", lhs); | ||||||
3166 | *non_constant_p = true; | ||||||
3167 | return t; | ||||||
3168 | } | ||||||
3169 | else if (code == POINTER_PLUS_EXPR) | ||||||
3170 | r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p, | ||||||
3171 | overflow_p); | ||||||
3172 | else if (code == SPACESHIP_EXPR) | ||||||
3173 | { | ||||||
3174 | r = genericize_spaceship (loc, type, lhs, rhs); | ||||||
3175 | return cxx_eval_constant_expression (ctx, r, lval, non_constant_p, | ||||||
3176 | overflow_p); | ||||||
3177 | } | ||||||
3178 | |||||||
3179 | if (r == NULL_TREE(tree) nullptr) | ||||||
3180 | r = fold_binary_loc (loc, code, type, lhs, rhs); | ||||||
3181 | |||||||
3182 | if (r == NULL_TREE(tree) nullptr | ||||||
3183 | && (code == LSHIFT_EXPR || code == RSHIFT_EXPR) | ||||||
3184 | && TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == INTEGER_CST | ||||||
3185 | && TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == INTEGER_CST | ||||||
3186 | && wi::neg_p (wi::to_wide (rhs))) | ||||||
3187 | { | ||||||
3188 | /* For diagnostics and -fpermissive emulate previous behavior of | ||||||
3189 | handling shifts by negative amount. */ | ||||||
3190 | tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3190, __FUNCTION__))->typed.type), rhs); | ||||||
3191 | if (nrhs) | ||||||
3192 | r = fold_binary_loc (loc, | ||||||
3193 | code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR, | ||||||
3194 | type, lhs, nrhs); | ||||||
3195 | } | ||||||
3196 | |||||||
3197 | if (r == NULL_TREE(tree) nullptr) | ||||||
3198 | { | ||||||
3199 | if (lhs == orig_lhs && rhs == orig_rhs) | ||||||
3200 | r = t; | ||||||
3201 | else | ||||||
3202 | r = build2_loc (loc, code, type, lhs, rhs); | ||||||
3203 | } | ||||||
3204 | else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs)) | ||||||
3205 | *non_constant_p = true; | ||||||
3206 | /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to | ||||||
3207 | a local array in a constexpr function. */ | ||||||
3208 | bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs))((((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3208, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE ) || (((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3208, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )); | ||||||
3209 | if (!ptr) | ||||||
3210 | VERIFY_CONSTANT (r)do { if (verify_constant ((r), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0); | ||||||
3211 | return r; | ||||||
3212 | } | ||||||
3213 | |||||||
3214 | /* Subroutine of cxx_eval_constant_expression. | ||||||
3215 | Attempt to evaluate condition expressions. Dead branches are not | ||||||
3216 | looked into. */ | ||||||
3217 | |||||||
3218 | static tree | ||||||
3219 | cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, | ||||||
3220 | bool lval, | ||||||
3221 | bool *non_constant_p, bool *overflow_p, | ||||||
3222 | tree *jump_target) | ||||||
3223 | { | ||||||
3224 | tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3224, __FUNCTION__))))), | ||||||
3225 | /*lval*/false, | ||||||
3226 | non_constant_p, overflow_p); | ||||||
3227 | VERIFY_CONSTANT (val)do { if (verify_constant ((val), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3228 | /* Don't VERIFY_CONSTANT the other operands. */ | ||||||
3229 | if (integer_zerop (val)) | ||||||
3230 | val = TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3230, __FUNCTION__))))); | ||||||
3231 | else | ||||||
3232 | val = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3232, __FUNCTION__))))); | ||||||
3233 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == IF_STMT && !val) | ||||||
3234 | val = void_nodeglobal_trees[TI_VOID]; | ||||||
3235 | return cxx_eval_constant_expression (ctx, val, lval, non_constant_p, | ||||||
3236 | overflow_p, jump_target); | ||||||
3237 | } | ||||||
3238 | |||||||
3239 | /* Subroutine of cxx_eval_constant_expression. | ||||||
3240 | Attempt to evaluate vector condition expressions. Unlike | ||||||
3241 | cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal | ||||||
3242 | ternary arithmetics operation, where all 3 arguments have to be | ||||||
3243 | evaluated as constants and then folding computes the result from | ||||||
3244 | them. */ | ||||||
3245 | |||||||
3246 | static tree | ||||||
3247 | cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t, | ||||||
3248 | bool *non_constant_p, bool *overflow_p) | ||||||
3249 | { | ||||||
3250 | tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3250, __FUNCTION__))))), | ||||||
3251 | /*lval*/false, | ||||||
3252 | non_constant_p, overflow_p); | ||||||
3253 | VERIFY_CONSTANT (arg1)do { if (verify_constant ((arg1), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3254 | tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3254, __FUNCTION__))))), | ||||||
3255 | /*lval*/false, | ||||||
3256 | non_constant_p, overflow_p); | ||||||
3257 | VERIFY_CONSTANT (arg2)do { if (verify_constant ((arg2), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3258 | tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3258, __FUNCTION__))))), | ||||||
3259 | /*lval*/false, | ||||||
3260 | non_constant_p, overflow_p); | ||||||
3261 | VERIFY_CONSTANT (arg3)do { if (verify_constant ((arg3), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3262 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); | ||||||
3263 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3263, __FUNCTION__))->typed.type); | ||||||
3264 | tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3); | ||||||
3265 | if (r == NULL_TREE(tree) nullptr) | ||||||
3266 | { | ||||||
3267 | if (arg1 == TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3267, __FUNCTION__))))) | ||||||
3268 | && arg2 == TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3268, __FUNCTION__))))) | ||||||
3269 | && arg3 == TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3269, __FUNCTION__)))))) | ||||||
3270 | r = t; | ||||||
3271 | else | ||||||
3272 | r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3); | ||||||
3273 | } | ||||||
3274 | VERIFY_CONSTANT (r)do { if (verify_constant ((r), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0); | ||||||
3275 | return r; | ||||||
3276 | } | ||||||
3277 | |||||||
3278 | /* Returns less than, equal to, or greater than zero if KEY is found to be | ||||||
3279 | less than, to match, or to be greater than the constructor_elt's INDEX. */ | ||||||
3280 | |||||||
3281 | static int | ||||||
3282 | array_index_cmp (tree key, tree index) | ||||||
3283 | { | ||||||
3284 | gcc_assert (TREE_CODE (key) == INTEGER_CST)((void)(!(((enum tree_code) (key)->base.code) == INTEGER_CST ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3284, __FUNCTION__), 0 : 0)); | ||||||
3285 | |||||||
3286 | switch (TREE_CODE (index)((enum tree_code) (index)->base.code)) | ||||||
3287 | { | ||||||
3288 | case INTEGER_CST: | ||||||
3289 | return tree_int_cst_compare (key, index); | ||||||
3290 | case RANGE_EXPR: | ||||||
3291 | { | ||||||
3292 | tree lo = TREE_OPERAND (index, 0)(*((const_cast<tree*> (tree_operand_check ((index), (0) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3292, __FUNCTION__))))); | ||||||
3293 | tree hi = TREE_OPERAND (index, 1)(*((const_cast<tree*> (tree_operand_check ((index), (1) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3293, __FUNCTION__))))); | ||||||
3294 | if (tree_int_cst_lt (key, lo)) | ||||||
3295 | return -1; | ||||||
3296 | else if (tree_int_cst_lt (hi, key)) | ||||||
3297 | return 1; | ||||||
3298 | else | ||||||
3299 | return 0; | ||||||
3300 | } | ||||||
3301 | default: | ||||||
3302 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3302, __FUNCTION__)); | ||||||
3303 | } | ||||||
3304 | } | ||||||
3305 | |||||||
3306 | /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1 | ||||||
3307 | if none. If INSERT is true, insert a matching element rather than fail. */ | ||||||
3308 | |||||||
3309 | static HOST_WIDE_INTlong | ||||||
3310 | find_array_ctor_elt (tree ary, tree dindex, bool insert) | ||||||
3311 | { | ||||||
3312 | if (tree_int_cst_sgn (dindex) < 0) | ||||||
3313 | return -1; | ||||||
3314 | |||||||
3315 | unsigned HOST_WIDE_INTlong i = tree_to_uhwi (dindex); | ||||||
3316 | vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3316, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
3317 | unsigned HOST_WIDE_INTlong len = vec_safe_length (elts); | ||||||
3318 | |||||||
3319 | unsigned HOST_WIDE_INTlong end = len; | ||||||
3320 | unsigned HOST_WIDE_INTlong begin = 0; | ||||||
3321 | |||||||
3322 | /* If the last element of the CONSTRUCTOR has its own index, we can assume | ||||||
3323 | that the same is true of the other elements and index directly. */ | ||||||
3324 | if (end > 0) | ||||||
3325 | { | ||||||
3326 | tree cindex = (*elts)[end - 1].index; | ||||||
3327 | if (cindex == NULL_TREE(tree) nullptr) | ||||||
3328 | { | ||||||
3329 | /* Verify that if the last index is missing, all indexes | ||||||
3330 | are missing. */ | ||||||
3331 | if (flag_checkingglobal_options.x_flag_checking) | ||||||
3332 | for (unsigned int j = 0; j < len - 1; ++j) | ||||||
3333 | gcc_assert ((*elts)[j].index == NULL_TREE)((void)(!((*elts)[j].index == (tree) nullptr) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3333, __FUNCTION__), 0 : 0)); | ||||||
3334 | if (i < end) | ||||||
3335 | return i; | ||||||
3336 | else | ||||||
3337 | { | ||||||
3338 | begin = end; | ||||||
3339 | if (i == end) | ||||||
3340 | /* If the element is to be added right at the end, | ||||||
3341 | make sure it is added with cleared index too. */ | ||||||
3342 | dindex = NULL_TREE(tree) nullptr; | ||||||
3343 | else if (insert) | ||||||
3344 | /* Otherwise, in order not to break the assumption | ||||||
3345 | that CONSTRUCTOR either has all indexes or none, | ||||||
3346 | we need to add indexes to all elements. */ | ||||||
3347 | for (unsigned int j = 0; j < len; ++j) | ||||||
3348 | (*elts)[j].index = build_int_cst (TREE_TYPE (dindex)((contains_struct_check ((dindex), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3348, __FUNCTION__))->typed.type), j); | ||||||
3349 | } | ||||||
3350 | } | ||||||
3351 | else if (TREE_CODE (cindex)((enum tree_code) (cindex)->base.code) == INTEGER_CST | ||||||
3352 | && compare_tree_int (cindex, end - 1) == 0) | ||||||
3353 | { | ||||||
3354 | if (i < end) | ||||||
3355 | return i; | ||||||
3356 | else | ||||||
3357 | begin = end; | ||||||
3358 | } | ||||||
3359 | } | ||||||
3360 | |||||||
3361 | /* Otherwise, find a matching index by means of a binary search. */ | ||||||
3362 | while (begin != end) | ||||||
3363 | { | ||||||
3364 | unsigned HOST_WIDE_INTlong middle = (begin + end) / 2; | ||||||
3365 | constructor_elt &elt = (*elts)[middle]; | ||||||
3366 | tree idx = elt.index; | ||||||
3367 | |||||||
3368 | int cmp = array_index_cmp (dindex, idx); | ||||||
3369 | if (cmp < 0) | ||||||
3370 | end = middle; | ||||||
3371 | else if (cmp > 0) | ||||||
3372 | begin = middle + 1; | ||||||
3373 | else | ||||||
3374 | { | ||||||
3375 | if (insert && TREE_CODE (idx)((enum tree_code) (idx)->base.code) == RANGE_EXPR) | ||||||
3376 | { | ||||||
3377 | /* We need to split the range. */ | ||||||
3378 | constructor_elt e; | ||||||
3379 | tree lo = TREE_OPERAND (idx, 0)(*((const_cast<tree*> (tree_operand_check ((idx), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3379, __FUNCTION__))))); | ||||||
3380 | tree hi = TREE_OPERAND (idx, 1)(*((const_cast<tree*> (tree_operand_check ((idx), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3380, __FUNCTION__))))); | ||||||
3381 | tree value = elt.value; | ||||||
3382 | dindex = fold_convert (sizetype, dindex)fold_convert_loc (((location_t) 0), sizetype_tab[(int) stk_sizetype ], dindex); | ||||||
3383 | if (tree_int_cst_lt (lo, dindex)) | ||||||
3384 | { | ||||||
3385 | /* There are still some lower elts; shorten the range. */ | ||||||
3386 | tree new_hi = int_const_binop (MINUS_EXPR, dindex, | ||||||
3387 | size_one_nodeglobal_trees[TI_SIZE_ONE]); | ||||||
3388 | if (tree_int_cst_equal (lo, new_hi)) | ||||||
3389 | /* Only one element left, no longer a range. */ | ||||||
3390 | elt.index = lo; | ||||||
3391 | else | ||||||
3392 | TREE_OPERAND (idx, 1)(*((const_cast<tree*> (tree_operand_check ((idx), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3392, __FUNCTION__))))) = new_hi; | ||||||
3393 | /* Append the element we want to insert. */ | ||||||
3394 | ++middle; | ||||||
3395 | e.index = dindex; | ||||||
3396 | e.value = unshare_constructor (value); | ||||||
3397 | vec_safe_insert (CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3397, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), middle, e); | ||||||
3398 | } | ||||||
3399 | else | ||||||
3400 | /* No lower elts, the range elt is now ours. */ | ||||||
3401 | elt.index = dindex; | ||||||
3402 | |||||||
3403 | if (tree_int_cst_lt (dindex, hi)) | ||||||
3404 | { | ||||||
3405 | /* There are still some higher elts; append a range. */ | ||||||
3406 | tree new_lo = int_const_binop (PLUS_EXPR, dindex, | ||||||
3407 | size_one_nodeglobal_trees[TI_SIZE_ONE]); | ||||||
3408 | if (tree_int_cst_equal (new_lo, hi)) | ||||||
3409 | e.index = hi; | ||||||
3410 | else | ||||||
3411 | e.index = build2 (RANGE_EXPR, sizetypesizetype_tab[(int) stk_sizetype], new_lo, hi); | ||||||
3412 | e.value = unshare_constructor (value); | ||||||
3413 | vec_safe_insert (CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3413, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), middle + 1, e); | ||||||
3414 | } | ||||||
3415 | } | ||||||
3416 | return middle; | ||||||
3417 | } | ||||||
3418 | } | ||||||
3419 | |||||||
3420 | if (insert
| ||||||
3421 | { | ||||||
3422 | constructor_elt e = { dindex, NULL_TREE(tree) nullptr }; | ||||||
3423 | vec_safe_insert (CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3423, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), end, e); | ||||||
3424 | return end; | ||||||
3425 | } | ||||||
3426 | |||||||
3427 | return -1; | ||||||
3428 | } | ||||||
3429 | |||||||
3430 | /* Return a pointer to the constructor_elt of CTOR which matches INDEX. If no | ||||||
3431 | matching constructor_elt exists, then add one to CTOR. | ||||||
3432 | |||||||
3433 | As an optimization, if POS_HINT is non-negative then it is used as a guess | ||||||
3434 | for the (integer) index of the matching constructor_elt within CTOR. */ | ||||||
3435 | |||||||
3436 | static constructor_elt * | ||||||
3437 | get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1) | ||||||
3438 | { | ||||||
3439 | /* Check the hint first. */ | ||||||
3440 | if (pos_hint >= 0 && (unsigned)pos_hint < CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3440, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) | ||||||
3441 | && CONSTRUCTOR_ELT (ctor, pos_hint)(&(*((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3441, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ pos_hint])->index == index) | ||||||
3442 | return CONSTRUCTOR_ELT (ctor, pos_hint)(&(*((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3442, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ pos_hint]); | ||||||
3443 | |||||||
3444 | tree type = TREE_TYPE (ctor)((contains_struct_check ((ctor), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3444, __FUNCTION__))->typed.type); | ||||||
3445 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == VECTOR_TYPE && index == NULL_TREE(tree) nullptr) | ||||||
3446 | { | ||||||
3447 | CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (ctor), index, NULL_TREE)do { constructor_elt _ce___ = {index, (tree) nullptr}; vec_safe_push ((((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3447, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)), _ce___); } while (0); | ||||||
3448 | return &CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3448, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)->last(); | ||||||
3449 | } | ||||||
3450 | else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == ARRAY_TYPE || TREE_CODE (type)((enum tree_code) (type)->base.code) == VECTOR_TYPE) | ||||||
3451 | { | ||||||
3452 | if (TREE_CODE (index)((enum tree_code) (index)->base.code) == RANGE_EXPR) | ||||||
3453 | { | ||||||
3454 | /* Support for RANGE_EXPR index lookups is currently limited to | ||||||
3455 | accessing an existing element via POS_HINT, or appending a new | ||||||
3456 | element to the end of CTOR. ??? Support for other access | ||||||
3457 | patterns may also be needed. */ | ||||||
3458 | vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3458, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
3459 | if (vec_safe_length (elts)) | ||||||
3460 | { | ||||||
3461 | tree lo = TREE_OPERAND (index, 0)(*((const_cast<tree*> (tree_operand_check ((index), (0) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3461, __FUNCTION__))))); | ||||||
3462 | gcc_assert (array_index_cmp (elts->last().index, lo) < 0)((void)(!(array_index_cmp (elts->last().index, lo) < 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3462, __FUNCTION__), 0 : 0)); | ||||||
3463 | } | ||||||
3464 | CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE)do { constructor_elt _ce___ = {index, (tree) nullptr}; vec_safe_push ((elts), _ce___); } while (0); | ||||||
3465 | return &elts->last(); | ||||||
3466 | } | ||||||
3467 | |||||||
3468 | HOST_WIDE_INTlong i = find_array_ctor_elt (ctor, index, /*insert*/true); | ||||||
3469 | gcc_assert (i >= 0)((void)(!(i >= 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3469, __FUNCTION__), 0 : 0)); | ||||||
3470 | constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i)(&(*((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3470, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i]); | ||||||
3471 | gcc_assert (cep->index == NULL_TREE((void)(!(cep->index == (tree) nullptr || ((enum tree_code ) (cep->index)->base.code) != RANGE_EXPR) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3472, __FUNCTION__), 0 : 0)) | ||||||
3472 | || TREE_CODE (cep->index) != RANGE_EXPR)((void)(!(cep->index == (tree) nullptr || ((enum tree_code ) (cep->index)->base.code) != RANGE_EXPR) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3472, __FUNCTION__), 0 : 0)); | ||||||
3473 | return cep; | ||||||
3474 | } | ||||||
3475 | else | ||||||
3476 | { | ||||||
3477 | gcc_assert (TREE_CODE (index) == FIELD_DECL)((void)(!(((enum tree_code) (index)->base.code) == FIELD_DECL ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3477, __FUNCTION__), 0 : 0)); | ||||||
3478 | |||||||
3479 | /* We must keep the CONSTRUCTOR's ELTS in FIELD order. | ||||||
3480 | Usually we meet initializers in that order, but it is | ||||||
3481 | possible for base types to be placed not in program | ||||||
3482 | order. */ | ||||||
3483 | tree fields = TYPE_FIELDS (DECL_CONTEXT (index))((tree_check3 ((((contains_struct_check ((index), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3483, __FUNCTION__))->decl_minimal.context)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3483, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); | ||||||
3484 | unsigned HOST_WIDE_INTlong idx = 0; | ||||||
3485 | constructor_elt *cep = NULLnullptr; | ||||||
3486 | |||||||
3487 | /* Check if we're changing the active member of a union. */ | ||||||
3488 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == UNION_TYPE && CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3488, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) | ||||||
3489 | && CONSTRUCTOR_ELT (ctor, 0)(&(*((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3489, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0])->index != index) | ||||||
3490 | vec_safe_truncate (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3490, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), 0); | ||||||
3491 | /* If the bit offset of INDEX is larger than that of the last | ||||||
3492 | constructor_elt, then we can just immediately append a new | ||||||
3493 | constructor_elt to the end of CTOR. */ | ||||||
3494 | else if (CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3494, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) | ||||||
3495 | && tree_int_cst_compare (bit_position (index), | ||||||
3496 | bit_position (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3496, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts) | ||||||
3497 | ->last().index)) > 0) | ||||||
3498 | { | ||||||
3499 | idx = CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3499, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))); | ||||||
3500 | goto insert; | ||||||
3501 | } | ||||||
3502 | |||||||
3503 | /* Otherwise, we need to iterate over CTOR to find or insert INDEX | ||||||
3504 | appropriately. */ | ||||||
3505 | |||||||
3506 | for (; vec_safe_iterate (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3506, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), idx, &cep); | ||||||
3507 | idx++, fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3507, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3507, __FUNCTION__))->common.chain))) | ||||||
3508 | { | ||||||
3509 | if (index == cep->index) | ||||||
3510 | goto found; | ||||||
3511 | |||||||
3512 | /* The field we're initializing must be on the field | ||||||
3513 | list. Look to see if it is present before the | ||||||
3514 | field the current ELT initializes. */ | ||||||
3515 | for (; fields != cep->index; fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3515, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3515, __FUNCTION__))->common.chain))) | ||||||
3516 | if (index == fields) | ||||||
3517 | goto insert; | ||||||
3518 | } | ||||||
3519 | /* We fell off the end of the CONSTRUCTOR, so insert a new | ||||||
3520 | entry at the end. */ | ||||||
3521 | |||||||
3522 | insert: | ||||||
3523 | { | ||||||
3524 | constructor_elt ce = { index, NULL_TREE(tree) nullptr }; | ||||||
3525 | |||||||
3526 | vec_safe_insert (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3526, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), idx, ce); | ||||||
3527 | cep = CONSTRUCTOR_ELT (ctor, idx)(&(*((tree_check ((ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3527, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ idx]); | ||||||
3528 | } | ||||||
3529 | found:; | ||||||
3530 | |||||||
3531 | return cep; | ||||||
3532 | } | ||||||
3533 | } | ||||||
3534 | |||||||
3535 | /* Under the control of CTX, issue a detailed diagnostic for | ||||||
3536 | an out-of-bounds subscript INDEX into the expression ARRAY. */ | ||||||
3537 | |||||||
3538 | static void | ||||||
3539 | diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree index) | ||||||
3540 | { | ||||||
3541 | if (!ctx->quiet) | ||||||
3542 | { | ||||||
3543 | tree arraytype = TREE_TYPE (array)((contains_struct_check ((array), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3543, __FUNCTION__))->typed.type); | ||||||
3544 | |||||||
3545 | /* Convert the unsigned array subscript to a signed integer to avoid | ||||||
3546 | printing huge numbers for small negative values. */ | ||||||
3547 | tree sidx = fold_convert (ssizetype, index)fold_convert_loc (((location_t) 0), sizetype_tab[(int) stk_ssizetype ], index); | ||||||
3548 | STRIP_ANY_LOCATION_WRAPPER (array)(array) = tree_strip_any_location_wrapper ((const_cast<union tree_node *> (((array))))); | ||||||
3549 | if (DECL_P (array)(tree_code_type[(int) (((enum tree_code) (array)->base.code ))] == tcc_declaration)) | ||||||
3550 | { | ||||||
3551 | if (TYPE_DOMAIN (arraytype)((tree_check ((arraytype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3551, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )) | ||||||
3552 | error_at (loc, "array subscript value %qE is outside the bounds " | ||||||
3553 | "of array %qD of type %qT", sidx, array, arraytype); | ||||||
3554 | else | ||||||
3555 | error_at (loc, "nonzero array subscript %qE is used with array %qD of " | ||||||
3556 | "type %qT with unknown bounds", sidx, array, arraytype); | ||||||
3557 | inform (DECL_SOURCE_LOCATION (array)((contains_struct_check ((array), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3557, __FUNCTION__))->decl_minimal.locus), "declared here"); | ||||||
3558 | } | ||||||
3559 | else if (TYPE_DOMAIN (arraytype)((tree_check ((arraytype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3559, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )) | ||||||
3560 | error_at (loc, "array subscript value %qE is outside the bounds " | ||||||
3561 | "of array type %qT", sidx, arraytype); | ||||||
3562 | else | ||||||
3563 | error_at (loc, "nonzero array subscript %qE is used with array of type %qT " | ||||||
3564 | "with unknown bounds", sidx, arraytype); | ||||||
3565 | } | ||||||
3566 | } | ||||||
3567 | |||||||
3568 | /* Return the number of elements for TYPE (which is an ARRAY_TYPE or | ||||||
3569 | a VECTOR_TYPE). */ | ||||||
3570 | |||||||
3571 | static tree | ||||||
3572 | get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type, | ||||||
3573 | bool *non_constant_p, bool *overflow_p) | ||||||
3574 | { | ||||||
3575 | tree nelts; | ||||||
3576 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == ARRAY_TYPE) | ||||||
3577 | { | ||||||
3578 | if (TYPE_DOMAIN (type)((tree_check ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3578, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )) | ||||||
3579 | nelts = array_type_nelts_top (type); | ||||||
3580 | else | ||||||
3581 | nelts = size_zero_nodeglobal_trees[TI_SIZE_ZERO]; | ||||||
3582 | } | ||||||
3583 | else if (VECTOR_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE)) | ||||||
3584 | nelts = size_int (TYPE_VECTOR_SUBPARTS (type))size_int_kind (TYPE_VECTOR_SUBPARTS (type), stk_sizetype); | ||||||
3585 | else | ||||||
3586 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3586, __FUNCTION__)); | ||||||
3587 | |||||||
3588 | /* For VLAs, the number of elements won't be an integer constant. */ | ||||||
3589 | nelts = cxx_eval_constant_expression (ctx, nelts, false, | ||||||
3590 | non_constant_p, overflow_p); | ||||||
3591 | return nelts; | ||||||
3592 | } | ||||||
3593 | |||||||
3594 | /* Extract element INDEX consisting of CHARS_PER_ELT chars from | ||||||
3595 | STRING_CST STRING. */ | ||||||
3596 | |||||||
3597 | static tree | ||||||
3598 | extract_string_elt (tree string, unsigned chars_per_elt, unsigned index) | ||||||
3599 | { | ||||||
3600 | tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string))((contains_struct_check ((((contains_struct_check ((string), ( TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3600, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3600, __FUNCTION__))->typed.type)); | ||||||
3601 | tree r; | ||||||
3602 | |||||||
3603 | if (chars_per_elt == 1) | ||||||
3604 | r = build_int_cst (type, TREE_STRING_POINTER (string)((const char *)((tree_check ((string), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3604, __FUNCTION__, (STRING_CST)))->string.str))[index]); | ||||||
3605 | else | ||||||
3606 | { | ||||||
3607 | const unsigned char *ptr | ||||||
3608 | = ((const unsigned char *)TREE_STRING_POINTER (string)((const char *)((tree_check ((string), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3608, __FUNCTION__, (STRING_CST)))->string.str)) | ||||||
3609 | + index * chars_per_elt); | ||||||
3610 | r = native_interpret_expr (type, ptr, chars_per_elt); | ||||||
3611 | } | ||||||
3612 | return r; | ||||||
3613 | } | ||||||
3614 | |||||||
3615 | /* Subroutine of cxx_eval_array_reference. T is an ARRAY_REF; evaluate the | ||||||
3616 | subscript, diagnose any problems with it, and return the result. */ | ||||||
3617 | |||||||
3618 | static tree | ||||||
3619 | eval_and_check_array_index (const constexpr_ctx *ctx, | ||||||
3620 | tree t, bool allow_one_past, | ||||||
3621 | bool *non_constant_p, bool *overflow_p) | ||||||
3622 | { | ||||||
3623 | location_t loc = cp_expr_loc_or_input_loc (t); | ||||||
3624 | tree ary = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3624, __FUNCTION__))))); | ||||||
3625 | t = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3625, __FUNCTION__))))); | ||||||
3626 | tree index = cxx_eval_constant_expression (ctx, t, false, | ||||||
3627 | non_constant_p, overflow_p); | ||||||
3628 | VERIFY_CONSTANT (index)do { if (verify_constant ((index), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3629 | |||||||
3630 | if (!tree_fits_shwi_p (index) | ||||||
3631 | || tree_int_cst_sgn (index) < 0) | ||||||
3632 | { | ||||||
3633 | diag_array_subscript (loc, ctx, ary, index); | ||||||
3634 | *non_constant_p = true; | ||||||
3635 | return t; | ||||||
3636 | } | ||||||
3637 | |||||||
3638 | tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary)((contains_struct_check ((ary), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3638, __FUNCTION__))->typed.type), non_constant_p, | ||||||
3639 | overflow_p); | ||||||
3640 | VERIFY_CONSTANT (nelts)do { if (verify_constant ((nelts), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3641 | if (allow_one_past | ||||||
3642 | ? !tree_int_cst_le (index, nelts) | ||||||
3643 | : !tree_int_cst_lt (index, nelts)) | ||||||
3644 | { | ||||||
3645 | diag_array_subscript (loc, ctx, ary, index); | ||||||
3646 | *non_constant_p = true; | ||||||
3647 | return t; | ||||||
3648 | } | ||||||
3649 | |||||||
3650 | return index; | ||||||
3651 | } | ||||||
3652 | |||||||
3653 | /* Subroutine of cxx_eval_constant_expression. | ||||||
3654 | Attempt to reduce a reference to an array slot. */ | ||||||
3655 | |||||||
3656 | static tree | ||||||
3657 | cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, | ||||||
3658 | bool lval, | ||||||
3659 | bool *non_constant_p, bool *overflow_p) | ||||||
3660 | { | ||||||
3661 | tree oldary = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3661, __FUNCTION__))))); | ||||||
3662 | tree ary = cxx_eval_constant_expression (ctx, oldary, | ||||||
3663 | lval, | ||||||
3664 | non_constant_p, overflow_p); | ||||||
3665 | if (*non_constant_p) | ||||||
3666 | return t; | ||||||
3667 | if (!lval | ||||||
3668 | && TREE_CODE (ary)((enum tree_code) (ary)->base.code) == VIEW_CONVERT_EXPR | ||||||
3669 | && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))(((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((ary), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3669, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3669, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE ) | ||||||
3670 | && TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3670, __FUNCTION__))->typed.type) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0)))((contains_struct_check ((((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((ary), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3670, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3670, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3670, __FUNCTION__))->typed.type)) | ||||||
3671 | ary = TREE_OPERAND (ary, 0)(*((const_cast<tree*> (tree_operand_check ((ary), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3671, __FUNCTION__))))); | ||||||
3672 | |||||||
3673 | tree oldidx = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3673, __FUNCTION__))))); | ||||||
3674 | tree index = eval_and_check_array_index (ctx, t, lval, | ||||||
3675 | non_constant_p, overflow_p); | ||||||
3676 | if (*non_constant_p) | ||||||
3677 | return t; | ||||||
3678 | |||||||
3679 | if (lval && ary == oldary && index == oldidx) | ||||||
3680 | return t; | ||||||
3681 | else if (lval) | ||||||
3682 | return build4 (ARRAY_REF, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3682, __FUNCTION__))->typed.type), ary, index, NULLnullptr, NULLnullptr); | ||||||
3683 | |||||||
3684 | unsigned len = 0, elem_nchars = 1; | ||||||
3685 | tree elem_type = TREE_TYPE (TREE_TYPE (ary))((contains_struct_check ((((contains_struct_check ((ary), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3685, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3685, __FUNCTION__))->typed.type); | ||||||
3686 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR) | ||||||
3687 | len = CONSTRUCTOR_NELTS (ary)(vec_safe_length (((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3687, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))); | ||||||
3688 | else if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == STRING_CST) | ||||||
3689 | { | ||||||
3690 | elem_nchars = (TYPE_PRECISION (elem_type)((tree_class_check ((elem_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3690, __FUNCTION__))->type_common.precision) | ||||||
3691 | / TYPE_PRECISION (char_type_node)((tree_class_check ((integer_types[itk_char]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3691, __FUNCTION__))->type_common.precision)); | ||||||
3692 | len = (unsigned) TREE_STRING_LENGTH (ary)((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3692, __FUNCTION__, (STRING_CST)))->string.length) / elem_nchars; | ||||||
3693 | } | ||||||
3694 | else if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == VECTOR_CST) | ||||||
3695 | /* We don't create variable-length VECTOR_CSTs. */ | ||||||
3696 | len = VECTOR_CST_NELTS (ary)(TYPE_VECTOR_SUBPARTS (((contains_struct_check ((ary), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3696, __FUNCTION__))->typed.type))).to_constant (); | ||||||
3697 | else | ||||||
3698 | { | ||||||
3699 | /* We can't do anything with other tree codes, so use | ||||||
3700 | VERIFY_CONSTANT to complain and fail. */ | ||||||
3701 | VERIFY_CONSTANT (ary)do { if (verify_constant ((ary), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
3702 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3702, __FUNCTION__)); | ||||||
3703 | } | ||||||
3704 | |||||||
3705 | bool found; | ||||||
3706 | HOST_WIDE_INTlong i = 0; | ||||||
3707 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR) | ||||||
3708 | { | ||||||
3709 | HOST_WIDE_INTlong ix = find_array_ctor_elt (ary, index); | ||||||
3710 | found = (ix >= 0); | ||||||
3711 | if (found) | ||||||
3712 | i = ix; | ||||||
3713 | } | ||||||
3714 | else | ||||||
3715 | { | ||||||
3716 | i = tree_to_shwi (index); | ||||||
3717 | found = (i < len); | ||||||
3718 | } | ||||||
3719 | |||||||
3720 | if (found) | ||||||
3721 | { | ||||||
3722 | tree r; | ||||||
3723 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR) | ||||||
3724 | r = (*CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3724, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[i].value; | ||||||
3725 | else if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == VECTOR_CST) | ||||||
3726 | r = VECTOR_CST_ELT (ary, i)vector_cst_elt (ary, i); | ||||||
3727 | else | ||||||
3728 | r = extract_string_elt (ary, elem_nchars, i); | ||||||
3729 | |||||||
3730 | if (r) | ||||||
3731 | /* Don't VERIFY_CONSTANT here. */ | ||||||
3732 | return r; | ||||||
3733 | |||||||
3734 | /* Otherwise the element doesn't have a value yet. */ | ||||||
3735 | } | ||||||
3736 | |||||||
3737 | /* Not found. */ | ||||||
3738 | |||||||
3739 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR | ||||||
3740 | && CONSTRUCTOR_NO_CLEARING (ary)((tree_check ((ary), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3740, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) | ||||||
3741 | { | ||||||
3742 | /* 'ary' is part of the aggregate initializer we're currently | ||||||
3743 | building; if there's no initializer for this element yet, | ||||||
3744 | that's an error. */ | ||||||
3745 | if (!ctx->quiet) | ||||||
3746 | error ("accessing uninitialized array element"); | ||||||
3747 | *non_constant_p = true; | ||||||
3748 | return t; | ||||||
3749 | } | ||||||
3750 | |||||||
3751 | /* If it's within the array bounds but doesn't have an explicit | ||||||
3752 | initializer, it's initialized from {}. But use build_value_init | ||||||
3753 | directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */ | ||||||
3754 | tree val; | ||||||
3755 | constexpr_ctx new_ctx; | ||||||
3756 | if (CP_AGGREGATE_TYPE_P (elem_type)(gnu_vector_type_p (elem_type) || ((enum tree_code) (elem_type )->base.code) == ARRAY_TYPE || ((((((enum tree_code) (elem_type )->base.code)) == RECORD_TYPE || (((enum tree_code) (elem_type )->base.code)) == UNION_TYPE) && ((tree_class_check ((elem_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3756, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((elem_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3756, __FUNCTION__))->type_common.size) != (tree) nullptr ) && !((((tree_class_check ((elem_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3756, __FUNCTION__))->type_with_lang_specific.lang_specific ))->non_aggregate)))) | ||||||
3757 | { | ||||||
3758 | tree empty_ctor = build_constructor (init_list_type_nodecp_global_trees[CPTI_INIT_LIST_TYPE], NULLnullptr); | ||||||
3759 | val = digest_init (elem_type, empty_ctor, tf_warning_or_error); | ||||||
3760 | new_ctx = *ctx; | ||||||
3761 | new_ctx.ctor = build_constructor (elem_type, NULLnullptr); | ||||||
3762 | ctx = &new_ctx; | ||||||
3763 | } | ||||||
3764 | else | ||||||
3765 | val = build_value_init (elem_type, tf_warning_or_error); | ||||||
3766 | t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p, | ||||||
3767 | overflow_p); | ||||||
3768 | if (CP_AGGREGATE_TYPE_P (elem_type)(gnu_vector_type_p (elem_type) || ((enum tree_code) (elem_type )->base.code) == ARRAY_TYPE || ((((((enum tree_code) (elem_type )->base.code)) == RECORD_TYPE || (((enum tree_code) (elem_type )->base.code)) == UNION_TYPE) && ((tree_class_check ((elem_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3768, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((elem_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3768, __FUNCTION__))->type_common.size) != (tree) nullptr ) && !((((tree_class_check ((elem_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3768, __FUNCTION__))->type_with_lang_specific.lang_specific ))->non_aggregate))) && t != ctx->ctor) | ||||||
3769 | free_constructor (ctx->ctor); | ||||||
3770 | return t; | ||||||
3771 | } | ||||||
3772 | |||||||
3773 | /* Subroutine of cxx_eval_constant_expression. | ||||||
3774 | Attempt to reduce a field access of a value of class type. */ | ||||||
3775 | |||||||
3776 | static tree | ||||||
3777 | cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, | ||||||
3778 | bool lval, | ||||||
3779 | bool *non_constant_p, bool *overflow_p) | ||||||
3780 | { | ||||||
3781 | unsigned HOST_WIDE_INTlong i; | ||||||
3782 | tree field; | ||||||
3783 | tree value; | ||||||
3784 | tree part = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3784, __FUNCTION__))))); | ||||||
3785 | tree orig_whole = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3785, __FUNCTION__))))); | ||||||
3786 | tree whole = cxx_eval_constant_expression (ctx, orig_whole, | ||||||
3787 | lval, | ||||||
3788 | non_constant_p, overflow_p); | ||||||
3789 | if (INDIRECT_REF_P (whole)(((enum tree_code) (whole)->base.code) == INDIRECT_REF) | ||||||
3790 | && integer_zerop (TREE_OPERAND (whole, 0)(*((const_cast<tree*> (tree_operand_check ((whole), (0) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3790, __FUNCTION__))))))) | ||||||
3791 | { | ||||||
3792 | if (!ctx->quiet) | ||||||
3793 | error ("dereferencing a null pointer in %qE", orig_whole); | ||||||
3794 | *non_constant_p = true; | ||||||
3795 | return t; | ||||||
3796 | } | ||||||
3797 | |||||||
3798 | if (TREE_CODE (whole)((enum tree_code) (whole)->base.code) == PTRMEM_CST) | ||||||
3799 | whole = cplus_expand_constant (whole); | ||||||
3800 | if (whole == orig_whole) | ||||||
3801 | return t; | ||||||
3802 | if (lval) | ||||||
3803 | return fold_build3 (COMPONENT_REF, TREE_TYPE (t),fold_build3_loc (((location_t) 0), COMPONENT_REF, ((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3803, __FUNCTION__))->typed.type), whole, part, (tree) nullptr ) | ||||||
3804 | whole, part, NULL_TREE)fold_build3_loc (((location_t) 0), COMPONENT_REF, ((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3803, __FUNCTION__))->typed.type), whole, part, (tree) nullptr ); | ||||||
3805 | /* Don't VERIFY_CONSTANT here; we only want to check that we got a | ||||||
3806 | CONSTRUCTOR. */ | ||||||
3807 | if (!*non_constant_p && TREE_CODE (whole)((enum tree_code) (whole)->base.code) != CONSTRUCTOR) | ||||||
3808 | { | ||||||
3809 | if (!ctx->quiet) | ||||||
3810 | error ("%qE is not a constant expression", orig_whole); | ||||||
3811 | *non_constant_p = true; | ||||||
3812 | } | ||||||
3813 | if (DECL_MUTABLE_P (part)(((contains_struct_check (((tree_check ((part), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3813, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3813, __FUNCTION__))->decl_common.lang_flag_0))) | ||||||
3814 | { | ||||||
3815 | if (!ctx->quiet) | ||||||
3816 | error ("mutable %qD is not usable in a constant expression", part); | ||||||
3817 | *non_constant_p = true; | ||||||
3818 | } | ||||||
3819 | if (*non_constant_p) | ||||||
3820 | return t; | ||||||
3821 | bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole))(((enum tree_code) (((contains_struct_check ((whole), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3821, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && (((tree_class_check (((tree_check ((((contains_struct_check ((whole), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3821, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3821, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3821, __FUNCTION__))->type_common.lang_flag_2))); | ||||||
3822 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)for (i = 0; (i >= vec_safe_length (((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3822, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : (((void) (value = (*((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3822, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].value)), (field = (*((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3822, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].index), true); (i)++) | ||||||
3823 | { | ||||||
3824 | /* Use name match for PMF fields, as a variant will have a | ||||||
3825 | different FIELD_DECL with a different type. */ | ||||||
3826 | if (pmf ? DECL_NAME (field)((contains_struct_check ((field), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3826, __FUNCTION__))->decl_minimal.name) == DECL_NAME (part)((contains_struct_check ((part), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3826, __FUNCTION__))->decl_minimal.name) | ||||||
3827 | : field == part) | ||||||
3828 | { | ||||||
3829 | if (value) | ||||||
3830 | { | ||||||
3831 | STRIP_ANY_LOCATION_WRAPPER (value)(value) = tree_strip_any_location_wrapper ((const_cast<union tree_node *> (((value))))); | ||||||
3832 | return value; | ||||||
3833 | } | ||||||
3834 | else | ||||||
3835 | /* We're in the middle of initializing it. */ | ||||||
3836 | break; | ||||||
3837 | } | ||||||
3838 | } | ||||||
3839 | if (TREE_CODE (TREE_TYPE (whole))((enum tree_code) (((contains_struct_check ((whole), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3839, __FUNCTION__))->typed.type))->base.code) == UNION_TYPE | ||||||
3840 | && CONSTRUCTOR_NELTS (whole)(vec_safe_length (((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3840, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) > 0) | ||||||
3841 | { | ||||||
3842 | /* DR 1188 says we don't have to deal with this. */ | ||||||
3843 | if (!ctx->quiet) | ||||||
3844 | { | ||||||
3845 | constructor_elt *cep = CONSTRUCTOR_ELT (whole, 0)(&(*((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3845, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0]); | ||||||
3846 | if (cep->value == NULL_TREE(tree) nullptr) | ||||||
3847 | error ("accessing uninitialized member %qD", part); | ||||||
3848 | else | ||||||
3849 | error ("accessing %qD member instead of initialized %qD member in " | ||||||
3850 | "constant expression", part, cep->index); | ||||||
3851 | } | ||||||
3852 | *non_constant_p = true; | ||||||
3853 | return t; | ||||||
3854 | } | ||||||
3855 | |||||||
3856 | /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty | ||||||
3857 | classes never get represented; throw together a value now. */ | ||||||
3858 | if (is_really_empty_class (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3858, __FUNCTION__))->typed.type), /*ignore_vptr*/false)) | ||||||
3859 | return build_constructor (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3859, __FUNCTION__))->typed.type), NULLnullptr); | ||||||
3860 | |||||||
3861 | gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)))((void)(!(((contains_struct_check ((part), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3861, __FUNCTION__))->decl_minimal.context) == ((tree_class_check ((((contains_struct_check ((whole), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3861, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3861, __FUNCTION__))->type_common.main_variant)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3861, __FUNCTION__), 0 : 0)); | ||||||
3862 | |||||||
3863 | if (CONSTRUCTOR_NO_CLEARING (whole)((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3863, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) | ||||||
3864 | { | ||||||
3865 | /* 'whole' is part of the aggregate initializer we're currently | ||||||
3866 | building; if there's no initializer for this member yet, that's an | ||||||
3867 | error. */ | ||||||
3868 | if (!ctx->quiet) | ||||||
3869 | error ("accessing uninitialized member %qD", part); | ||||||
3870 | *non_constant_p = true; | ||||||
3871 | return t; | ||||||
3872 | } | ||||||
3873 | |||||||
3874 | /* If there's no explicit init for this field, it's value-initialized. */ | ||||||
3875 | value = build_value_init (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3875, __FUNCTION__))->typed.type), tf_warning_or_error); | ||||||
3876 | return cxx_eval_constant_expression (ctx, value, | ||||||
3877 | lval, | ||||||
3878 | non_constant_p, overflow_p); | ||||||
3879 | } | ||||||
3880 | |||||||
3881 | /* Subroutine of cxx_eval_constant_expression. | ||||||
3882 | Attempt to reduce a field access of a value of class type that is | ||||||
3883 | expressed as a BIT_FIELD_REF. */ | ||||||
3884 | |||||||
3885 | static tree | ||||||
3886 | cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t, | ||||||
3887 | bool lval, | ||||||
3888 | bool *non_constant_p, bool *overflow_p) | ||||||
3889 | { | ||||||
3890 | tree orig_whole = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3890, __FUNCTION__))))); | ||||||
3891 | tree retval, fldval, utype, mask; | ||||||
3892 | bool fld_seen = false; | ||||||
3893 | HOST_WIDE_INTlong istart, isize; | ||||||
3894 | tree whole = cxx_eval_constant_expression (ctx, orig_whole, | ||||||
3895 | lval, | ||||||
3896 | non_constant_p, overflow_p); | ||||||
3897 | tree start, field, value; | ||||||
3898 | unsigned HOST_WIDE_INTlong i; | ||||||
3899 | |||||||
3900 | if (whole == orig_whole) | ||||||
3901 | return t; | ||||||
3902 | /* Don't VERIFY_CONSTANT here; we only want to check that we got a | ||||||
3903 | CONSTRUCTOR. */ | ||||||
3904 | if (!*non_constant_p | ||||||
3905 | && TREE_CODE (whole)((enum tree_code) (whole)->base.code) != VECTOR_CST | ||||||
3906 | && TREE_CODE (whole)((enum tree_code) (whole)->base.code) != CONSTRUCTOR) | ||||||
3907 | { | ||||||
3908 | if (!ctx->quiet) | ||||||
3909 | error ("%qE is not a constant expression", orig_whole); | ||||||
3910 | *non_constant_p = true; | ||||||
3911 | } | ||||||
3912 | if (*non_constant_p) | ||||||
3913 | return t; | ||||||
3914 | |||||||
3915 | if (TREE_CODE (whole)((enum tree_code) (whole)->base.code) == VECTOR_CST) | ||||||
3916 | return fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,fold_ternary_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3916, __FUNCTION__))->typed.type), whole, (*((const_cast <tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3917, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((t), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3917, __FUNCTION__)))))) | ||||||
3917 | TREE_OPERAND (t, 1), TREE_OPERAND (t, 2))fold_ternary_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3916, __FUNCTION__))->typed.type), whole, (*((const_cast <tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3917, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((t), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3917, __FUNCTION__)))))); | ||||||
3918 | |||||||
3919 | start = TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3919, __FUNCTION__))))); | ||||||
3920 | istart = tree_to_shwi (start); | ||||||
3921 | isize = tree_to_shwi (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3921, __FUNCTION__)))))); | ||||||
3922 | utype = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3922, __FUNCTION__))->typed.type); | ||||||
3923 | if (!TYPE_UNSIGNED (utype)((tree_class_check ((utype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3923, __FUNCTION__))->base.u.bits.unsigned_flag)) | ||||||
3924 | utype = build_nonstandard_integer_type (TYPE_PRECISION (utype)((tree_class_check ((utype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3924, __FUNCTION__))->type_common.precision), 1); | ||||||
3925 | retval = build_int_cst (utype, 0); | ||||||
3926 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)for (i = 0; (i >= vec_safe_length (((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3926, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : (((void) (value = (*((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3926, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].value)), (field = (*((tree_check ((whole), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3926, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].index), true); (i)++) | ||||||
3927 | { | ||||||
3928 | tree bitpos = bit_position (field); | ||||||
3929 | STRIP_ANY_LOCATION_WRAPPER (value)(value) = tree_strip_any_location_wrapper ((const_cast<union tree_node *> (((value))))); | ||||||
3930 | if (bitpos == start && DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3930, __FUNCTION__))->decl_common.size) == TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3930, __FUNCTION__)))))) | ||||||
3931 | return value; | ||||||
3932 | if (TREE_CODE (TREE_TYPE (field))((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3932, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE | ||||||
3933 | && TREE_CODE (value)((enum tree_code) (value)->base.code) == INTEGER_CST | ||||||
3934 | && tree_fits_shwi_p (bitpos) | ||||||
3935 | && tree_fits_shwi_p (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3935, __FUNCTION__))->decl_common.size))) | ||||||
3936 | { | ||||||
3937 | HOST_WIDE_INTlong bit = tree_to_shwi (bitpos); | ||||||
3938 | HOST_WIDE_INTlong sz = tree_to_shwi (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3938, __FUNCTION__))->decl_common.size)); | ||||||
3939 | HOST_WIDE_INTlong shift; | ||||||
3940 | if (bit >= istart && bit + sz <= istart + isize) | ||||||
3941 | { | ||||||
3942 | fldval = fold_convert (utype, value)fold_convert_loc (((location_t) 0), utype, value); | ||||||
3943 | mask = build_int_cst_type (utype, -1); | ||||||
3944 | mask = fold_build2 (LSHIFT_EXPR, utype, mask,fold_build2_loc (((location_t) 0), LSHIFT_EXPR, utype, mask, size_int_kind (((tree_class_check ((utype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3945, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ) | ||||||
3945 | size_int (TYPE_PRECISION (utype) - sz))fold_build2_loc (((location_t) 0), LSHIFT_EXPR, utype, mask, size_int_kind (((tree_class_check ((utype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3945, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ); | ||||||
3946 | mask = fold_build2 (RSHIFT_EXPR, utype, mask,fold_build2_loc (((location_t) 0), RSHIFT_EXPR, utype, mask, size_int_kind (((tree_class_check ((utype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3947, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ) | ||||||
3947 | size_int (TYPE_PRECISION (utype) - sz))fold_build2_loc (((location_t) 0), RSHIFT_EXPR, utype, mask, size_int_kind (((tree_class_check ((utype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3947, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ); | ||||||
3948 | fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask)fold_build2_loc (((location_t) 0), BIT_AND_EXPR, utype, fldval , mask ); | ||||||
3949 | shift = bit - istart; | ||||||
3950 | if (BYTES_BIG_ENDIAN0) | ||||||
3951 | shift = TYPE_PRECISION (utype)((tree_class_check ((utype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3951, __FUNCTION__))->type_common.precision) - shift - sz; | ||||||
3952 | fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,fold_build2_loc (((location_t) 0), LSHIFT_EXPR, utype, fldval , size_int_kind (shift, stk_sizetype) ) | ||||||
3953 | size_int (shift))fold_build2_loc (((location_t) 0), LSHIFT_EXPR, utype, fldval , size_int_kind (shift, stk_sizetype) ); | ||||||
3954 | retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval)fold_build2_loc (((location_t) 0), BIT_IOR_EXPR, utype, retval , fldval ); | ||||||
3955 | fld_seen = true; | ||||||
3956 | } | ||||||
3957 | } | ||||||
3958 | } | ||||||
3959 | if (fld_seen) | ||||||
3960 | return fold_convert (TREE_TYPE (t), retval)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3960, __FUNCTION__))->typed.type), retval); | ||||||
3961 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 3961, __FUNCTION__)); | ||||||
3962 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||||
3963 | } | ||||||
3964 | |||||||
3965 | /* Helper for cxx_eval_bit_cast. | ||||||
3966 | Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From | ||||||
3967 | types and types of all subobjects have is_union_v<T>, is_pointer_v<T>, | ||||||
3968 | is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static | ||||||
3969 | data members of reference type. */ | ||||||
3970 | |||||||
3971 | static bool | ||||||
3972 | check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type, | ||||||
3973 | tree orig_type) | ||||||
3974 | { | ||||||
3975 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == UNION_TYPE) | ||||||
3976 | { | ||||||
3977 | if (!ctx->quiet) | ||||||
3978 | { | ||||||
3979 | if (type == orig_type) | ||||||
3980 | error_at (loc, "%qs is not a constant expression because %qT is " | ||||||
3981 | "a union type", "__builtin_bit_cast", type); | ||||||
3982 | else | ||||||
3983 | error_at (loc, "%qs is not a constant expression because %qT " | ||||||
3984 | "contains a union type", "__builtin_bit_cast", | ||||||
3985 | orig_type); | ||||||
3986 | } | ||||||
3987 | return true; | ||||||
3988 | } | ||||||
3989 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == POINTER_TYPE) | ||||||
3990 | { | ||||||
3991 | if (!ctx->quiet) | ||||||
3992 | { | ||||||
3993 | if (type == orig_type) | ||||||
3994 | error_at (loc, "%qs is not a constant expression because %qT is " | ||||||
3995 | "a pointer type", "__builtin_bit_cast", type); | ||||||
3996 | else | ||||||
3997 | error_at (loc, "%qs is not a constant expression because %qT " | ||||||
3998 | "contains a pointer type", "__builtin_bit_cast", | ||||||
3999 | orig_type); | ||||||
4000 | } | ||||||
4001 | return true; | ||||||
4002 | } | ||||||
4003 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == REFERENCE_TYPE) | ||||||
4004 | { | ||||||
4005 | if (!ctx->quiet) | ||||||
4006 | { | ||||||
4007 | if (type == orig_type) | ||||||
4008 | error_at (loc, "%qs is not a constant expression because %qT is " | ||||||
4009 | "a reference type", "__builtin_bit_cast", type); | ||||||
4010 | else | ||||||
4011 | error_at (loc, "%qs is not a constant expression because %qT " | ||||||
4012 | "contains a reference type", "__builtin_bit_cast", | ||||||
4013 | orig_type); | ||||||
4014 | } | ||||||
4015 | return true; | ||||||
4016 | } | ||||||
4017 | if (TYPE_PTRMEM_P (type)((((enum tree_code) (type)->base.code) == OFFSET_TYPE) || ( ((enum tree_code) (type)->base.code) == RECORD_TYPE && (((tree_class_check (((tree_check ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4017, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4017, __FUNCTION__))->type_common.lang_flag_2))))) | ||||||
4018 | { | ||||||
4019 | if (!ctx->quiet) | ||||||
4020 | { | ||||||
4021 | if (type == orig_type) | ||||||
4022 | error_at (loc, "%qs is not a constant expression because %qT is " | ||||||
4023 | "a pointer to member type", "__builtin_bit_cast", | ||||||
4024 | type); | ||||||
4025 | else | ||||||
4026 | error_at (loc, "%qs is not a constant expression because %qT " | ||||||
4027 | "contains a pointer to member type", | ||||||
4028 | "__builtin_bit_cast", orig_type); | ||||||
4029 | } | ||||||
4030 | return true; | ||||||
4031 | } | ||||||
4032 | if (TYPE_VOLATILE (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4032, __FUNCTION__))->base.volatile_flag)) | ||||||
4033 | { | ||||||
4034 | if (!ctx->quiet) | ||||||
4035 | { | ||||||
4036 | if (type == orig_type) | ||||||
4037 | error_at (loc, "%qs is not a constant expression because %qT is " | ||||||
4038 | "volatile", "__builtin_bit_cast", type); | ||||||
4039 | else | ||||||
4040 | error_at (loc, "%qs is not a constant expression because %qT " | ||||||
4041 | "contains a volatile subobject", | ||||||
4042 | "__builtin_bit_cast", orig_type); | ||||||
4043 | } | ||||||
4044 | return true; | ||||||
4045 | } | ||||||
4046 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE) | ||||||
4047 | for (tree field = TYPE_FIELDS (type)((tree_check3 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4047, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); field; field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4047, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4047, __FUNCTION__))->common.chain))) | ||||||
4048 | if (TREE_CODE (field)((enum tree_code) (field)->base.code) == FIELD_DECL | ||||||
4049 | && check_bit_cast_type (ctx, loc, TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4049, __FUNCTION__))->typed.type), orig_type)) | ||||||
4050 | return true; | ||||||
4051 | return false; | ||||||
4052 | } | ||||||
4053 | |||||||
4054 | /* Subroutine of cxx_eval_constant_expression. | ||||||
4055 | Attempt to evaluate a BIT_CAST_EXPR. */ | ||||||
4056 | |||||||
4057 | static tree | ||||||
4058 | cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p, | ||||||
4059 | bool *overflow_p) | ||||||
4060 | { | ||||||
4061 | if (check_bit_cast_type (ctx, EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)), TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4061, __FUNCTION__))->typed.type), | ||||||
4062 | TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4062, __FUNCTION__))->typed.type)) | ||||||
4063 | || check_bit_cast_type (ctx, cp_expr_loc_or_loc (TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4063, __FUNCTION__))))), | ||||||
4064 | EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0))), | ||||||
4065 | TREE_TYPE (TREE_OPERAND (t, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4065, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4065, __FUNCTION__))->typed.type), | ||||||
4066 | TREE_TYPE (TREE_OPERAND (t, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4066, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4066, __FUNCTION__))->typed.type))) | ||||||
4067 | { | ||||||
4068 | *non_constant_p = true; | ||||||
4069 | return t; | ||||||
4070 | } | ||||||
4071 | |||||||
4072 | tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4072, __FUNCTION__))))), false, | ||||||
4073 | non_constant_p, overflow_p); | ||||||
4074 | if (*non_constant_p) | ||||||
4075 | return t; | ||||||
4076 | |||||||
4077 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) ( (t))->base.code))]) >= tcc_reference && (tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); | ||||||
4078 | if (BITS_PER_UNIT(8) != 8 || CHAR_BIT8 != 8) | ||||||
4079 | { | ||||||
4080 | if (!ctx->quiet) | ||||||
4081 | sorry_at (loc, "%qs cannot be constant evaluated on the target", | ||||||
4082 | "__builtin_bit_cast"); | ||||||
4083 | *non_constant_p = true; | ||||||
4084 | return t; | ||||||
4085 | } | ||||||
4086 | |||||||
4087 | if (!tree_fits_shwi_p (TYPE_SIZE_UNIT (TREE_TYPE (t))((tree_class_check ((((contains_struct_check ((t), (TS_TYPED) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4087, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4087, __FUNCTION__))->type_common.size_unit))) | ||||||
4088 | { | ||||||
4089 | if (!ctx->quiet) | ||||||
4090 | sorry_at (loc, "%qs cannot be constant evaluated because the " | ||||||
4091 | "type is too large", "__builtin_bit_cast"); | ||||||
4092 | *non_constant_p = true; | ||||||
4093 | return t; | ||||||
4094 | } | ||||||
4095 | |||||||
4096 | HOST_WIDE_INTlong len = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (t))((tree_class_check ((((contains_struct_check ((t), (TS_TYPED) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4096, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4096, __FUNCTION__))->type_common.size_unit)); | ||||||
4097 | if (len < 0 || (int) len != len) | ||||||
4098 | { | ||||||
4099 | if (!ctx->quiet) | ||||||
4100 | sorry_at (loc, "%qs cannot be constant evaluated because the " | ||||||
4101 | "type is too large", "__builtin_bit_cast"); | ||||||
4102 | *non_constant_p = true; | ||||||
4103 | return t; | ||||||
4104 | } | ||||||
4105 | |||||||
4106 | unsigned char buf[64]; | ||||||
4107 | unsigned char *ptr, *mask; | ||||||
4108 | size_t alen = (size_t) len * 2; | ||||||
4109 | if (alen <= sizeof (buf)) | ||||||
4110 | ptr = buf; | ||||||
4111 | else | ||||||
4112 | ptr = XNEWVEC (unsigned char, alen)((unsigned char *) xmalloc (sizeof (unsigned char) * (alen))); | ||||||
4113 | mask = ptr + (size_t) len; | ||||||
4114 | /* At the beginning consider everything indeterminate. */ | ||||||
4115 | memset (mask, ~0, (size_t) len); | ||||||
4116 | |||||||
4117 | if (native_encode_initializer (op, ptr, len, 0, mask) != len) | ||||||
4118 | { | ||||||
4119 | if (!ctx->quiet) | ||||||
4120 | sorry_at (loc, "%qs cannot be constant evaluated because the " | ||||||
4121 | "argument cannot be encoded", "__builtin_bit_cast"); | ||||||
4122 | *non_constant_p = true; | ||||||
4123 | if (ptr != buf) | ||||||
4124 | XDELETE (ptr)free ((void*) (ptr)); | ||||||
4125 | return t; | ||||||
4126 | } | ||||||
4127 | |||||||
4128 | tree r = NULL_TREE(tree) nullptr; | ||||||
4129 | if (can_native_interpret_type_p (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4129, __FUNCTION__))->typed.type))) | ||||||
4130 | r = native_interpret_expr (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4130, __FUNCTION__))->typed.type), ptr, len); | ||||||
4131 | else if (TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4131, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE) | ||||||
4132 | { | ||||||
4133 | r = native_interpret_aggregate (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4133, __FUNCTION__))->typed.type), ptr, 0, len); | ||||||
4134 | if (r != NULL_TREE(tree) nullptr) | ||||||
4135 | clear_type_padding_in_mask (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4135, __FUNCTION__))->typed.type), mask); | ||||||
4136 | } | ||||||
4137 | |||||||
4138 | if (r != NULL_TREE(tree) nullptr) | ||||||
4139 | { | ||||||
4140 | for (int i = 0; i < len; i++) | ||||||
4141 | if (mask[i]) | ||||||
4142 | { | ||||||
4143 | if (!ctx->quiet) | ||||||
4144 | error_at (loc, "%qs accessing uninitialized byte at offset %d", | ||||||
4145 | "__builtin_bit_cast", i); | ||||||
4146 | *non_constant_p = true; | ||||||
4147 | r = t; | ||||||
4148 | break; | ||||||
4149 | } | ||||||
4150 | if (ptr != buf) | ||||||
4151 | XDELETE (ptr)free ((void*) (ptr)); | ||||||
4152 | return r; | ||||||
4153 | } | ||||||
4154 | |||||||
4155 | if (!ctx->quiet) | ||||||
4156 | sorry_at (loc, "%qs cannot be constant evaluated because the " | ||||||
4157 | "argument cannot be interpreted", "__builtin_bit_cast"); | ||||||
4158 | *non_constant_p = true; | ||||||
4159 | if (ptr != buf) | ||||||
4160 | XDELETE (ptr)free ((void*) (ptr)); | ||||||
4161 | return t; | ||||||
4162 | } | ||||||
4163 | |||||||
4164 | /* Subroutine of cxx_eval_constant_expression. | ||||||
4165 | Evaluate a short-circuited logical expression T in the context | ||||||
4166 | of a given constexpr CALL. BAILOUT_VALUE is the value for | ||||||
4167 | early return. CONTINUE_VALUE is used here purely for | ||||||
4168 | sanity check purposes. */ | ||||||
4169 | |||||||
4170 | static tree | ||||||
4171 | cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t, | ||||||
4172 | tree bailout_value, tree continue_value, | ||||||
4173 | bool lval, | ||||||
4174 | bool *non_constant_p, bool *overflow_p) | ||||||
4175 | { | ||||||
4176 | tree r; | ||||||
4177 | tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4177, __FUNCTION__))))), | ||||||
4178 | lval, | ||||||
4179 | non_constant_p, overflow_p); | ||||||
4180 | VERIFY_CONSTANT (lhs)do { if (verify_constant ((lhs), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); | ||||||
4181 | if (tree_int_cst_equal (lhs, bailout_value)) | ||||||
4182 | return lhs; | ||||||
4183 | gcc_assert (tree_int_cst_equal (lhs, continue_value))((void)(!(tree_int_cst_equal (lhs, continue_value)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4183, __FUNCTION__), 0 : 0)); | ||||||
4184 | r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4184, __FUNCTION__))))), | ||||||
4185 | lval, non_constant_p, | ||||||
4186 | overflow_p); | ||||||
4187 | VERIFY_CONSTANT (r)do { if (verify_constant ((r), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0); | ||||||
4188 | return r; | ||||||
4189 | } | ||||||
4190 | |||||||
4191 | /* REF is a COMPONENT_REF designating a particular field. V is a vector of | ||||||
4192 | CONSTRUCTOR elements to initialize (part of) an object containing that | ||||||
4193 | field. Return a pointer to the constructor_elt corresponding to the | ||||||
4194 | initialization of the field. */ | ||||||
4195 | |||||||
4196 | static constructor_elt * | ||||||
4197 | base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref) | ||||||
4198 | { | ||||||
4199 | tree aggr = TREE_OPERAND (ref, 0)(*((const_cast<tree*> (tree_operand_check ((ref), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4199, __FUNCTION__))))); | ||||||
4200 | tree field = TREE_OPERAND (ref, 1)(*((const_cast<tree*> (tree_operand_check ((ref), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4200, __FUNCTION__))))); | ||||||
4201 | HOST_WIDE_INTlong i; | ||||||
4202 | constructor_elt *ce; | ||||||
4203 | |||||||
4204 | gcc_assert (TREE_CODE (ref) == COMPONENT_REF)((void)(!(((enum tree_code) (ref)->base.code) == COMPONENT_REF ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4204, __FUNCTION__), 0 : 0)); | ||||||
4205 | |||||||
4206 | if (TREE_CODE (aggr)((enum tree_code) (aggr)->base.code) == COMPONENT_REF) | ||||||
4207 | { | ||||||
4208 | constructor_elt *base_ce | ||||||
4209 | = base_field_constructor_elt (v, aggr); | ||||||
4210 | v = CONSTRUCTOR_ELTS (base_ce->value)((tree_check ((base_ce->value), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4210, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
4211 | } | ||||||
4212 | |||||||
4213 | for (i = 0; vec_safe_iterate (v, i, &ce); ++i) | ||||||
4214 | if (ce->index == field) | ||||||
4215 | return ce; | ||||||
4216 | |||||||
4217 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4217, __FUNCTION__)); | ||||||
4218 | return NULLnullptr; | ||||||
4219 | } | ||||||
4220 | |||||||
4221 | /* Some of the expressions fed to the constexpr mechanism are calls to | ||||||
4222 | constructors, which have type void. In that case, return the type being | ||||||
4223 | initialized by the constructor. */ | ||||||
4224 | |||||||
4225 | static tree | ||||||
4226 | initialized_type (tree t) | ||||||
4227 | { | ||||||
4228 | if (TYPE_P (t)(tree_code_type[(int) (((enum tree_code) (t)->base.code))] == tcc_type)) | ||||||
4229 | return t; | ||||||
4230 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4230, __FUNCTION__))->typed.type); | ||||||
4231 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR) | ||||||
4232 | { | ||||||
4233 | /* A constructor call has void type, so we need to look deeper. */ | ||||||
4234 | tree fn = get_function_named_in_call (t); | ||||||
4235 | if (fn && TREE_CODE (fn)((enum tree_code) (fn)->base.code) == FUNCTION_DECL | ||||||
4236 | && DECL_CXX_CONSTRUCTOR_P (fn)((tree_check ((fn), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4236, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) | ||||||
4237 | type = DECL_CONTEXT (fn)((contains_struct_check ((fn), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4237, __FUNCTION__))->decl_minimal.context); | ||||||
4238 | } | ||||||
4239 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == COMPOUND_EXPR) | ||||||
4240 | return initialized_type (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4240, __FUNCTION__)))))); | ||||||
4241 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == AGGR_INIT_EXPR) | ||||||
4242 | type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4242, __FUNCTION__, (AGGR_INIT_EXPR)))), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4242, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4242, __FUNCTION__))->typed.type); | ||||||
4243 | return cv_unqualified (type); | ||||||
4244 | } | ||||||
4245 | |||||||
4246 | /* We're about to initialize element INDEX of an array or class from VALUE. | ||||||
4247 | Set up NEW_CTX appropriately by adjusting .object to refer to the | ||||||
4248 | subobject and creating a new CONSTRUCTOR if the element is itself | ||||||
4249 | a class or array. */ | ||||||
4250 | |||||||
4251 | static void | ||||||
4252 | init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx, | ||||||
4253 | tree index, tree &value) | ||||||
4254 | { | ||||||
4255 | new_ctx = *ctx; | ||||||
4256 | |||||||
4257 | if (index && TREE_CODE (index)((enum tree_code) (index)->base.code) != INTEGER_CST | ||||||
4258 | && TREE_CODE (index)((enum tree_code) (index)->base.code) != FIELD_DECL | ||||||
4259 | && TREE_CODE (index)((enum tree_code) (index)->base.code) != RANGE_EXPR) | ||||||
4260 | /* This won't have an element in the new CONSTRUCTOR. */ | ||||||
4261 | return; | ||||||
4262 | |||||||
4263 | tree type = initialized_type (value); | ||||||
4264 | if (!AGGREGATE_TYPE_P (type)(((enum tree_code) (type)->base.code) == ARRAY_TYPE || ((( enum tree_code) (type)->base.code) == RECORD_TYPE || ((enum tree_code) (type)->base.code) == UNION_TYPE || ((enum tree_code ) (type)->base.code) == QUAL_UNION_TYPE)) && !VECTOR_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE)) | ||||||
4265 | /* A non-aggregate member doesn't get its own CONSTRUCTOR. */ | ||||||
4266 | return; | ||||||
4267 | |||||||
4268 | /* The sub-aggregate initializer might contain a placeholder; | ||||||
4269 | update object to refer to the subobject and ctor to refer to | ||||||
4270 | the (newly created) sub-initializer. */ | ||||||
4271 | if (ctx->object) | ||||||
4272 | { | ||||||
4273 | if (index == NULL_TREE(tree) nullptr || TREE_CODE (index)((enum tree_code) (index)->base.code) == RANGE_EXPR) | ||||||
4274 | /* There's no well-defined subobject for this index. */ | ||||||
4275 | new_ctx.object = NULL_TREE(tree) nullptr; | ||||||
4276 | else | ||||||
4277 | new_ctx.object = build_ctor_subob_ref (index, type, ctx->object); | ||||||
4278 | } | ||||||
4279 | tree elt = build_constructor (type, NULLnullptr); | ||||||
4280 | CONSTRUCTOR_NO_CLEARING (elt)((tree_check ((elt), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4280, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = true; | ||||||
4281 | new_ctx.ctor = elt; | ||||||
4282 | |||||||
4283 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) == TARGET_EXPR) | ||||||
4284 | /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR. */ | ||||||
4285 | value = TARGET_EXPR_INITIAL (value)(*(tree_operand_check_code ((value), (TARGET_EXPR), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4285, __FUNCTION__))); | ||||||
4286 | } | ||||||
4287 | |||||||
4288 | /* We're about to process an initializer for a class or array TYPE. Make | ||||||
4289 | sure that CTX is set up appropriately. */ | ||||||
4290 | |||||||
4291 | static void | ||||||
4292 | verify_ctor_sanity (const constexpr_ctx *ctx, tree type) | ||||||
4293 | { | ||||||
4294 | /* We don't bother building a ctor for an empty base subobject. */ | ||||||
4295 | if (is_empty_class (type)) | ||||||
4296 | return; | ||||||
4297 | |||||||
4298 | /* We're in the middle of an initializer that might involve placeholders; | ||||||
4299 | our caller should have created a CONSTRUCTOR for us to put the | ||||||
4300 | initializer into. We will either return that constructor or T. */ | ||||||
4301 | gcc_assert (ctx->ctor)((void)(!(ctx->ctor) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4301, __FUNCTION__), 0 : 0)); | ||||||
4302 | gcc_assert (same_type_ignoring_top_level_qualifiers_p((void)(!(same_type_ignoring_top_level_qualifiers_p (type, (( contains_struct_check ((ctx->ctor), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4303, __FUNCTION__))->typed.type))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4303, __FUNCTION__), 0 : 0)) | ||||||
4303 | (type, TREE_TYPE (ctx->ctor)))((void)(!(same_type_ignoring_top_level_qualifiers_p (type, (( contains_struct_check ((ctx->ctor), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4303, __FUNCTION__))->typed.type))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4303, __FUNCTION__), 0 : 0)); | ||||||
4304 | /* We used to check that ctx->ctor was empty, but that isn't the case when | ||||||
4305 | the object is zero-initialized before calling the constructor. */ | ||||||
4306 | if (ctx->object) | ||||||
4307 | { | ||||||
4308 | tree otype = TREE_TYPE (ctx->object)((contains_struct_check ((ctx->object), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4308, __FUNCTION__))->typed.type); | ||||||
4309 | gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, otype)((void)(!(same_type_ignoring_top_level_qualifiers_p (type, otype ) || (((enum tree_code) (otype)->base.code) == ARRAY_TYPE && ((tree_check ((otype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4312, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) == (tree) nullptr && ((enum tree_code) (type)->base .code) == ARRAY_TYPE && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type), ((contains_struct_check ((otype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__), 0 : 0)) | ||||||
4310 | /* Handle flexible array members. */((void)(!(same_type_ignoring_top_level_qualifiers_p (type, otype ) || (((enum tree_code) (otype)->base.code) == ARRAY_TYPE && ((tree_check ((otype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4312, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) == (tree) nullptr && ((enum tree_code) (type)->base .code) == ARRAY_TYPE && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type), ((contains_struct_check ((otype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__), 0 : 0)) | ||||||
4311 | || (TREE_CODE (otype) == ARRAY_TYPE((void)(!(same_type_ignoring_top_level_qualifiers_p (type, otype ) || (((enum tree_code) (otype)->base.code) == ARRAY_TYPE && ((tree_check ((otype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4312, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) == (tree) nullptr && ((enum tree_code) (type)->base .code) == ARRAY_TYPE && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type), ((contains_struct_check ((otype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__), 0 : 0)) | ||||||
4312 | && TYPE_DOMAIN (otype) == NULL_TREE((void)(!(same_type_ignoring_top_level_qualifiers_p (type, otype ) || (((enum tree_code) (otype)->base.code) == ARRAY_TYPE && ((tree_check ((otype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4312, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) == (tree) nullptr && ((enum tree_code) (type)->base .code) == ARRAY_TYPE && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type), ((contains_struct_check ((otype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__), 0 : 0)) | ||||||
4313 | && TREE_CODE (type) == ARRAY_TYPE((void)(!(same_type_ignoring_top_level_qualifiers_p (type, otype ) || (((enum tree_code) (otype)->base.code) == ARRAY_TYPE && ((tree_check ((otype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4312, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) == (tree) nullptr && ((enum tree_code) (type)->base .code) == ARRAY_TYPE && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type), ((contains_struct_check ((otype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__), 0 : 0)) | ||||||
4314 | && (same_type_ignoring_top_level_qualifiers_p((void)(!(same_type_ignoring_top_level_qualifiers_p (type, otype ) || (((enum tree_code) (otype)->base.code) == ARRAY_TYPE && ((tree_check ((otype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4312, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) == (tree) nullptr && ((enum tree_code) (type)->base .code) == ARRAY_TYPE && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type), ((contains_struct_check ((otype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__), 0 : 0)) | ||||||
4315 | (TREE_TYPE (type), TREE_TYPE (otype)))))((void)(!(same_type_ignoring_top_level_qualifiers_p (type, otype ) || (((enum tree_code) (otype)->base.code) == ARRAY_TYPE && ((tree_check ((otype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4312, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ) == (tree) nullptr && ((enum tree_code) (type)->base .code) == ARRAY_TYPE && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((type), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type), ((contains_struct_check ((otype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__))->typed.type))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4315, __FUNCTION__), 0 : 0)); | ||||||
4316 | } | ||||||
4317 | gcc_assert (!ctx->object || !DECL_P (ctx->object)((void)(!(!ctx->object || !(tree_code_type[(int) (((enum tree_code ) (ctx->object)->base.code))] == tcc_declaration) || *( ctx->global->values.get (ctx->object)) == ctx->ctor ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4318, __FUNCTION__), 0 : 0)) | ||||||
4318 | || *(ctx->global->values.get (ctx->object)) == ctx->ctor)((void)(!(!ctx->object || !(tree_code_type[(int) (((enum tree_code ) (ctx->object)->base.code))] == tcc_declaration) || *( ctx->global->values.get (ctx->object)) == ctx->ctor ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4318, __FUNCTION__), 0 : 0)); | ||||||
4319 | } | ||||||
4320 | |||||||
4321 | /* Subroutine of cxx_eval_constant_expression. | ||||||
4322 | The expression tree T denotes a C-style array or a C-style | ||||||
4323 | aggregate. Reduce it to a constant expression. */ | ||||||
4324 | |||||||
4325 | static tree | ||||||
4326 | cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, | ||||||
4327 | bool lval, | ||||||
4328 | bool *non_constant_p, bool *overflow_p) | ||||||
4329 | { | ||||||
4330 | vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t)((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4330, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
4331 | bool changed = false; | ||||||
4332 | gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t))((void)(!(!(((enum tree_code) (t)->base.code) == CONSTRUCTOR && ((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4332, __FUNCTION__))->typed.type) == cp_global_trees[CPTI_INIT_LIST_TYPE ])) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4332, __FUNCTION__), 0 : 0)); | ||||||
4333 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4333, __FUNCTION__))->typed.type); | ||||||
4334 | |||||||
4335 | constexpr_ctx new_ctx; | ||||||
4336 | if (TYPE_PTRMEMFUNC_P (type)(((enum tree_code) (type)->base.code) == RECORD_TYPE && (((tree_class_check (((tree_check ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4336, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4336, __FUNCTION__))->type_common.lang_flag_2))) || VECTOR_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE)) | ||||||
4337 | { | ||||||
4338 | /* We don't really need the ctx->ctor business for a PMF or | ||||||
4339 | vector, but it's simpler to use the same code. */ | ||||||
4340 | new_ctx = *ctx; | ||||||
4341 | new_ctx.ctor = build_constructor (type, NULLnullptr); | ||||||
4342 | new_ctx.object = NULL_TREE(tree) nullptr; | ||||||
4343 | ctx = &new_ctx; | ||||||
4344 | }; | ||||||
4345 | verify_ctor_sanity (ctx, type); | ||||||
4346 | vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor)((tree_check ((ctx->ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4346, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
4347 | vec_alloc (*p, vec_safe_length (v)); | ||||||
4348 | |||||||
4349 | if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t)(((tree_not_check2 (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4349, __FUNCTION__, (CONSTRUCTOR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4349, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_5))) | ||||||
4350 | CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor)(((tree_not_check2 (((tree_check ((ctx->ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4350, __FUNCTION__, (CONSTRUCTOR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4350, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_5)) = 1; | ||||||
4351 | |||||||
4352 | unsigned i; | ||||||
4353 | tree index, value; | ||||||
4354 | bool constant_p = true; | ||||||
4355 | bool side_effects_p = false; | ||||||
4356 | FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)for (i = 0; (i >= vec_safe_length (v)) ? false : (((void) ( value = (*v)[i].value)), (index = (*v)[i].index), true); (i)++ ) | ||||||
4357 | { | ||||||
4358 | tree orig_value = value; | ||||||
4359 | init_subob_ctx (ctx, new_ctx, index, value); | ||||||
4360 | int pos_hint = -1; | ||||||
4361 | if (new_ctx.ctor != ctx->ctor) | ||||||
4362 | { | ||||||
4363 | /* If we built a new CONSTRUCTOR, attach it now so that other | ||||||
4364 | initializers can refer to it. */ | ||||||
4365 | constructor_elt *cep = get_or_insert_ctor_field (ctx->ctor, index); | ||||||
4366 | cep->value = new_ctx.ctor; | ||||||
4367 | pos_hint = cep - (*p)->begin(); | ||||||
4368 | } | ||||||
4369 | else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == UNION_TYPE) | ||||||
4370 | /* Otherwise if we're constructing a non-aggregate union member, set | ||||||
4371 | the active union member now so that we can later detect and diagnose | ||||||
4372 | if its initializer attempts to activate another member. */ | ||||||
4373 | get_or_insert_ctor_field (ctx->ctor, index); | ||||||
4374 | tree elt = cxx_eval_constant_expression (&new_ctx, value, | ||||||
4375 | lval, | ||||||
4376 | non_constant_p, overflow_p); | ||||||
4377 | /* Don't VERIFY_CONSTANT here. */ | ||||||
4378 | if (ctx->quiet && *non_constant_p) | ||||||
4379 | break; | ||||||
4380 | if (elt != orig_value) | ||||||
4381 | changed = true; | ||||||
4382 | |||||||
4383 | if (!TREE_CONSTANT (elt)((non_type_check ((elt), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4383, __FUNCTION__))->base.constant_flag)) | ||||||
4384 | constant_p = false; | ||||||
4385 | if (TREE_SIDE_EFFECTS (elt)((non_type_check ((elt), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4385, __FUNCTION__))->base.side_effects_flag)) | ||||||
4386 | side_effects_p = true; | ||||||
4387 | if (index && TREE_CODE (index)((enum tree_code) (index)->base.code) == COMPONENT_REF) | ||||||
4388 | { | ||||||
4389 | /* This is an initialization of a vfield inside a base | ||||||
4390 | subaggregate that we already initialized; push this | ||||||
4391 | initialization into the previous initialization. */ | ||||||
4392 | constructor_elt *inner = base_field_constructor_elt (*p, index); | ||||||
4393 | inner->value = elt; | ||||||
4394 | changed = true; | ||||||
4395 | } | ||||||
4396 | else if (index | ||||||
4397 | && (TREE_CODE (index)((enum tree_code) (index)->base.code) == NOP_EXPR | ||||||
4398 | || TREE_CODE (index)((enum tree_code) (index)->base.code) == POINTER_PLUS_EXPR)) | ||||||
4399 | { | ||||||
4400 | /* This is an initializer for an empty base; now that we've | ||||||
4401 | checked that it's constant, we can ignore it. */ | ||||||
4402 | gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index))))((void)(!(is_empty_class (((contains_struct_check ((((contains_struct_check ((index), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4402, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4402, __FUNCTION__))->typed.type))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4402, __FUNCTION__), 0 : 0)); | ||||||
4403 | changed = true; | ||||||
4404 | } | ||||||
4405 | else | ||||||
4406 | { | ||||||
4407 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == UNION_TYPE | ||||||
4408 | && (*p)->last().index != index) | ||||||
4409 | /* The initializer erroneously changed the active union member that | ||||||
4410 | we're initializing. */ | ||||||
4411 | gcc_assert (*non_constant_p)((void)(!(*non_constant_p) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4411, __FUNCTION__), 0 : 0)); | ||||||
4412 | else | ||||||
4413 | { | ||||||
4414 | /* The initializer might have mutated the underlying CONSTRUCTOR, | ||||||
4415 | so recompute the location of the target constructer_elt. */ | ||||||
4416 | constructor_elt *cep | ||||||
4417 | = get_or_insert_ctor_field (ctx->ctor, index, pos_hint); | ||||||
4418 | cep->value = elt; | ||||||
4419 | } | ||||||
4420 | |||||||
4421 | /* Adding or replacing an element might change the ctor's flags. */ | ||||||
4422 | TREE_CONSTANT (ctx->ctor)((non_type_check ((ctx->ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4422, __FUNCTION__))->base.constant_flag) = constant_p; | ||||||
4423 | TREE_SIDE_EFFECTS (ctx->ctor)((non_type_check ((ctx->ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4423, __FUNCTION__))->base.side_effects_flag) = side_effects_p; | ||||||
4424 | } | ||||||
4425 | } | ||||||
4426 | if (*non_constant_p || !changed) | ||||||
4427 | return t; | ||||||
4428 | t = ctx->ctor; | ||||||
4429 | /* We're done building this CONSTRUCTOR, so now we can interpret an | ||||||
4430 | element without an explicit initializer as value-initialized. */ | ||||||
4431 | CONSTRUCTOR_NO_CLEARING (t)((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4431, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = false; | ||||||
4432 | TREE_CONSTANT (t)((non_type_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4432, __FUNCTION__))->base.constant_flag) = constant_p; | ||||||
4433 | TREE_SIDE_EFFECTS (t)((non_type_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4433, __FUNCTION__))->base.side_effects_flag) = side_effects_p; | ||||||
4434 | if (VECTOR_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE)) | ||||||
4435 | t = fold (t); | ||||||
4436 | return t; | ||||||
4437 | } | ||||||
4438 | |||||||
4439 | /* Subroutine of cxx_eval_constant_expression. | ||||||
4440 | The expression tree T is a VEC_INIT_EXPR which denotes the desired | ||||||
4441 | initialization of a non-static data member of array type. Reduce it to a | ||||||
4442 | CONSTRUCTOR. | ||||||
4443 | |||||||
4444 | Note that apart from value-initialization (when VALUE_INIT is true), | ||||||
4445 | this is only intended to support value-initialization and the | ||||||
4446 | initializations done by defaulted constructors for classes with | ||||||
4447 | non-static data members of array type. In this case, VEC_INIT_EXPR_INIT | ||||||
4448 | will either be NULL_TREE for the default constructor, or a COMPONENT_REF | ||||||
4449 | for the copy/move constructor. */ | ||||||
4450 | |||||||
4451 | static tree | ||||||
4452 | cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, | ||||||
4453 | bool value_init, bool lval, | ||||||
4454 | bool *non_constant_p, bool *overflow_p) | ||||||
4455 | { | ||||||
4456 | tree elttype = TREE_TYPE (atype)((contains_struct_check ((atype), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4456, __FUNCTION__))->typed.type); | ||||||
4457 | verify_ctor_sanity (ctx, atype); | ||||||
4458 | vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor)((tree_check ((ctx->ctor), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.c" , 4458, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); | ||||||
4459 | bool pre_init = false; | ||||||
4460 | unsigned HOST_WIDE_INTlong i; | ||||||
4461 | tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error; | ||||||
4462 | |||||||
4463 | if (init && TREE_CODE (init)((enum tree_code) (init)->base.code) == CONSTRUCTOR) | ||||||
4464 | return cxx_eval_bare_aggregate (ctx, init, lval, | ||||||
4465 | non_constant_p, overflow_p); | ||||||
4466 | |||||||
4467 | /* For the default constructor, build up a call to the default | ||||||
4468 | constructor of the element type. We only need to handle class types | ||||||
4469 | here, as for a constructor to be constexpr, all members must be | ||||||
4470 | initialized, which for a defaulted default constructor means they must | ||||||
4471 | be of a class type with a constexpr default constructor. */ | ||||||
4472 | if (TREE_CODE (elttype)((enum tree_code) (elttype)->base.code) == ARRAY_TYPE) | ||||||
4473 | /* We only do this at the lowest level. */; | ||||||
4474 | else if (value_init) | ||||||
4475 | { |