File: | build/gcc/cp/constexpr.cc |
Warning: | line 6060, column 8 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-2023 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 "timevar.h" |
35 | #include "fold-const-call.h" |
36 | #include "stor-layout.h" |
37 | #include "cgraph.h" |
38 | #include "opts.h" |
39 | #include "stringpool.h" |
40 | #include "attribs.h" |
41 | #include "fold-const.h" |
42 | #include "intl.h" |
43 | #include "toplev.h" |
44 | |
45 | static bool verify_constant (tree, bool, bool *, bool *); |
46 | #define VERIFY_CONSTANT(X)do { if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0) \ |
47 | do { \ |
48 | if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \ |
49 | return t; \ |
50 | } while (0) |
51 | |
52 | static HOST_WIDE_INTlong find_array_ctor_elt (tree ary, tree dindex, |
53 | bool insert = false); |
54 | static int array_index_cmp (tree key, tree index); |
55 | |
56 | /* Returns true iff FUN is an instantiation of a constexpr function |
57 | template or a defaulted constexpr function. */ |
58 | |
59 | bool |
60 | is_instantiation_of_constexpr (tree fun) |
61 | { |
62 | return ((DECL_TEMPLOID_INSTANTIATION (fun)(((((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 62, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 62, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 62, __FUNCTION__)), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 62, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info) && !(((contains_struct_check ((fun), ( TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 62, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) |
63 | && 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__)), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__)), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__, (TEMPLATE_INFO))))->tmpl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__, (TEMPLATE_DECL))))))))->result : ((struct tree_template_info*)(tree_check (((((contains_struct_check ( (template_info_decl_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__)), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__, (TEMPLATE_INFO))))->tmpl)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 63, __FUNCTION__))->decl_common.lang_flag_8)) |
64 | || (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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 64, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun)) , (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 64, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 64, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 64, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 64, __FUNCTION__); <->u.fn; })->defaulted_p) |
65 | && 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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 65, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun)) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 65, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 65, __FUNCTION__))->decl_common.lang_flag_8))); |
66 | } |
67 | |
68 | /* Return true if T is a literal type. */ |
69 | |
70 | bool |
71 | literal_type_p (tree t) |
72 | { |
73 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 73, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 73, __FUNCTION__))->type_common.lang_flag_2))) || (((enum tree_code) (t)->base.code) == NULLPTR_TYPE)) |
74 | || VECTOR_TYPE_P (t)(((enum tree_code) (t)->base.code) == VECTOR_TYPE) |
75 | || TYPE_REF_P (t)(((enum tree_code) (t)->base.code) == REFERENCE_TYPE) |
76 | || (VOID_TYPE_P (t)(((enum tree_code) (t)->base.code) == VOID_TYPE) && cxx_dialect >= cxx14)) |
77 | return true; |
78 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 78, __FUNCTION__))->type_common.lang_flag_5))) |
79 | { |
80 | t = complete_type (t); |
81 | gcc_assert (COMPLETE_TYPE_P (t) || errorcount)((void)(!((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 81, __FUNCTION__))->type_common.size) != (tree) __null) || (global_dc)->diagnostic_count[(int) (DK_ERROR)]) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 81, __FUNCTION__), 0 : 0)); |
82 | return CLASSTYPE_LITERAL_P (t)((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 82, __FUNCTION__))->type_with_lang_specific.lang_specific ))->is_literal); |
83 | } |
84 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_TYPE) |
85 | return literal_type_p (strip_array_types (t)); |
86 | return false; |
87 | } |
88 | |
89 | /* If DECL is a variable declared `constexpr', require its type |
90 | be literal. Return error_mark_node if we give an error, the |
91 | DECL otherwise. */ |
92 | |
93 | tree |
94 | ensure_literal_type_for_constexpr_object (tree decl) |
95 | { |
96 | tree type = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 96, __FUNCTION__))->typed.type); |
97 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) |
98 | && (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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 98, __FUNCTION__, (TEMPLATE_DECL))))))))->result : decl) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 98, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 98, __FUNCTION__))->decl_common.lang_flag_8) |
99 | || var_in_constexpr_fn (decl)) |
100 | && !processing_template_declscope_chain->x_processing_template_decl) |
101 | { |
102 | tree stype = strip_array_types (type); |
103 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 103, __FUNCTION__))->type_common.lang_flag_5)) && !COMPLETE_TYPE_P (complete_type (stype))(((tree_class_check ((complete_type (stype)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 103, __FUNCTION__))->type_common.size) != (tree) __null)) |
104 | /* Don't complain here, we'll complain about incompleteness |
105 | when we try to initialize the variable. */; |
106 | else if (!literal_type_p (type)) |
107 | { |
108 | 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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 108, __FUNCTION__, (TEMPLATE_DECL))))))))->result : decl )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 108, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 108, __FUNCTION__))->decl_common.lang_flag_8)) |
109 | { |
110 | auto_diagnostic_group d; |
111 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 111, __FUNCTION__))->decl_minimal.locus), |
112 | "the type %qT of %<constexpr%> variable %qD " |
113 | "is not literal", type, decl); |
114 | explain_non_literal_class (type); |
115 | decl = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
116 | } |
117 | else if (cxx_dialect < cxx23) |
118 | { |
119 | if (!is_instantiation_of_constexpr (current_function_decl)) |
120 | { |
121 | auto_diagnostic_group d; |
122 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 122, __FUNCTION__))->decl_minimal.locus), |
123 | "variable %qD of non-literal type %qT in " |
124 | "%<constexpr%> function only available with " |
125 | "%<-std=c++2b%> or %<-std=gnu++2b%>", decl, type); |
126 | explain_non_literal_class (type); |
127 | decl = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
128 | } |
129 | cp_function_chain((cfun + 0)->language)->invalid_constexpr = true; |
130 | } |
131 | } |
132 | 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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 132, __FUNCTION__, (TEMPLATE_DECL))))))))->result : decl )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 132, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 132, __FUNCTION__))->decl_common.lang_flag_8) |
133 | && variably_modified_type_p (type, NULL_TREE(tree) __null)) |
134 | { |
135 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 135, __FUNCTION__))->decl_minimal.locus), |
136 | "%<constexpr%> variable %qD has variably-modified " |
137 | "type %qT", decl, type); |
138 | decl = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
139 | } |
140 | } |
141 | return decl; |
142 | } |
143 | |
144 | /* Issue a diagnostic with text GMSGID for constructs that are invalid in |
145 | constexpr functions. CONSTEXPR_FUNDEF_P is true if we're checking |
146 | a constexpr function body; if so, don't report hard errors and issue |
147 | a pedwarn pre-C++23, or a warning in C++23, if requested by |
148 | -Winvalid-constexpr. Otherwise, we're not in the context where we are |
149 | checking if a function can be marked 'constexpr', so give a hard error. */ |
150 | |
151 | ATTRIBUTE_GCC_DIAG(3,4)__attribute__ ((__format__ (__gcc_cxxdiag__, 3, 4))) __attribute__ ((__nonnull__ (3))) |
152 | static bool |
153 | constexpr_error (location_t location, bool constexpr_fundef_p, |
154 | const char *gmsgid, ...) |
155 | { |
156 | diagnostic_info diagnostic; |
157 | va_list ap; |
158 | rich_location richloc (line_table, location); |
159 | va_start (ap, gmsgid)__builtin_va_start(ap, gmsgid); |
160 | bool ret; |
161 | if (!constexpr_fundef_p) |
162 | { |
163 | /* Report an error that cannot be suppressed. */ |
164 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR); |
165 | ret = diagnostic_report_diagnostic (global_dc, &diagnostic); |
166 | } |
167 | else if (warn_invalid_constexprglobal_options.x_warn_invalid_constexpr) |
168 | { |
169 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, |
170 | cxx_dialect < cxx23 ? DK_PEDWARN : DK_WARNING); |
171 | diagnostic.option_index = OPT_Winvalid_constexpr; |
172 | ret = diagnostic_report_diagnostic (global_dc, &diagnostic); |
173 | } |
174 | else |
175 | ret = false; |
176 | va_end (ap)__builtin_va_end(ap); |
177 | return ret; |
178 | } |
179 | |
180 | struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef> |
181 | { |
182 | static hashval_t hash (const constexpr_fundef *); |
183 | static bool equal (const constexpr_fundef *, const constexpr_fundef *); |
184 | }; |
185 | |
186 | /* This table holds all constexpr function definitions seen in |
187 | the current translation unit. */ |
188 | |
189 | static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table; |
190 | |
191 | /* Utility function used for managing the constexpr function table. |
192 | Return true if the entries pointed to by P and Q are for the |
193 | same constexpr function. */ |
194 | |
195 | inline bool |
196 | constexpr_fundef_hasher::equal (const constexpr_fundef *lhs, |
197 | const constexpr_fundef *rhs) |
198 | { |
199 | return lhs->decl == rhs->decl; |
200 | } |
201 | |
202 | /* Utility function used for managing the constexpr function table. |
203 | Return a hash value for the entry pointed to by Q. */ |
204 | |
205 | inline hashval_t |
206 | constexpr_fundef_hasher::hash (const constexpr_fundef *fundef) |
207 | { |
208 | return DECL_UID (fundef->decl)((contains_struct_check ((fundef->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 208, __FUNCTION__))->decl_minimal.uid); |
209 | } |
210 | |
211 | /* Return a previously saved definition of function FUN. */ |
212 | |
213 | constexpr_fundef * |
214 | retrieve_constexpr_fundef (tree fun) |
215 | { |
216 | if (constexpr_fundef_table == NULL__null) |
217 | return NULL__null; |
218 | |
219 | constexpr_fundef fundef = { fun, NULL_TREE(tree) __null, NULL_TREE(tree) __null, NULL_TREE(tree) __null }; |
220 | return constexpr_fundef_table->find (&fundef); |
221 | } |
222 | |
223 | /* Check whether the parameter and return types of FUN are valid for a |
224 | constexpr function, and complain if COMPLAIN. */ |
225 | |
226 | bool |
227 | is_valid_constexpr_fn (tree fun, bool complain) |
228 | { |
229 | bool ret = true; |
230 | |
231 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 231, __FUNCTION__); <->u.fn; })->context : (tree ) __null) |
232 | && TREE_CODE (fun)((enum tree_code) (fun)->base.code) == TEMPLATE_DECL) |
233 | { |
234 | ret = false; |
235 | if (complain) |
236 | error ("inherited constructor %qD is not %<constexpr%>", |
237 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 237, __FUNCTION__); <->u.fn; })->context : (tree ) __null)); |
238 | } |
239 | else |
240 | { |
241 | for (tree parm = FUNCTION_FIRST_USER_PARM (fun)skip_artificial_parms_for ((fun), ((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 241, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments )); |
242 | parm != NULL_TREE(tree) __null; parm = TREE_CHAIN (parm)((contains_struct_check ((parm), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 242, __FUNCTION__))->common.chain)) |
243 | if (!literal_type_p (TREE_TYPE (parm)((contains_struct_check ((parm), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 243, __FUNCTION__))->typed.type))) |
244 | { |
245 | ret = false; |
246 | if (complain) |
247 | { |
248 | auto_diagnostic_group d; |
249 | if (constexpr_error (input_location, /*constexpr_fundef_p*/true, |
250 | "invalid type for parameter %d of " |
251 | "%<constexpr%> function %q+#D", |
252 | DECL_PARM_INDEX (parm)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check ((parm), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 252, __FUNCTION__))->decl_common.lang_specific); if (((enum tree_code) (parm)->base.code) != PARM_DECL || lt->u.base .selector != lds_parm) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 252, __FUNCTION__); <->u.parm; })->index), fun)) |
253 | explain_non_literal_class (TREE_TYPE (parm)((contains_struct_check ((parm), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 253, __FUNCTION__))->typed.type)); |
254 | } |
255 | } |
256 | } |
257 | |
258 | if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))(((enum tree_code) ((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name) && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name))) && ((tree_check ((((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name) && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__))->type_common.name)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 258, __FUNCTION__, (IDENTIFIER_NODE)))->base.protected_flag )) && cxx_dialect < cxx17) |
259 | { |
260 | ret = false; |
261 | if (complain) |
262 | inform (DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 262, __FUNCTION__))->decl_minimal.locus), |
263 | "lambdas are implicitly %<constexpr%> only in C++17 and later"); |
264 | } |
265 | else if (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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 265, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 265, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) |
266 | { |
267 | if (cxx_dialect < cxx20) |
268 | { |
269 | ret = false; |
270 | if (complain) |
271 | error_at (DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 271, __FUNCTION__))->decl_minimal.locus), |
272 | "%<constexpr%> destructors only available" |
273 | " with %<-std=c++20%> or %<-std=gnu++20%>"); |
274 | } |
275 | } |
276 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 276, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 276, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
277 | { |
278 | tree rettype = TREE_TYPE (TREE_TYPE (fun))((contains_struct_check ((((contains_struct_check ((fun), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 278, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 278, __FUNCTION__))->typed.type); |
279 | if (!literal_type_p (rettype)) |
280 | { |
281 | ret = false; |
282 | if (complain) |
283 | { |
284 | auto_diagnostic_group d; |
285 | if (constexpr_error (input_location, /*constexpr_fundef_p*/true, |
286 | "invalid return type %qT of %<constexpr%> " |
287 | "function %q+D", rettype, fun)) |
288 | explain_non_literal_class (rettype); |
289 | } |
290 | } |
291 | |
292 | /* C++14 DR 1684 removed this restriction. */ |
293 | if (cxx_dialect < cxx14 |
294 | && DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)(((enum tree_code) (((contains_struct_check ((fun), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 294, __FUNCTION__))->typed.type))->base.code) == METHOD_TYPE ) |
295 | && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun))((((tree_class_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 295, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 295, __FUNCTION__))->type_with_lang_specific.lang_specific ))->is_literal)) |
296 | { |
297 | ret = false; |
298 | if (complain) |
299 | { |
300 | auto_diagnostic_group d; |
301 | if (pedwarn (DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 301, __FUNCTION__))->decl_minimal.locus), OPT_Wpedantic, |
302 | "enclosing class of %<constexpr%> non-static" |
303 | " member function %q+#D is not a literal type", |
304 | fun)) |
305 | explain_non_literal_class (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 305, __FUNCTION__))->decl_minimal.context)); |
306 | } |
307 | } |
308 | } |
309 | else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun))((((tree_class_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 309, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 309, __FUNCTION__))->type_with_lang_specific.lang_specific ))->vbases)) |
310 | { |
311 | ret = false; |
312 | if (complain) |
313 | error ("%q#T has virtual base classes", DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 313, __FUNCTION__))->decl_minimal.context)); |
314 | } |
315 | |
316 | return ret; |
317 | } |
318 | |
319 | /* Subroutine of build_data_member_initialization. MEMBER is a COMPONENT_REF |
320 | for a member of an anonymous aggregate, INIT is the initializer for that |
321 | member, and VEC_OUTER is the vector of constructor elements for the class |
322 | whose constructor we are processing. Add the initializer to the vector |
323 | and return true to indicate success. */ |
324 | |
325 | static bool |
326 | build_anon_member_initialization (tree member, tree init, |
327 | vec<constructor_elt, va_gc> **vec_outer) |
328 | { |
329 | /* MEMBER presents the relevant fields from the inside out, but we need |
330 | to build up the initializer from the outside in so that we can reuse |
331 | previously built CONSTRUCTORs if this is, say, the second field in an |
332 | anonymous struct. So we use a vec as a stack. */ |
333 | auto_vec<tree, 2> fields; |
334 | do |
335 | { |
336 | fields.safe_push (TREE_OPERAND (member, 1)(*((const_cast<tree*> (tree_operand_check ((member), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 336, __FUNCTION__)))))); |
337 | member = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 337, __FUNCTION__))))); |
338 | } |
339 | while (ANON_AGGR_TYPE_P (TREE_TYPE (member))((((((enum tree_code) (((contains_struct_check ((member), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 339, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((member), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 339, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((member ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 339, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 339, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((member), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 339, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 339, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr) |
340 | && TREE_CODE (member)((enum tree_code) (member)->base.code) == COMPONENT_REF); |
341 | |
342 | /* VEC has the constructor elements vector for the context of FIELD. |
343 | If FIELD is an anonymous aggregate, we will push inside it. */ |
344 | vec<constructor_elt, va_gc> **vec = vec_outer; |
345 | tree field; |
346 | while (field = fields.pop(), |
347 | ANON_AGGR_TYPE_P (TREE_TYPE (field))((((((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 347, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 347, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((field ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 347, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 347, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((field), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 347, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 347, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) |
348 | { |
349 | tree ctor; |
350 | /* If there is already an outer constructor entry for the anonymous |
351 | aggregate FIELD, use it; otherwise, insert one. */ |
352 | if (vec_safe_is_empty (*vec) |
353 | || (*vec)->last().index != field) |
354 | { |
355 | ctor = build_constructor (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 355, __FUNCTION__))->typed.type), NULL__null); |
356 | CONSTRUCTOR_APPEND_ELT (*vec, field, ctor)do { constructor_elt _ce___ = {field, ctor}; vec_safe_push (( *vec), _ce___); } while (0); |
357 | } |
358 | else |
359 | ctor = (*vec)->last().value; |
360 | vec = &CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 360, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
361 | } |
362 | |
363 | /* Now we're at the innermost field, the one that isn't an anonymous |
364 | aggregate. Add its initializer to the CONSTRUCTOR and we're done. */ |
365 | gcc_assert (fields.is_empty())((void)(!(fields.is_empty()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 365, __FUNCTION__), 0 : 0)); |
366 | CONSTRUCTOR_APPEND_ELT (*vec, field, init)do { constructor_elt _ce___ = {field, init}; vec_safe_push (( *vec), _ce___); } while (0); |
367 | |
368 | return true; |
369 | } |
370 | |
371 | /* Subroutine of build_constexpr_constructor_member_initializers. |
372 | The expression tree T represents a data member initialization |
373 | in a (constexpr) constructor definition. Build a pairing of |
374 | the data member with its initializer, and prepend that pair |
375 | to the existing initialization pair INITS. */ |
376 | |
377 | static bool |
378 | build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec) |
379 | { |
380 | tree member, init; |
381 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CLEANUP_POINT_EXPR) |
382 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 382, __FUNCTION__))))); |
383 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == EXPR_STMT) |
384 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 384, __FUNCTION__))))); |
385 | if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
386 | return false; |
387 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == STATEMENT_LIST) |
388 | { |
389 | for (tree stmt : tsi_range (t)) |
390 | if (! build_data_member_initialization (stmt, vec)) |
391 | return false; |
392 | return true; |
393 | } |
394 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CLEANUP_STMT) |
395 | { |
396 | /* We can't see a CLEANUP_STMT in a constructor for a literal class, |
397 | but we can in a constexpr constructor for a non-literal class. Just |
398 | ignore it; either all the initialization will be constant, in which |
399 | case the cleanup can't run, or it can't be constexpr. |
400 | Still recurse into CLEANUP_BODY. */ |
401 | return build_data_member_initialization (CLEANUP_BODY (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 401, __FUNCTION__, (CLEANUP_STMT)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 401, __FUNCTION__))))), vec); |
402 | } |
403 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CONVERT_EXPR) |
404 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 404, __FUNCTION__))))); |
405 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == INIT_EXPR |
406 | /* vptr initialization shows up as a MODIFY_EXPR. In C++14 we only |
407 | use what this function builds for cx_check_missing_mem_inits, and |
408 | assignment in the ctor body doesn't count. */ |
409 | || (cxx_dialect < cxx14 && TREE_CODE (t)((enum tree_code) (t)->base.code) == MODIFY_EXPR)) |
410 | { |
411 | member = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 411, __FUNCTION__))))); |
412 | init = break_out_target_exprs (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 412, __FUNCTION__)))))); |
413 | } |
414 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR) |
415 | { |
416 | tree fn = get_callee_fndecl (t); |
417 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 417, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fn)) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 417, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
418 | /* We're only interested in calls to subobject constructors. */ |
419 | return true; |
420 | member = CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 420, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 420, __FUNCTION__))))); |
421 | /* We don't use build_cplus_new here because it complains about |
422 | abstract bases. Leaving the call unwrapped means that it has the |
423 | wrong type, but cxx_eval_constant_expression doesn't care. */ |
424 | init = break_out_target_exprs (t); |
425 | } |
426 | else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == BIND_EXPR) |
427 | return build_data_member_initialization (BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 427, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 427, __FUNCTION__)))))), vec); |
428 | else |
429 | /* Don't add anything else to the CONSTRUCTOR. */ |
430 | return true; |
431 | if (INDIRECT_REF_P (member)(((enum tree_code) (member)->base.code) == INDIRECT_REF)) |
432 | member = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 432, __FUNCTION__))))); |
433 | if (TREE_CODE (member)((enum tree_code) (member)->base.code) == NOP_EXPR) |
434 | { |
435 | tree op = member; |
436 | STRIP_NOPS (op)(op) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((op))))); |
437 | if (TREE_CODE (op)((enum tree_code) (op)->base.code) == ADDR_EXPR) |
438 | { |
439 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 440, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 440, __FUNCTION__))->typed.type), ((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__), 0 : 0)) |
440 | (TREE_TYPE (TREE_TYPE (op)),((void)(!(same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 440, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 440, __FUNCTION__))->typed.type), ((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__), 0 : 0)) |
441 | TREE_TYPE (TREE_TYPE (member))))((void)(!(same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((((contains_struct_check ((op), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 440, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 440, __FUNCTION__))->typed.type), ((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 441, __FUNCTION__), 0 : 0)); |
442 | /* Initializing a cv-qualified member; we need to look through |
443 | the const_cast. */ |
444 | member = op; |
445 | } |
446 | else if (op == current_class_ptr(*((cfun + 0) && ((cfun + 0)->language) ? &((cfun + 0)->language)->x_current_class_ptr : &scope_chain ->x_current_class_ptr)) |
447 | && (same_type_ignoring_top_level_qualifiers_p |
448 | (TREE_TYPE (TREE_TYPE (member))((contains_struct_check ((((contains_struct_check ((member), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 448, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 448, __FUNCTION__))->typed.type), |
449 | current_class_typescope_chain->class_type))) |
450 | /* Delegating constructor. */ |
451 | member = op; |
452 | else |
453 | { |
454 | /* This is an initializer for an empty base; keep it for now so |
455 | we can check it in cxx_eval_bare_aggregate. */ |
456 | gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))))((void)(!(is_empty_class (((contains_struct_check ((((contains_struct_check ((member), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 456, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 456, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 456, __FUNCTION__), 0 : 0)); |
457 | } |
458 | } |
459 | if (TREE_CODE (member)((enum tree_code) (member)->base.code) == ADDR_EXPR) |
460 | member = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 460, __FUNCTION__))))); |
461 | if (TREE_CODE (member)((enum tree_code) (member)->base.code) == COMPONENT_REF) |
462 | { |
463 | tree aggr = TREE_OPERAND (member, 0)(*((const_cast<tree*> (tree_operand_check ((member), (0 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 463, __FUNCTION__))))); |
464 | if (TREE_CODE (aggr)((enum tree_code) (aggr)->base.code) == VAR_DECL) |
465 | /* Initializing a local variable, don't add anything. */ |
466 | return true; |
467 | if (TREE_CODE (aggr)((enum tree_code) (aggr)->base.code) != COMPONENT_REF) |
468 | /* Normal member initialization. */ |
469 | member = TREE_OPERAND (member, 1)(*((const_cast<tree*> (tree_operand_check ((member), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 469, __FUNCTION__))))); |
470 | else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr))((((((enum tree_code) (((contains_struct_check ((aggr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 470, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((aggr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 470, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((aggr ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 470, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 470, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((aggr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 470, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 470, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) |
471 | /* Initializing a member of an anonymous union. */ |
472 | return build_anon_member_initialization (member, init, vec); |
473 | else |
474 | /* We're initializing a vtable pointer in a base. Leave it as |
475 | COMPONENT_REF so we remember the path to get to the vfield. */ |
476 | gcc_assert (TREE_TYPE (member) == vtbl_ptr_type_node)((void)(!(((contains_struct_check ((member), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 476, __FUNCTION__))->typed.type) == cp_global_trees[CPTI_VTBL_PTR_TYPE ]) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 476, __FUNCTION__), 0 : 0)); |
477 | } |
478 | |
479 | /* Value-initialization can produce multiple initializers for the |
480 | same field; use the last one. */ |
481 | if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member) |
482 | (*vec)->last().value = init; |
483 | else |
484 | CONSTRUCTOR_APPEND_ELT (*vec, member, init)do { constructor_elt _ce___ = {member, init}; vec_safe_push ( (*vec), _ce___); } while (0); |
485 | return true; |
486 | } |
487 | |
488 | /* Subroutine of check_constexpr_ctor_body_1 and constexpr_fn_retval. |
489 | In C++11 mode checks that the TYPE_DECLs in the BIND_EXPR_VARS of a |
490 | BIND_EXPR conform to 7.1.5/3/4 on typedef and alias declarations. */ |
491 | |
492 | static bool |
493 | check_constexpr_bind_expr_vars (tree t) |
494 | { |
495 | gcc_assert (TREE_CODE (t) == BIND_EXPR)((void)(!(((enum tree_code) (t)->base.code) == BIND_EXPR) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 495, __FUNCTION__), 0 : 0)); |
496 | |
497 | for (tree var = BIND_EXPR_VARS (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 497, __FUNCTION__, (BIND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 497, __FUNCTION__)))))); var; var = DECL_CHAIN (var)(((contains_struct_check (((contains_struct_check ((var), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 497, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 497, __FUNCTION__))->common.chain))) |
498 | if (TREE_CODE (var)((enum tree_code) (var)->base.code) == TYPE_DECL |
499 | && DECL_IMPLICIT_TYPEDEF_P (var)(((enum tree_code) (var)->base.code) == TYPE_DECL && ((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 499, __FUNCTION__))->decl_common.lang_flag_2)) |
500 | && !LAMBDA_TYPE_P (TREE_TYPE (var))(((enum tree_code) (((contains_struct_check ((var), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && ((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name) && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name))) && ((tree_check ((((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name) && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name))->base.code))] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check ((((contains_struct_check ((var), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__))->type_common.name)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 500, __FUNCTION__, (IDENTIFIER_NODE)))->base.protected_flag ))) |
501 | return false; |
502 | return true; |
503 | } |
504 | |
505 | /* Subroutine of check_constexpr_ctor_body. */ |
506 | |
507 | static bool |
508 | check_constexpr_ctor_body_1 (tree last, tree list) |
509 | { |
510 | switch (TREE_CODE (list)((enum tree_code) (list)->base.code)) |
511 | { |
512 | case DECL_EXPR: |
513 | if (TREE_CODE (DECL_EXPR_DECL (list))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((tree_check ((list), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 513, __FUNCTION__, (DECL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 513, __FUNCTION__))))))->base.code) == USING_DECL |
514 | || TREE_CODE (DECL_EXPR_DECL (list))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((tree_check ((list), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 514, __FUNCTION__, (DECL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 514, __FUNCTION__))))))->base.code) == TYPE_DECL) |
515 | return true; |
516 | return false; |
517 | |
518 | case CLEANUP_POINT_EXPR: |
519 | return check_constexpr_ctor_body (last, TREE_OPERAND (list, 0)(*((const_cast<tree*> (tree_operand_check ((list), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 519, __FUNCTION__))))), |
520 | /*complain=*/false); |
521 | |
522 | case BIND_EXPR: |
523 | if (!check_constexpr_bind_expr_vars (list) |
524 | || !check_constexpr_ctor_body (last, BIND_EXPR_BODY (list)((*((const_cast<tree*> (tree_operand_check (((tree_check ((list), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 524, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 524, __FUNCTION__)))))), |
525 | /*complain=*/false)) |
526 | return false; |
527 | return true; |
528 | |
529 | case USING_STMT: |
530 | case STATIC_ASSERT: |
531 | case DEBUG_BEGIN_STMT: |
532 | return true; |
533 | |
534 | default: |
535 | return false; |
536 | } |
537 | } |
538 | |
539 | /* Make sure that there are no statements after LAST in the constructor |
540 | body represented by LIST. */ |
541 | |
542 | bool |
543 | check_constexpr_ctor_body (tree last, tree list, bool complain) |
544 | { |
545 | /* C++14 doesn't require a constexpr ctor to have an empty body. */ |
546 | if (cxx_dialect >= cxx14) |
547 | return true; |
548 | |
549 | bool ok = true; |
550 | if (TREE_CODE (list)((enum tree_code) (list)->base.code) == STATEMENT_LIST) |
551 | { |
552 | tree_stmt_iterator i = tsi_last (list); |
553 | for (; !tsi_end_p (i); tsi_prev (&i)) |
554 | { |
555 | tree t = tsi_stmt (i); |
556 | if (t == last) |
557 | break; |
558 | if (!check_constexpr_ctor_body_1 (last, t)) |
559 | { |
560 | ok = false; |
561 | break; |
562 | } |
563 | } |
564 | } |
565 | else if (list != last |
566 | && !check_constexpr_ctor_body_1 (last, list)) |
567 | ok = false; |
568 | if (!ok) |
569 | { |
570 | if (complain) |
571 | error ("%<constexpr%> constructor does not have empty body"); |
572 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 572, __FUNCTION__, (TEMPLATE_DECL))))))))->result : current_function_decl )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 572, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 572, __FUNCTION__))->decl_common.lang_flag_8) = false; |
573 | } |
574 | return ok; |
575 | } |
576 | |
577 | /* V is a vector of constructor elements built up for the base and member |
578 | initializers of a constructor for TYPE. They need to be in increasing |
579 | offset order, which they might not be yet if TYPE has a primary base |
580 | which is not first in the base-clause or a vptr and at least one base |
581 | all of which are non-primary. */ |
582 | |
583 | static vec<constructor_elt, va_gc> * |
584 | sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v) |
585 | { |
586 | tree pri = CLASSTYPE_PRIMARY_BINFO (type)((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 586, __FUNCTION__))->type_with_lang_specific.lang_specific ))->primary_base); |
587 | tree field_type; |
588 | unsigned i; |
589 | constructor_elt *ce; |
590 | |
591 | if (pri) |
592 | field_type = BINFO_TYPE (pri)((contains_struct_check (((tree_check ((pri), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 592, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 592, __FUNCTION__))->typed.type); |
593 | else if (TYPE_CONTAINS_VPTR_P (type)((((tree_not_check2 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 593, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) || ((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 593, __FUNCTION__))->type_with_lang_specific.lang_specific ))->vbases))) |
594 | field_type = vtbl_ptr_type_nodecp_global_trees[CPTI_VTBL_PTR_TYPE]; |
595 | else |
596 | return v; |
597 | |
598 | /* Find the element for the primary base or vptr and move it to the |
599 | beginning of the vec. */ |
600 | for (i = 0; vec_safe_iterate (v, i, &ce); ++i) |
601 | if (TREE_TYPE (ce->index)((contains_struct_check ((ce->index), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 601, __FUNCTION__))->typed.type) == field_type) |
602 | break; |
603 | |
604 | if (i > 0 && i < vec_safe_length (v)) |
605 | { |
606 | vec<constructor_elt, va_gc> &vref = *v; |
607 | constructor_elt elt = vref[i]; |
608 | for (; i > 0; --i) |
609 | vref[i] = vref[i-1]; |
610 | vref[0] = elt; |
611 | } |
612 | |
613 | return v; |
614 | } |
615 | |
616 | /* Build compile-time evalable representations of member-initializer list |
617 | for a constexpr constructor. */ |
618 | |
619 | static tree |
620 | build_constexpr_constructor_member_initializers (tree type, tree body) |
621 | { |
622 | vec<constructor_elt, va_gc> *vec = NULL__null; |
623 | bool ok = true; |
624 | while (true) |
625 | switch (TREE_CODE (body)((enum tree_code) (body)->base.code)) |
626 | { |
627 | case MUST_NOT_THROW_EXPR: |
628 | case EH_SPEC_BLOCK: |
629 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 629, __FUNCTION__))))); |
630 | break; |
631 | |
632 | case STATEMENT_LIST: |
633 | for (tree stmt : tsi_range (body)) |
634 | { |
635 | body = stmt; |
636 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == BIND_EXPR) |
637 | break; |
638 | } |
639 | break; |
640 | |
641 | case BIND_EXPR: |
642 | body = BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 642, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 642, __FUNCTION__)))))); |
643 | goto found; |
644 | |
645 | default: |
646 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 646, __FUNCTION__)); |
647 | } |
648 | found: |
649 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == TRY_BLOCK) |
650 | { |
651 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 651, __FUNCTION__))))); |
652 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == BIND_EXPR) |
653 | body = BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 653, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 653, __FUNCTION__)))))); |
654 | } |
655 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == CLEANUP_POINT_EXPR) |
656 | { |
657 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 657, __FUNCTION__))))); |
658 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == EXPR_STMT) |
659 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 659, __FUNCTION__))))); |
660 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == INIT_EXPR |
661 | && (same_type_ignoring_top_level_qualifiers_p |
662 | (TREE_TYPE (TREE_OPERAND (body, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 662, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 662, __FUNCTION__))->typed.type), |
663 | current_class_typescope_chain->class_type))) |
664 | { |
665 | /* Trivial copy. */ |
666 | return TREE_OPERAND (body, 1)(*((const_cast<tree*> (tree_operand_check ((body), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 666, __FUNCTION__))))); |
667 | } |
668 | ok = build_data_member_initialization (body, &vec); |
669 | } |
670 | else if (TREE_CODE (body)((enum tree_code) (body)->base.code) == STATEMENT_LIST) |
671 | { |
672 | for (tree stmt : tsi_range (body)) |
673 | { |
674 | ok = build_data_member_initialization (stmt, &vec); |
675 | if (!ok) |
676 | break; |
677 | } |
678 | } |
679 | else if (EXPR_P (body)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (body)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (body)->base.code))]) <= tcc_expression)) |
680 | ok = build_data_member_initialization (body, &vec); |
681 | else |
682 | gcc_assert (errorcount > 0)((void)(!((global_dc)->diagnostic_count[(int) (DK_ERROR)] > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 682, __FUNCTION__), 0 : 0)); |
683 | if (ok) |
684 | { |
685 | if (vec_safe_length (vec) > 0) |
686 | { |
687 | /* In a delegating constructor, return the target. */ |
688 | constructor_elt *ce = &(*vec)[0]; |
689 | if (ce->index == current_class_ptr(*((cfun + 0) && ((cfun + 0)->language) ? &((cfun + 0)->language)->x_current_class_ptr : &scope_chain ->x_current_class_ptr))) |
690 | { |
691 | body = ce->value; |
692 | vec_free (vec); |
693 | return body; |
694 | } |
695 | } |
696 | vec = sort_constexpr_mem_initializers (type, vec); |
697 | return build_constructor (type, vec); |
698 | } |
699 | else |
700 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
701 | } |
702 | |
703 | /* We have an expression tree T that represents a call, either CALL_EXPR |
704 | or AGGR_INIT_EXPR. If the call is lexically to a named function, |
705 | retrun the _DECL for that function. */ |
706 | |
707 | static tree |
708 | get_function_named_in_call (tree t) |
709 | { |
710 | tree fun = cp_get_callee (t); |
711 | if (fun && TREE_CODE (fun)((enum tree_code) (fun)->base.code) == ADDR_EXPR |
712 | && TREE_CODE (TREE_OPERAND (fun, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((fun), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 712, __FUNCTION__))))))->base.code) == FUNCTION_DECL) |
713 | fun = TREE_OPERAND (fun, 0)(*((const_cast<tree*> (tree_operand_check ((fun), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 713, __FUNCTION__))))); |
714 | return fun; |
715 | } |
716 | |
717 | /* Subroutine of check_constexpr_fundef. BODY is the body of a function |
718 | declared to be constexpr, or a sub-statement thereof. Returns the |
719 | return value if suitable, error_mark_node for a statement not allowed in |
720 | a constexpr function, or NULL_TREE if no return value was found. */ |
721 | |
722 | tree |
723 | constexpr_fn_retval (tree body) |
724 | { |
725 | switch (TREE_CODE (body)((enum tree_code) (body)->base.code)) |
726 | { |
727 | case STATEMENT_LIST: |
728 | { |
729 | tree expr = NULL_TREE(tree) __null; |
730 | for (tree stmt : tsi_range (body)) |
731 | { |
732 | tree s = constexpr_fn_retval (stmt); |
733 | if (s == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
734 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
735 | else if (s == NULL_TREE(tree) __null) |
736 | /* Keep iterating. */; |
737 | else if (expr) |
738 | /* Multiple return statements. */ |
739 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
740 | else |
741 | expr = s; |
742 | } |
743 | return expr; |
744 | } |
745 | |
746 | case RETURN_EXPR: |
747 | return break_out_target_exprs (TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 747, __FUNCTION__)))))); |
748 | |
749 | case DECL_EXPR: |
750 | { |
751 | tree decl = DECL_EXPR_DECL (body)(*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 751, __FUNCTION__, (DECL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 751, __FUNCTION__))))); |
752 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == USING_DECL |
753 | /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */ |
754 | || DECL_ARTIFICIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 754, __FUNCTION__))->decl_common.artificial_flag)) |
755 | return NULL_TREE(tree) __null; |
756 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
757 | } |
758 | |
759 | case CLEANUP_POINT_EXPR: |
760 | return constexpr_fn_retval (TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 760, __FUNCTION__)))))); |
761 | |
762 | case BIND_EXPR: |
763 | if (!check_constexpr_bind_expr_vars (body)) |
764 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
765 | return constexpr_fn_retval (BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 765, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 765, __FUNCTION__))))))); |
766 | |
767 | case USING_STMT: |
768 | case DEBUG_BEGIN_STMT: |
769 | return NULL_TREE(tree) __null; |
770 | |
771 | case CALL_EXPR: |
772 | { |
773 | tree fun = get_function_named_in_call (body); |
774 | if (fun != NULL_TREE(tree) __null |
775 | && fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE)) |
776 | return NULL_TREE(tree) __null; |
777 | } |
778 | /* Fallthru. */ |
779 | |
780 | default: |
781 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
782 | } |
783 | } |
784 | |
785 | /* Subroutine of check_constexpr_fundef. BODY is the DECL_SAVED_TREE of |
786 | FUN; do the necessary transformations to turn it into a single expression |
787 | that we can store in the hash table. */ |
788 | |
789 | static tree |
790 | massage_constexpr_body (tree fun, tree body) |
791 | { |
792 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 792, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 792, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
793 | body = build_constexpr_constructor_member_initializers |
794 | (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 794, __FUNCTION__))->decl_minimal.context), body); |
795 | else if (cxx_dialect < cxx14) |
796 | { |
797 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == EH_SPEC_BLOCK) |
798 | body = EH_SPEC_STMTS (body)(*((const_cast<tree*> (tree_operand_check (((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 798, __FUNCTION__, (EH_SPEC_BLOCK)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 798, __FUNCTION__))))); |
799 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) == MUST_NOT_THROW_EXPR) |
800 | body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 800, __FUNCTION__))))); |
801 | body = constexpr_fn_retval (body); |
802 | } |
803 | return body; |
804 | } |
805 | |
806 | /* CTYPE is a type constructed from BODY. Return true if some |
807 | bases/fields are uninitialized, and complain if COMPLAIN. */ |
808 | |
809 | static bool |
810 | cx_check_missing_mem_inits (tree ctype, tree body, bool complain) |
811 | { |
812 | /* We allow uninitialized bases/fields in C++20. */ |
813 | if (cxx_dialect >= cxx20) |
814 | return false; |
815 | |
816 | unsigned nelts = 0; |
817 | |
818 | if (body) |
819 | { |
820 | if (TREE_CODE (body)((enum tree_code) (body)->base.code) != CONSTRUCTOR) |
821 | return false; |
822 | nelts = CONSTRUCTOR_NELTS (body)(vec_safe_length (((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 822, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))); |
823 | } |
824 | tree field = TYPE_FIELDS (ctype)((tree_check3 ((ctype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 824, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); |
825 | |
826 | if (TREE_CODE (ctype)((enum tree_code) (ctype)->base.code) == UNION_TYPE) |
827 | { |
828 | if (nelts == 0 && next_aggregate_field (field)) |
829 | { |
830 | if (complain) |
831 | error ("%<constexpr%> constructor for union %qT must " |
832 | "initialize exactly one non-static data member", ctype); |
833 | return true; |
834 | } |
835 | return false; |
836 | } |
837 | |
838 | /* Iterate over the CONSTRUCTOR, checking any missing fields don't |
839 | need an explicit initialization. */ |
840 | bool bad = false; |
841 | for (unsigned i = 0; i <= nelts; ++i) |
842 | { |
843 | tree index = NULL_TREE(tree) __null; |
844 | if (i < nelts) |
845 | { |
846 | index = CONSTRUCTOR_ELT (body, i)(&(*((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 846, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[i ])->index; |
847 | /* Skip base and vtable inits. */ |
848 | if (TREE_CODE (index)((enum tree_code) (index)->base.code) != FIELD_DECL |
849 | || DECL_ARTIFICIAL (index)((contains_struct_check ((index), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 849, __FUNCTION__))->decl_common.artificial_flag)) |
850 | continue; |
851 | } |
852 | |
853 | for (; field != index; field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 853, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 853, __FUNCTION__))->common.chain))) |
854 | { |
855 | tree ftype; |
856 | if (TREE_CODE (field)((enum tree_code) (field)->base.code) != FIELD_DECL) |
857 | continue; |
858 | if (DECL_UNNAMED_BIT_FIELD (field)((((contains_struct_check (((tree_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 858, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 858, __FUNCTION__))->decl_common.lang_flag_4) == 1) && !((contains_struct_check ((field), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 858, __FUNCTION__))->decl_minimal.name))) |
859 | continue; |
860 | if (DECL_ARTIFICIAL (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 860, __FUNCTION__))->decl_common.artificial_flag)) |
861 | continue; |
862 | if (ANON_AGGR_TYPE_P (TREE_TYPE (field))((((((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 862, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 862, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((field ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 862, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 862, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((field), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 862, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 862, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) |
863 | { |
864 | /* Recurse to check the anonymous aggregate member. */ |
865 | bad |= cx_check_missing_mem_inits |
866 | (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 866, __FUNCTION__))->typed.type), NULL_TREE(tree) __null, complain); |
867 | if (bad && !complain) |
868 | return true; |
869 | continue; |
870 | } |
871 | ftype = TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 871, __FUNCTION__))->typed.type); |
872 | if (!ftype || !TYPE_P (ftype)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ftype)->base.code))] == tcc_type) || !COMPLETE_TYPE_P (ftype)(((tree_class_check ((ftype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 872, __FUNCTION__))->type_common.size) != (tree) __null)) |
873 | /* A flexible array can't be intialized here, so don't complain |
874 | that it isn't. */ |
875 | continue; |
876 | if (is_empty_field (field)) |
877 | /* An empty field doesn't need an initializer. */ |
878 | continue; |
879 | ftype = strip_array_types (ftype); |
880 | if (type_has_constexpr_default_constructor (ftype)) |
881 | { |
882 | /* It's OK to skip a member with a trivial constexpr ctor. |
883 | A constexpr ctor that isn't trivial should have been |
884 | added in by now. */ |
885 | gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype)((void)(!(!((((tree_class_check ((ftype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 885, __FUNCTION__))->type_with_lang_specific.lang_specific ))->has_complex_dflt) || (global_dc)->diagnostic_count[ (int) (DK_ERROR)] != 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 886, __FUNCTION__), 0 : 0)) |
886 | || errorcount != 0)((void)(!(!((((tree_class_check ((ftype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 885, __FUNCTION__))->type_with_lang_specific.lang_specific ))->has_complex_dflt) || (global_dc)->diagnostic_count[ (int) (DK_ERROR)] != 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 886, __FUNCTION__), 0 : 0)); |
887 | continue; |
888 | } |
889 | if (!complain) |
890 | return true; |
891 | auto_diagnostic_group d; |
892 | error ("member %qD must be initialized by mem-initializer " |
893 | "in %<constexpr%> constructor", field); |
894 | inform (DECL_SOURCE_LOCATION (field)((contains_struct_check ((field), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 894, __FUNCTION__))->decl_minimal.locus), "declared here"); |
895 | bad = true; |
896 | } |
897 | if (field == NULL_TREE(tree) __null) |
898 | break; |
899 | |
900 | if (ANON_AGGR_TYPE_P (TREE_TYPE (index))((((((enum tree_code) (((contains_struct_check ((index), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 900, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((index), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 900, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((index ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 900, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 900, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((((contains_struct_check ((index), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 900, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 900, __FUNCTION__))->type_with_lang_specific.lang_specific ))->anon_aggr)) |
901 | { |
902 | /* Check the anonymous aggregate initializer is valid. */ |
903 | bad |= cx_check_missing_mem_inits |
904 | (TREE_TYPE (index)((contains_struct_check ((index), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 904, __FUNCTION__))->typed.type), CONSTRUCTOR_ELT (body, i)(&(*((tree_check ((body), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 904, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[i ])->value, complain); |
905 | if (bad && !complain) |
906 | return true; |
907 | } |
908 | field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 908, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 908, __FUNCTION__))->common.chain)); |
909 | } |
910 | |
911 | return bad; |
912 | } |
913 | |
914 | /* We are processing the definition of the constexpr function FUN. |
915 | Check that its body fulfills the apropriate requirements and |
916 | enter it in the constexpr function definition table. */ |
917 | |
918 | void |
919 | maybe_save_constexpr_fundef (tree fun) |
920 | { |
921 | if (processing_template_declscope_chain->x_processing_template_decl |
922 | || cp_function_chain((cfun + 0)->language)->invalid_constexpr |
923 | || (DECL_CLONED_FUNCTION_P (fun)(((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__))->decl_minimal.name) && ((!(( tree_not_check2 (((tree_check ((((contains_struct_check ((fun ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & ((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1)) && !((((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_CTOR_IDENTIFIER]) || (((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_DTOR_IDENTIFIER]))) && !DECL_DELETING_DESTRUCTOR_P (fun)(((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 923, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_DELETING_DTOR_IDENTIFIER]))) |
924 | return; |
925 | |
926 | /* With -fimplicit-constexpr, try to make inlines constexpr. We'll |
927 | actually set DECL_DECLARED_CONSTEXPR_P below if the checks pass. */ |
928 | bool implicit = false; |
929 | if (flag_implicit_constexprglobal_options.x_flag_implicit_constexpr) |
930 | { |
931 | if (DECL_DELETING_DESTRUCTOR_P (fun)(((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 931, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_DELETING_DTOR_IDENTIFIER]) |
932 | && decl_implicit_constexpr_p (DECL_CLONED_FUNCTION (fun)(((contains_struct_check (((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 932, __FUNCTION__, (FUNCTION_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 932, __FUNCTION__))->decl_common.lang_specific)->u.fn .u5.cloned_function))) |
933 | /* Don't inherit implicit constexpr from the non-deleting |
934 | destructor. */ |
935 | 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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 935, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 935, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 935, __FUNCTION__))->decl_common.lang_flag_8) = false; |
936 | |
937 | 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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 937, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 937, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 937, __FUNCTION__))->decl_common.lang_flag_8) |
938 | && DECL_DECLARED_INLINE_P (fun)((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 938, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag ) |
939 | && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 939, __FUNCTION__))->decl_common.attributes))) |
940 | implicit = true; |
941 | } |
942 | |
943 | 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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 943, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 943, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 943, __FUNCTION__))->decl_common.lang_flag_8) && !implicit) |
944 | return; |
945 | |
946 | bool complain = !DECL_GENERATED_P (fun)((((((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__)), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__))->decl_common.lang_specific) ->u.min .template_info) && !(((contains_struct_check ((fun), ( TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 946, __FUNCTION__); <->u.fn; })->defaulted_p)) && !implicit; |
947 | |
948 | if (!is_valid_constexpr_fn (fun, complain)) |
949 | return; |
950 | |
951 | tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun)((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 951, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree )); |
952 | if (massaged == NULL_TREE(tree) __null || massaged == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
953 | { |
954 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 954, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 954, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) && complain) |
955 | error ("body of %<constexpr%> function %qD not a return-statement", |
956 | fun); |
957 | return; |
958 | } |
959 | |
960 | bool potential = potential_rvalue_constant_expression (massaged); |
961 | if (!potential && complain) |
962 | require_potential_rvalue_constant_expression_fncheck (massaged); |
963 | |
964 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 964, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 964, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) && potential |
965 | && !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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 965, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 965, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 965, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 965, __FUNCTION__, (TEMPLATE_DECL))))))))->result)->base .code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 965, __FUNCTION__); <->u.fn; })->defaulted_p)) |
966 | { |
967 | if (cx_check_missing_mem_inits (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 967, __FUNCTION__))->decl_minimal.context), |
968 | massaged, complain)) |
969 | potential = false; |
970 | else if (cxx_dialect > cxx11) |
971 | { |
972 | /* What we got from massage_constexpr_body is pretty much just the |
973 | ctor-initializer, also check the body. */ |
974 | massaged = DECL_SAVED_TREE (fun)((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 974, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ); |
975 | potential = potential_rvalue_constant_expression (massaged); |
976 | if (!potential && complain) |
977 | require_potential_rvalue_constant_expression_fncheck (massaged); |
978 | } |
979 | } |
980 | |
981 | if (!potential && complain |
982 | /* If -Wno-invalid-constexpr was specified, we haven't complained |
983 | about non-constant expressions yet. Register the function and |
984 | complain in explain_invalid_constexpr_fn if the function is |
985 | called. */ |
986 | && warn_invalid_constexprglobal_options.x_warn_invalid_constexpr != 0) |
987 | return; |
988 | |
989 | if (implicit) |
990 | { |
991 | if (potential) |
992 | { |
993 | 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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 993, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 993, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 993, __FUNCTION__))->decl_common.lang_flag_8) = true; |
994 | DECL_LANG_SPECIFIC (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 994, __FUNCTION__))->decl_common.lang_specific)->u.fn.implicit_constexpr = true; |
995 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 995, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun) ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 995, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
996 | TYPE_HAS_CONSTEXPR_CTOR (DECL_CONTEXT (fun))((((tree_class_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 996, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 996, __FUNCTION__))->type_with_lang_specific.lang_specific ))->has_constexpr_ctor) = true; |
997 | } |
998 | else |
999 | /* Don't bother keeping the pre-generic body of unsuitable functions |
1000 | not explicitly declared constexpr. */ |
1001 | return; |
1002 | } |
1003 | |
1004 | constexpr_fundef entry = {fun, NULL_TREE(tree) __null, NULL_TREE(tree) __null, NULL_TREE(tree) __null}; |
1005 | bool clear_ctx = false; |
1006 | if (DECL_RESULT (fun)((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1006, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ) && DECL_CONTEXT (DECL_RESULT (fun))((contains_struct_check ((((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1006, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1006, __FUNCTION__))->decl_minimal.context) == NULL_TREE(tree) __null) |
1007 | { |
1008 | clear_ctx = true; |
1009 | DECL_CONTEXT (DECL_RESULT (fun))((contains_struct_check ((((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1009, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1009, __FUNCTION__))->decl_minimal.context) = fun; |
1010 | } |
1011 | tree saved_fn = current_function_decl; |
1012 | current_function_decl = fun; |
1013 | entry.body = copy_fn (entry.decl, entry.parms, entry.result); |
1014 | current_function_decl = saved_fn; |
1015 | if (clear_ctx) |
1016 | DECL_CONTEXT (DECL_RESULT (entry.decl))((contains_struct_check ((((tree_check ((entry.decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1016, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result )), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1016, __FUNCTION__))->decl_minimal.context) = NULL_TREE(tree) __null; |
1017 | if (!potential) |
1018 | /* For a template instantiation, we want to remember the pre-generic body |
1019 | for explain_invalid_constexpr_fn, but do tell cxx_eval_call_expression |
1020 | that it doesn't need to bother trying to expand the function. */ |
1021 | entry.result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
1022 | |
1023 | register_constexpr_fundef (entry); |
1024 | } |
1025 | |
1026 | /* BODY is a validated and massaged definition of a constexpr |
1027 | function. Register it in the hash table. */ |
1028 | |
1029 | void |
1030 | register_constexpr_fundef (const constexpr_fundef &value) |
1031 | { |
1032 | /* Create the constexpr function table if necessary. */ |
1033 | if (constexpr_fundef_table == NULL__null) |
1034 | constexpr_fundef_table |
1035 | = hash_table<constexpr_fundef_hasher>::create_ggc (101); |
1036 | |
1037 | constexpr_fundef **slot = constexpr_fundef_table->find_slot |
1038 | (const_cast<constexpr_fundef *> (&value), INSERT); |
1039 | |
1040 | gcc_assert (*slot == NULL)((void)(!(*slot == __null) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1040, __FUNCTION__), 0 : 0)); |
1041 | *slot = ggc_alloc<constexpr_fundef> (); |
1042 | **slot = value; |
1043 | } |
1044 | |
1045 | /* FUN is a non-constexpr (or, with -Wno-invalid-constexpr, a constexpr |
1046 | function called in a context that requires a constant expression). |
1047 | If it comes from a constexpr template, explain why the instantiation |
1048 | isn't constexpr. Otherwise, explain why the function cannot be used |
1049 | in a constexpr context. */ |
1050 | |
1051 | void |
1052 | explain_invalid_constexpr_fn (tree fun) |
1053 | { |
1054 | static hash_set<tree> *diagnosed; |
1055 | tree body; |
1056 | /* In C++23, a function marked 'constexpr' may not actually be a constant |
1057 | expression. We haven't diagnosed the problem yet: -Winvalid-constexpr |
1058 | wasn't enabled. The function was called, so diagnose why it cannot be |
1059 | used in a constant expression. */ |
1060 | if (warn_invalid_constexprglobal_options.x_warn_invalid_constexpr == 0 && 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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1060, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1060, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1060, __FUNCTION__))->decl_common.lang_flag_8)) |
1061 | /* Go on. */; |
1062 | /* Only diagnose defaulted functions, lambdas, or instantiations. */ |
1063 | else 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1063, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1063, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1063, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1063, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1063, __FUNCTION__); <->u.fn; })->defaulted_p) |
1064 | && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))(((enum tree_code) ((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name) && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name))->base.code)) ] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name))) && ((tree_check ((((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name) && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name))->base.code)) ] == tcc_declaration) ? ((contains_struct_check ((((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.name) : ((tree_class_check ((((tree_class_check (((!(! (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL])), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__))->type_common.name)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1064, __FUNCTION__, (IDENTIFIER_NODE)))->base.protected_flag )) |
1065 | && !is_instantiation_of_constexpr (fun)) |
1066 | { |
1067 | inform (DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1067, __FUNCTION__))->decl_minimal.locus), "%qD declared here", fun); |
1068 | return; |
1069 | } |
1070 | if (diagnosed == NULL__null) |
1071 | diagnosed = new hash_set<tree>; |
1072 | if (diagnosed->add (fun)) |
1073 | /* Already explained. */ |
1074 | return; |
1075 | |
1076 | iloc_sentinel ils = input_location; |
1077 | if (!lambda_static_thunk_p (fun)) |
1078 | { |
1079 | /* Diagnostics should completely ignore the static thunk, so leave |
1080 | input_location set to our caller's location. */ |
1081 | input_location = DECL_SOURCE_LOCATION (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1081, __FUNCTION__))->decl_minimal.locus); |
1082 | inform (input_location, |
1083 | "%qD is not usable as a %<constexpr%> function because:", fun); |
1084 | } |
1085 | /* First check the declaration. */ |
1086 | if (is_valid_constexpr_fn (fun, true)) |
1087 | { |
1088 | /* Then if it's OK, the body. */ |
1089 | 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) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1089, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1089, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1089, __FUNCTION__))->decl_common.lang_flag_8) |
1090 | && 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1090, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1090, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1090, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1090, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1090, __FUNCTION__); <->u.fn; })->defaulted_p)) |
1091 | explain_implicit_non_constexpr (fun); |
1092 | else |
1093 | { |
1094 | if (constexpr_fundef *fd = retrieve_constexpr_fundef (fun)) |
1095 | body = fd->body; |
1096 | else |
1097 | body = DECL_SAVED_TREE (fun)((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1097, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ); |
1098 | body = massage_constexpr_body (fun, body); |
1099 | require_potential_rvalue_constant_expression (body); |
1100 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1100, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1100, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
1101 | cx_check_missing_mem_inits (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1101, __FUNCTION__))->decl_minimal.context), body, true); |
1102 | } |
1103 | } |
1104 | } |
1105 | |
1106 | /* Objects of this type represent calls to constexpr functions |
1107 | along with the bindings of parameters to their arguments, for |
1108 | the purpose of compile time evaluation. */ |
1109 | |
1110 | struct GTY((for_user)) constexpr_call { |
1111 | /* Description of the constexpr function definition. */ |
1112 | constexpr_fundef *fundef; |
1113 | /* Parameter bindings environment. A TREE_VEC of arguments. */ |
1114 | tree bindings; |
1115 | /* Result of the call. |
1116 | NULL means the call is being evaluated. |
1117 | error_mark_node means that the evaluation was erroneous; |
1118 | otherwise, the actuall value of the call. */ |
1119 | tree result; |
1120 | /* The hash of this call; we remember it here to avoid having to |
1121 | recalculate it when expanding the hash table. */ |
1122 | hashval_t hash; |
1123 | /* The value of constexpr_ctx::manifestly_const_eval. */ |
1124 | enum mce_value manifestly_const_eval; |
1125 | }; |
1126 | |
1127 | struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call> |
1128 | { |
1129 | static hashval_t hash (constexpr_call *); |
1130 | static bool equal (constexpr_call *, constexpr_call *); |
1131 | }; |
1132 | |
1133 | enum constexpr_switch_state { |
1134 | /* Used when processing a switch for the first time by cxx_eval_switch_expr |
1135 | and default: label for that switch has not been seen yet. */ |
1136 | css_default_not_seen, |
1137 | /* Used when processing a switch for the first time by cxx_eval_switch_expr |
1138 | and default: label for that switch has been seen already. */ |
1139 | css_default_seen, |
1140 | /* Used when processing a switch for the second time by |
1141 | cxx_eval_switch_expr, where default: label should match. */ |
1142 | css_default_processing |
1143 | }; |
1144 | |
1145 | /* The constexpr expansion context part which needs one instance per |
1146 | cxx_eval_outermost_constant_expr invocation. VALUES is a map of values of |
1147 | variables initialized within the expression. */ |
1148 | |
1149 | class constexpr_global_ctx { |
1150 | /* Values for any temporaries or local variables within the |
1151 | constant-expression. */ |
1152 | hash_map<tree,tree> values; |
1153 | public: |
1154 | /* Number of cxx_eval_constant_expression calls (except skipped ones, |
1155 | on simple constants or location wrappers) encountered during current |
1156 | cxx_eval_outermost_constant_expr call. */ |
1157 | HOST_WIDE_INTlong constexpr_ops_count; |
1158 | /* Heap VAR_DECLs created during the evaluation of the outermost constant |
1159 | expression. */ |
1160 | auto_vec<tree, 16> heap_vars; |
1161 | /* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */ |
1162 | vec<tree> *cleanups; |
1163 | /* If non-null, only allow modification of existing values of the variables |
1164 | in this set. Set by modifiable_tracker, below. */ |
1165 | hash_set<tree> *modifiable; |
1166 | /* Number of heap VAR_DECL deallocations. */ |
1167 | unsigned heap_dealloc_count; |
1168 | /* Constructor. */ |
1169 | constexpr_global_ctx () |
1170 | : constexpr_ops_count (0), cleanups (NULL__null), modifiable (nullptr), |
1171 | heap_dealloc_count (0) {} |
1172 | |
1173 | tree get_value (tree t) |
1174 | { |
1175 | if (tree *p = values.get (t)) |
1176 | return *p; |
1177 | return NULL_TREE(tree) __null; |
1178 | } |
1179 | tree *get_value_ptr (tree t) |
1180 | { |
1181 | if (modifiable && !modifiable->contains (t)) |
1182 | return nullptr; |
1183 | return values.get (t); |
1184 | } |
1185 | void put_value (tree t, tree v) |
1186 | { |
1187 | bool already_in_map = values.put (t, v); |
1188 | if (!already_in_map && modifiable) |
1189 | modifiable->add (t); |
1190 | } |
1191 | void remove_value (tree t) { values.remove (t); } |
1192 | }; |
1193 | |
1194 | /* Helper class for constexpr_global_ctx. In some cases we want to avoid |
1195 | side-effects from evaluation of a particular subexpression of a |
1196 | constant-expression. In such cases we use modifiable_tracker to prevent |
1197 | modification of variables created outside of that subexpression. |
1198 | |
1199 | ??? We could change the hash_set to a hash_map, allow and track external |
1200 | modifications, and roll them back in the destructor. It's not clear to me |
1201 | that this would be worthwhile. */ |
1202 | |
1203 | class modifiable_tracker |
1204 | { |
1205 | hash_set<tree> set; |
1206 | constexpr_global_ctx *global; |
1207 | public: |
1208 | modifiable_tracker (constexpr_global_ctx *g): global(g) |
1209 | { |
1210 | global->modifiable = &set; |
1211 | } |
1212 | ~modifiable_tracker () |
1213 | { |
1214 | for (tree t: set) |
1215 | global->remove_value (t); |
1216 | global->modifiable = nullptr; |
1217 | } |
1218 | }; |
1219 | |
1220 | /* The constexpr expansion context. CALL is the current function |
1221 | expansion, CTOR is the current aggregate initializer, OBJECT is the |
1222 | object being initialized by CTOR, either a VAR_DECL or a _REF. */ |
1223 | |
1224 | struct constexpr_ctx { |
1225 | /* The part of the context that needs to be unique to the whole |
1226 | cxx_eval_outermost_constant_expr invocation. */ |
1227 | constexpr_global_ctx *global; |
1228 | /* The innermost call we're evaluating. */ |
1229 | constexpr_call *call; |
1230 | /* SAVE_EXPRs and TARGET_EXPR_SLOT vars of TARGET_EXPRs that we've seen |
1231 | within the current LOOP_EXPR. NULL if we aren't inside a loop. */ |
1232 | vec<tree> *save_exprs; |
1233 | /* The CONSTRUCTOR we're currently building up for an aggregate |
1234 | initializer. */ |
1235 | tree ctor; |
1236 | /* The object we're building the CONSTRUCTOR for. */ |
1237 | tree object; |
1238 | /* If inside SWITCH_EXPR. */ |
1239 | constexpr_switch_state *css_state; |
1240 | /* The aggregate initialization context inside which this one is nested. This |
1241 | is used by lookup_placeholder to resolve PLACEHOLDER_EXPRs. */ |
1242 | const constexpr_ctx *parent; |
1243 | |
1244 | /* Whether we should error on a non-constant expression or fail quietly. |
1245 | This flag needs to be here, but some of the others could move to global |
1246 | if they get larger than a word. */ |
1247 | bool quiet; |
1248 | /* Whether we are strictly conforming to constant expression rules or |
1249 | trying harder to get a constant value. */ |
1250 | bool strict; |
1251 | /* Whether __builtin_is_constant_evaluated () should be true. */ |
1252 | mce_value manifestly_const_eval; |
1253 | }; |
1254 | |
1255 | /* This internal flag controls whether we should avoid doing anything during |
1256 | constexpr evaluation that would cause extra DECL_UID generation, such as |
1257 | template instantiation and function body copying. */ |
1258 | |
1259 | static bool uid_sensitive_constexpr_evaluation_value; |
1260 | |
1261 | /* An internal counter that keeps track of the number of times |
1262 | uid_sensitive_constexpr_evaluation_p returned true. */ |
1263 | |
1264 | static unsigned uid_sensitive_constexpr_evaluation_true_counter; |
1265 | |
1266 | /* The accessor for uid_sensitive_constexpr_evaluation_value which also |
1267 | increments the corresponding counter. */ |
1268 | |
1269 | static bool |
1270 | uid_sensitive_constexpr_evaluation_p () |
1271 | { |
1272 | if (uid_sensitive_constexpr_evaluation_value) |
1273 | { |
1274 | ++uid_sensitive_constexpr_evaluation_true_counter; |
1275 | return true; |
1276 | } |
1277 | else |
1278 | return false; |
1279 | } |
1280 | |
1281 | /* The default constructor for uid_sensitive_constexpr_evaluation_sentinel |
1282 | enables the internal flag for uid_sensitive_constexpr_evaluation_p |
1283 | during the lifetime of the sentinel object. Upon its destruction, the |
1284 | previous value of uid_sensitive_constexpr_evaluation_p is restored. */ |
1285 | |
1286 | uid_sensitive_constexpr_evaluation_sentinel |
1287 | ::uid_sensitive_constexpr_evaluation_sentinel () |
1288 | : ovr (uid_sensitive_constexpr_evaluation_value, true) |
1289 | { |
1290 | } |
1291 | |
1292 | /* The default constructor for uid_sensitive_constexpr_evaluation_checker |
1293 | records the current number of times that uid_sensitive_constexpr_evaluation_p |
1294 | has been called and returned true. */ |
1295 | |
1296 | uid_sensitive_constexpr_evaluation_checker |
1297 | ::uid_sensitive_constexpr_evaluation_checker () |
1298 | : saved_counter (uid_sensitive_constexpr_evaluation_true_counter) |
1299 | { |
1300 | } |
1301 | |
1302 | /* Returns true iff uid_sensitive_constexpr_evaluation_p is true, and |
1303 | some constexpr evaluation was restricted due to u_s_c_e_p being called |
1304 | and returning true during the lifetime of this checker object. */ |
1305 | |
1306 | bool |
1307 | uid_sensitive_constexpr_evaluation_checker::evaluation_restricted_p () const |
1308 | { |
1309 | return (uid_sensitive_constexpr_evaluation_value |
1310 | && saved_counter != uid_sensitive_constexpr_evaluation_true_counter); |
1311 | } |
1312 | |
1313 | |
1314 | /* A table of all constexpr calls that have been evaluated by the |
1315 | compiler in this translation unit. */ |
1316 | |
1317 | static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table; |
1318 | |
1319 | /* Compute a hash value for a constexpr call representation. */ |
1320 | |
1321 | inline hashval_t |
1322 | constexpr_call_hasher::hash (constexpr_call *info) |
1323 | { |
1324 | return info->hash; |
1325 | } |
1326 | |
1327 | /* Return true if the objects pointed to by P and Q represent calls |
1328 | to the same constexpr function with the same arguments. |
1329 | Otherwise, return false. */ |
1330 | |
1331 | bool |
1332 | constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs) |
1333 | { |
1334 | if (lhs == rhs) |
1335 | return true; |
1336 | if (lhs->hash != rhs->hash) |
1337 | return false; |
1338 | if (lhs->manifestly_const_eval != rhs->manifestly_const_eval) |
1339 | return false; |
1340 | if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef)) |
1341 | return false; |
1342 | return cp_tree_equal (lhs->bindings, rhs->bindings); |
1343 | } |
1344 | |
1345 | /* Initialize the constexpr call table, if needed. */ |
1346 | |
1347 | static void |
1348 | maybe_initialize_constexpr_call_table (void) |
1349 | { |
1350 | if (constexpr_call_table == NULL__null) |
1351 | constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101); |
1352 | } |
1353 | |
1354 | /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when |
1355 | a function happens to get called recursively, we unshare the callee |
1356 | function's body and evaluate this unshared copy instead of evaluating the |
1357 | original body. |
1358 | |
1359 | FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function |
1360 | copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map |
1361 | that's keyed off of the original FUNCTION_DECL and whose value is a |
1362 | TREE_LIST of this function's unused copies awaiting reuse. |
1363 | |
1364 | This is not GC-deletable to avoid GC affecting UID generation. */ |
1365 | |
1366 | static GTY(()) decl_tree_map *fundef_copies_table; |
1367 | |
1368 | /* Reuse a copy or create a new unshared copy of the function FUN. |
1369 | Return this copy. We use a TREE_LIST whose PURPOSE is body, VALUE |
1370 | is parms, TYPE is result. */ |
1371 | |
1372 | static tree |
1373 | get_fundef_copy (constexpr_fundef *fundef) |
1374 | { |
1375 | tree copy; |
1376 | bool existed; |
1377 | tree *slot = &(hash_map_safe_get_or_insert<hm_ggc> |
1378 | (fundef_copies_table, fundef->decl, &existed, 127)); |
1379 | |
1380 | if (!existed) |
1381 | { |
1382 | /* There is no cached function available, or in use. We can use |
1383 | the function directly. That the slot is now created records |
1384 | that this function is now in use. */ |
1385 | copy = build_tree_list (fundef->body, fundef->parms); |
1386 | TREE_TYPE (copy)((contains_struct_check ((copy), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1386, __FUNCTION__))->typed.type) = fundef->result; |
1387 | } |
1388 | else if (*slot == NULL_TREE(tree) __null) |
1389 | { |
1390 | if (uid_sensitive_constexpr_evaluation_p ()) |
1391 | return NULL_TREE(tree) __null; |
1392 | |
1393 | /* We've already used the function itself, so make a copy. */ |
1394 | copy = build_tree_list (NULL__null, NULL__null); |
1395 | tree saved_body = DECL_SAVED_TREE (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1395, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ); |
1396 | tree saved_parms = DECL_ARGUMENTS (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1396, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ); |
1397 | tree saved_result = DECL_RESULT (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1397, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ); |
1398 | tree saved_fn = current_function_decl; |
1399 | DECL_SAVED_TREE (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1399, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ) = fundef->body; |
1400 | DECL_ARGUMENTS (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1400, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ) = fundef->parms; |
1401 | DECL_RESULT (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1401, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ) = fundef->result; |
1402 | current_function_decl = fundef->decl; |
1403 | TREE_PURPOSE (copy)((tree_check ((copy), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1403, __FUNCTION__, (TREE_LIST)))->list.purpose) = copy_fn (fundef->decl, TREE_VALUE (copy)((tree_check ((copy), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1403, __FUNCTION__, (TREE_LIST)))->list.value), |
1404 | TREE_TYPE (copy)((contains_struct_check ((copy), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1404, __FUNCTION__))->typed.type)); |
1405 | current_function_decl = saved_fn; |
1406 | DECL_RESULT (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1406, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ) = saved_result; |
1407 | DECL_ARGUMENTS (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1407, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ) = saved_parms; |
1408 | DECL_SAVED_TREE (fundef->decl)((tree_check ((fundef->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1408, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ) = saved_body; |
1409 | } |
1410 | else |
1411 | { |
1412 | /* We have a cached function available. */ |
1413 | copy = *slot; |
1414 | *slot = TREE_CHAIN (copy)((contains_struct_check ((copy), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1414, __FUNCTION__))->common.chain); |
1415 | } |
1416 | |
1417 | return copy; |
1418 | } |
1419 | |
1420 | /* Save the copy COPY of function FUN for later reuse by |
1421 | get_fundef_copy(). By construction, there will always be an entry |
1422 | to find. */ |
1423 | |
1424 | static void |
1425 | save_fundef_copy (tree fun, tree copy) |
1426 | { |
1427 | tree *slot = fundef_copies_table->get (fun); |
1428 | TREE_CHAIN (copy)((contains_struct_check ((copy), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1428, __FUNCTION__))->common.chain) = *slot; |
1429 | *slot = copy; |
1430 | } |
1431 | |
1432 | /* Whether our evaluation wants a prvalue (e.g. CONSTRUCTOR or _CST), |
1433 | a glvalue (e.g. VAR_DECL or _REF), or nothing. */ |
1434 | |
1435 | enum value_cat { |
1436 | vc_prvalue = 0, |
1437 | vc_glvalue = 1, |
1438 | vc_discard = 2 |
1439 | }; |
1440 | |
1441 | static tree cxx_eval_constant_expression (const constexpr_ctx *, tree, |
1442 | value_cat, bool *, bool *, tree * = NULL__null); |
1443 | static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree, |
1444 | bool * = NULL__null); |
1445 | static tree find_heap_var_refs (tree *, int *, void *); |
1446 | |
1447 | /* Attempt to evaluate T which represents a call to a builtin function. |
1448 | We assume here that all builtin functions evaluate to scalar types |
1449 | represented by _CST nodes. */ |
1450 | |
1451 | static tree |
1452 | cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, |
1453 | value_cat lval, |
1454 | bool *non_constant_p, bool *overflow_p) |
1455 | { |
1456 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1456, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1456, __FUNCTION__)))) - 3); |
1457 | tree *args = (tree *) alloca (nargs * sizeof (tree))__builtin_alloca(nargs * sizeof (tree)); |
1458 | tree new_call; |
1459 | int i; |
1460 | |
1461 | /* Don't fold __builtin_constant_p within a constexpr function. */ |
1462 | bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun)(((enum tree_code) (fun)->base.code) == FUNCTION_DECL && ((built_in_class) (tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1462, __FUNCTION__, (FUNCTION_DECL)))->function_decl.built_in_class ) == BUILT_IN_NORMAL && DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P ); |
1463 | |
1464 | /* If we aren't requiring a constant expression, defer __builtin_constant_p |
1465 | in a constexpr function until we have values for the parameters. */ |
1466 | if (bi_const_p |
1467 | && ctx->manifestly_const_eval != mce_true |
1468 | && current_function_decl |
1469 | && 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1469, __FUNCTION__, (TEMPLATE_DECL))))))))->result : current_function_decl )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1469, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1469, __FUNCTION__))->decl_common.lang_flag_8)) |
1470 | { |
1471 | *non_constant_p = true; |
1472 | return t; |
1473 | } |
1474 | |
1475 | /* For __builtin_is_constant_evaluated, defer it if not |
1476 | ctx->manifestly_const_eval (as sometimes we try to constant evaluate |
1477 | without manifestly_const_eval even expressions or parts thereof which |
1478 | will later be manifestly const_eval evaluated), otherwise fold it to |
1479 | true. */ |
1480 | if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED, |
1481 | BUILT_IN_FRONTEND)) |
1482 | { |
1483 | if (ctx->manifestly_const_eval == mce_unknown) |
1484 | { |
1485 | *non_constant_p = true; |
1486 | return t; |
1487 | } |
1488 | return constant_boolean_node (ctx->manifestly_const_eval == mce_true, |
1489 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]); |
1490 | } |
1491 | |
1492 | if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND)) |
1493 | { |
1494 | temp_override<tree> ovr (current_function_decl); |
1495 | if (ctx->call && ctx->call->fundef) |
1496 | current_function_decl = ctx->call->fundef->decl; |
1497 | return fold_builtin_source_location (t); |
1498 | } |
1499 | |
1500 | int strops = 0; |
1501 | int strret = 0; |
1502 | if (fndecl_built_in_p (fun, BUILT_IN_NORMAL)) |
1503 | switch (DECL_FUNCTION_CODE (fun)) |
1504 | { |
1505 | case BUILT_IN_STRLEN: |
1506 | case BUILT_IN_STRNLEN: |
1507 | strops = 1; |
1508 | break; |
1509 | case BUILT_IN_MEMCHR: |
1510 | case BUILT_IN_STRCHR: |
1511 | case BUILT_IN_STRRCHR: |
1512 | strops = 1; |
1513 | strret = 1; |
1514 | break; |
1515 | case BUILT_IN_MEMCMP: |
1516 | case BUILT_IN_STRCMP: |
1517 | strops = 2; |
1518 | break; |
1519 | case BUILT_IN_STRSTR: |
1520 | strops = 2; |
1521 | strret = 1; |
1522 | break; |
1523 | case BUILT_IN_ASAN_POINTER_COMPARE: |
1524 | case BUILT_IN_ASAN_POINTER_SUBTRACT: |
1525 | /* These builtins shall be ignored during constant expression |
1526 | evaluation. */ |
1527 | return void_nodeglobal_trees[TI_VOID]; |
1528 | case BUILT_IN_UNREACHABLE: |
1529 | case BUILT_IN_TRAP: |
1530 | if (!*non_constant_p && !ctx->quiet) |
1531 | { |
1532 | /* Do not allow__builtin_unreachable in constexpr function. |
1533 | The __builtin_unreachable call with BUILTINS_LOCATION |
1534 | comes from cp_maybe_instrument_return. */ |
1535 | if (EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)) == BUILTINS_LOCATION((location_t) 1)) |
1536 | error ("%<constexpr%> call flows off the end of the function"); |
1537 | else |
1538 | error ("%q+E is not a constant expression", t); |
1539 | } |
1540 | *non_constant_p = true; |
1541 | return t; |
1542 | default: |
1543 | break; |
1544 | } |
1545 | |
1546 | /* Be permissive for arguments to built-ins; __builtin_constant_p should |
1547 | return constant false for a non-constant argument. */ |
1548 | constexpr_ctx new_ctx = *ctx; |
1549 | new_ctx.quiet = true; |
1550 | for (i = 0; i < nargs; ++i) |
1551 | { |
1552 | tree arg = CALL_EXPR_ARG (t, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1552, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1552, __FUNCTION__))))); |
1553 | tree oarg = arg; |
1554 | |
1555 | /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since |
1556 | expand_builtin doesn't know how to look in the values table. */ |
1557 | bool strop = i < strops; |
1558 | if (strop) |
1559 | { |
1560 | STRIP_NOPS (arg)(arg) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((arg))))); |
1561 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == ADDR_EXPR) |
1562 | arg = TREE_OPERAND (arg, 0)(*((const_cast<tree*> (tree_operand_check ((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1562, __FUNCTION__))))); |
1563 | else |
1564 | strop = false; |
1565 | } |
1566 | |
1567 | /* If builtin_valid_in_constant_expr_p is true, |
1568 | potential_constant_expression_1 has not recursed into the arguments |
1569 | of the builtin, verify it here. */ |
1570 | if (!builtin_valid_in_constant_expr_p (fun) |
1571 | || potential_constant_expression (arg)) |
1572 | { |
1573 | bool dummy1 = false, dummy2 = false; |
1574 | arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue, |
1575 | &dummy1, &dummy2); |
1576 | } |
1577 | |
1578 | if (bi_const_p) |
1579 | /* For __builtin_constant_p, fold all expressions with constant values |
1580 | even if they aren't C++ constant-expressions. */ |
1581 | arg = cp_fold_rvalue (arg); |
1582 | else if (strop) |
1583 | { |
1584 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == CONSTRUCTOR) |
1585 | arg = braced_lists_to_strings (TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1585, __FUNCTION__))->typed.type), arg); |
1586 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == STRING_CST) |
1587 | arg = build_address (arg); |
1588 | else |
1589 | arg = oarg; |
1590 | } |
1591 | |
1592 | args[i] = arg; |
1593 | } |
1594 | |
1595 | bool save_ffbcp = force_folding_builtin_constant_p; |
1596 | force_folding_builtin_constant_p |= ctx->manifestly_const_eval == mce_true; |
1597 | tree save_cur_fn = current_function_decl; |
1598 | /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */ |
1599 | if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION) |
1600 | && ctx->call |
1601 | && ctx->call->fundef) |
1602 | current_function_decl = ctx->call->fundef->decl; |
1603 | if (fndecl_built_in_p (fun, |
1604 | CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS, |
1605 | BUILT_IN_FRONTEND)) |
1606 | { |
1607 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); |
1608 | if (nargs >= 1) |
1609 | VERIFY_CONSTANT (args[0])do { if (verify_constant ((args[0]), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
1610 | new_call |
1611 | = fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs, |
1612 | args); |
1613 | } |
1614 | else if (fndecl_built_in_p (fun, |
1615 | CP_BUILT_IN_IS_CORRESPONDING_MEMBER, |
1616 | BUILT_IN_FRONTEND)) |
1617 | { |
1618 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); |
1619 | if (nargs >= 2) |
1620 | { |
1621 | VERIFY_CONSTANT (args[0])do { if (verify_constant ((args[0]), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
1622 | VERIFY_CONSTANT (args[1])do { if (verify_constant ((args[1]), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
1623 | } |
1624 | new_call = fold_builtin_is_corresponding_member (loc, nargs, args); |
1625 | } |
1626 | else |
1627 | new_call = fold_builtin_call_array (EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1627, __FUNCTION__))->typed.type), |
1628 | CALL_EXPR_FN (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1628, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1628, __FUNCTION__))))), nargs, args); |
1629 | current_function_decl = save_cur_fn; |
1630 | force_folding_builtin_constant_p = save_ffbcp; |
1631 | if (new_call == NULL__null) |
1632 | { |
1633 | if (!*non_constant_p && !ctx->quiet) |
1634 | { |
1635 | new_call = build_call_array_loc (EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1635, __FUNCTION__))->typed.type), |
1636 | CALL_EXPR_FN (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1636, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1636, __FUNCTION__))))), nargs, args); |
1637 | error ("%q+E is not a constant expression", new_call); |
1638 | } |
1639 | *non_constant_p = true; |
1640 | return t; |
1641 | } |
1642 | |
1643 | if (!potential_constant_expression (new_call)) |
1644 | { |
1645 | if (!*non_constant_p && !ctx->quiet) |
1646 | error ("%q+E is not a constant expression", new_call); |
1647 | *non_constant_p = true; |
1648 | return t; |
1649 | } |
1650 | |
1651 | if (strret) |
1652 | { |
1653 | /* memchr returns a pointer into the first argument, but we replaced the |
1654 | argument above with a STRING_CST; put it back it now. */ |
1655 | tree op = CALL_EXPR_ARG (t, strret-1)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1655, __FUNCTION__, (CALL_EXPR)))), ((strret-1) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1655, __FUNCTION__))))); |
1656 | STRIP_NOPS (new_call)(new_call) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((new_call))))); |
1657 | if (TREE_CODE (new_call)((enum tree_code) (new_call)->base.code) == POINTER_PLUS_EXPR) |
1658 | TREE_OPERAND (new_call, 0)(*((const_cast<tree*> (tree_operand_check ((new_call), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1658, __FUNCTION__))))) = op; |
1659 | else if (TREE_CODE (new_call)((enum tree_code) (new_call)->base.code) == ADDR_EXPR) |
1660 | new_call = op; |
1661 | } |
1662 | |
1663 | return cxx_eval_constant_expression (&new_ctx, new_call, lval, |
1664 | non_constant_p, overflow_p); |
1665 | } |
1666 | |
1667 | /* TEMP is the constant value of a temporary object of type TYPE. Adjust |
1668 | the type of the value to match. */ |
1669 | |
1670 | static tree |
1671 | adjust_temp_type (tree type, tree temp) |
1672 | { |
1673 | if (same_type_p (TREE_TYPE (temp), type)comptypes ((((contains_struct_check ((temp), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1673, __FUNCTION__))->typed.type)), (type), 0)) |
1674 | return temp; |
1675 | /* Avoid wrapping an aggregate value in a NOP_EXPR. */ |
1676 | if (TREE_CODE (temp)((enum tree_code) (temp)->base.code) == CONSTRUCTOR) |
1677 | { |
1678 | /* build_constructor wouldn't retain various CONSTRUCTOR flags. */ |
1679 | tree t = copy_node (temp); |
1680 | TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1680, __FUNCTION__))->typed.type) = type; |
1681 | return t; |
1682 | } |
1683 | if (TREE_CODE (temp)((enum tree_code) (temp)->base.code) == EMPTY_CLASS_EXPR) |
1684 | return build0 (EMPTY_CLASS_EXPR, type); |
1685 | gcc_assert (scalarish_type_p (type))((void)(!(scalarish_type_p (type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1685, __FUNCTION__), 0 : 0)); |
1686 | /* Now we know we're dealing with a scalar, and a prvalue of non-class |
1687 | type is cv-unqualified. */ |
1688 | return cp_fold_convert (cv_unqualified (type), temp); |
1689 | } |
1690 | |
1691 | /* If T is a CONSTRUCTOR, return an unshared copy of T and any |
1692 | sub-CONSTRUCTORs. Otherwise return T. |
1693 | |
1694 | We use this whenever we initialize an object as a whole, whether it's a |
1695 | parameter, a local variable, or a subobject, so that subsequent |
1696 | modifications don't affect other places where it was used. */ |
1697 | |
1698 | tree |
1699 | unshare_constructor (tree t MEM_STAT_DECL) |
1700 | { |
1701 | if (!t || TREE_CODE (t)((enum tree_code) (t)->base.code) != CONSTRUCTOR) |
1702 | return t; |
1703 | auto_vec <tree*, 4> ptrs; |
1704 | ptrs.safe_push (&t); |
1705 | while (!ptrs.is_empty ()) |
1706 | { |
1707 | tree *p = ptrs.pop (); |
1708 | tree n = copy_node (*p PASS_MEM_STAT); |
1709 | CONSTRUCTOR_ELTS (n)((tree_check ((n), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1709, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts) = vec_safe_copy (CONSTRUCTOR_ELTS (*p)((tree_check ((*p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1709, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts) PASS_MEM_STAT); |
1710 | *p = n; |
1711 | vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (n)((tree_check ((n), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1711, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
1712 | constructor_elt *ce; |
1713 | for (HOST_WIDE_INTlong i = 0; vec_safe_iterate (v, i, &ce); ++i) |
1714 | if (ce->value && TREE_CODE (ce->value)((enum tree_code) (ce->value)->base.code) == CONSTRUCTOR) |
1715 | ptrs.safe_push (&ce->value); |
1716 | } |
1717 | return t; |
1718 | } |
1719 | |
1720 | /* If T is a CONSTRUCTOR, ggc_free T and any sub-CONSTRUCTORs. */ |
1721 | |
1722 | static void |
1723 | free_constructor (tree t) |
1724 | { |
1725 | if (!t || TREE_CODE (t)((enum tree_code) (t)->base.code) != CONSTRUCTOR) |
1726 | return; |
1727 | releasing_vec ctors; |
1728 | vec_safe_push (ctors, t); |
1729 | while (!ctors->is_empty ()) |
1730 | { |
1731 | tree c = ctors->pop (); |
1732 | if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (c)((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1732, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)) |
1733 | { |
1734 | constructor_elt *ce; |
1735 | for (HOST_WIDE_INTlong i = 0; vec_safe_iterate (elts, i, &ce); ++i) |
1736 | if (TREE_CODE (ce->value)((enum tree_code) (ce->value)->base.code) == CONSTRUCTOR) |
1737 | vec_safe_push (ctors, ce->value); |
1738 | ggc_free (elts); |
1739 | } |
1740 | ggc_free (c); |
1741 | } |
1742 | } |
1743 | |
1744 | /* Helper function of cxx_bind_parameters_in_call. Return non-NULL |
1745 | if *TP is address of a static variable (or part of it) currently being |
1746 | constructed or of a heap artificial variable. */ |
1747 | |
1748 | static tree |
1749 | addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data) |
1750 | { |
1751 | if (TREE_CODE (*tp)((enum tree_code) (*tp)->base.code) == ADDR_EXPR) |
1752 | if (tree var = get_base_address (TREE_OPERAND (*tp, 0)(*((const_cast<tree*> (tree_operand_check ((*tp), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1752, __FUNCTION__))))))) |
1753 | if (VAR_P (var)(((enum tree_code) (var)->base.code) == VAR_DECL) && TREE_STATIC (var)((var)->base.static_flag)) |
1754 | { |
1755 | if (DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1755, __FUNCTION__))->decl_minimal.name) == heap_uninit_identifiercp_global_trees[CPTI_HEAP_UNINIT_IDENTIFIER] |
1756 | || DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1756, __FUNCTION__))->decl_minimal.name) == heap_identifiercp_global_trees[CPTI_HEAP_IDENTIFIER] |
1757 | || DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1757, __FUNCTION__))->decl_minimal.name) == heap_vec_uninit_identifiercp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER] |
1758 | || DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1758, __FUNCTION__))->decl_minimal.name) == heap_vec_identifiercp_global_trees[CPTI_HEAP_VEC_IDENTIFIER]) |
1759 | return var; |
1760 | |
1761 | constexpr_global_ctx *global = (constexpr_global_ctx *) data; |
1762 | if (global->get_value (var)) |
1763 | return var; |
1764 | } |
1765 | if (TYPE_P (*tp)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*tp)->base.code))] == tcc_type)) |
1766 | *walk_subtrees = false; |
1767 | return NULL_TREE(tree) __null; |
1768 | } |
1769 | |
1770 | /* Subroutine of cxx_eval_call_expression. |
1771 | We are processing a call expression (either CALL_EXPR or |
1772 | AGGR_INIT_EXPR) in the context of CTX. Evaluate |
1773 | all arguments and bind their values to correspondings |
1774 | parameters, making up the NEW_CALL context. */ |
1775 | |
1776 | static tree |
1777 | cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, |
1778 | bool *non_constant_p, bool *overflow_p, |
1779 | bool *non_constant_args) |
1780 | { |
1781 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1781, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1781, __FUNCTION__)))) - 3); |
1782 | tree parms = DECL_ARGUMENTS (fun)((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1782, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ); |
1783 | int i; |
1784 | /* We don't record ellipsis args below. */ |
1785 | int nparms = list_length (parms); |
1786 | int nbinds = nargs < nparms ? nargs : nparms; |
1787 | tree binds = make_tree_vec (nbinds); |
1788 | for (i = 0; i < nargs; ++i) |
1789 | { |
1790 | tree x, arg; |
1791 | tree type = parms ? TREE_TYPE (parms)((contains_struct_check ((parms), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1791, __FUNCTION__))->typed.type) : void_type_nodeglobal_trees[TI_VOID_TYPE]; |
1792 | if (parms && DECL_BY_REFERENCE (parms)((tree_check3 ((parms), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1792, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) )->decl_common.decl_by_reference_flag)) |
1793 | type = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1793, __FUNCTION__))->typed.type); |
1794 | x = get_nth_callarg (t, i); |
1795 | /* For member function, the first argument is a pointer to the implied |
1796 | object. For a constructor, it might still be a dummy object, in |
1797 | which case we get the real argument from ctx. */ |
1798 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1798, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1798, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) |
1799 | && is_dummy_object (x)) |
1800 | { |
1801 | x = ctx->object; |
1802 | x = build_address (x); |
1803 | } |
1804 | if (TREE_ADDRESSABLE (type)((type)->base.addressable_flag)) |
1805 | /* Undo convert_for_arg_passing work here. */ |
1806 | x = convert_from_reference (x); |
1807 | /* Normally we would strip a TARGET_EXPR in an initialization context |
1808 | such as this, but here we do the elision differently: we keep the |
1809 | TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */ |
1810 | arg = cxx_eval_constant_expression (ctx, x, vc_prvalue, |
1811 | non_constant_p, overflow_p); |
1812 | /* Don't VERIFY_CONSTANT here. */ |
1813 | if (*non_constant_p && ctx->quiet) |
1814 | break; |
1815 | /* Just discard ellipsis args after checking their constantitude. */ |
1816 | if (!parms) |
1817 | continue; |
1818 | |
1819 | if (!*non_constant_p) |
1820 | { |
1821 | /* Make sure the binding has the same type as the parm. But |
1822 | only for constant args. */ |
1823 | if (!TYPE_REF_P (type)(((enum tree_code) (type)->base.code) == REFERENCE_TYPE)) |
1824 | arg = adjust_temp_type (type, arg); |
1825 | if (!TREE_CONSTANT (arg)((non_type_check ((arg), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1825, __FUNCTION__))->base.constant_flag)) |
1826 | *non_constant_args = true; |
1827 | else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1827, __FUNCTION__))->type_common.lang_flag_4))) |
1828 | /* The destructor needs to see any modifications the callee makes |
1829 | to the argument. */ |
1830 | *non_constant_args = true; |
1831 | /* If arg is or contains address of a heap artificial variable or |
1832 | of a static variable being constructed, avoid caching the |
1833 | function call, as those variables might be modified by the |
1834 | function, or might be modified by the callers in between |
1835 | the cached function and just read by the function. */ |
1836 | else if (!*non_constant_args |
1837 | && cp_walk_tree (&arg, addr_of_non_const_var, ctx->global,walk_tree_1 (&arg, addr_of_non_const_var, ctx->global, __null, cp_walk_subtrees) |
1838 | NULL)walk_tree_1 (&arg, addr_of_non_const_var, ctx->global, __null, cp_walk_subtrees)) |
1839 | *non_constant_args = true; |
1840 | |
1841 | /* For virtual calls, adjust the this argument, so that it is |
1842 | the object on which the method is called, rather than |
1843 | one of its bases. */ |
1844 | if (i == 0 && DECL_VIRTUAL_P (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1844, __FUNCTION__))->decl_common.virtual_flag)) |
1845 | { |
1846 | tree addr = arg; |
1847 | STRIP_NOPS (addr)(addr) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((addr))))); |
1848 | if (TREE_CODE (addr)((enum tree_code) (addr)->base.code) == ADDR_EXPR) |
1849 | { |
1850 | tree obj = TREE_OPERAND (addr, 0)(*((const_cast<tree*> (tree_operand_check ((addr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1850, __FUNCTION__))))); |
1851 | while (TREE_CODE (obj)((enum tree_code) (obj)->base.code) == COMPONENT_REF |
1852 | && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1))((contains_struct_check (((tree_check (((*((const_cast<tree *> (tree_operand_check ((obj), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1852, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1852, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1852, __FUNCTION__))->decl_common.lang_flag_6) |
1853 | && !same_type_ignoring_top_level_qualifiers_p |
1854 | (TREE_TYPE (obj)((contains_struct_check ((obj), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1854, __FUNCTION__))->typed.type), DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1854, __FUNCTION__))->decl_minimal.context))) |
1855 | obj = TREE_OPERAND (obj, 0)(*((const_cast<tree*> (tree_operand_check ((obj), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1855, __FUNCTION__))))); |
1856 | if (obj != TREE_OPERAND (addr, 0)(*((const_cast<tree*> (tree_operand_check ((addr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1856, __FUNCTION__)))))) |
1857 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1858, __FUNCTION__))->typed.type)) |
1858 | TREE_TYPE (arg))build_fold_addr_expr_with_type_loc (((location_t) 0), (obj), ( (contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1858, __FUNCTION__))->typed.type)); |
1859 | } |
1860 | } |
1861 | TREE_VEC_ELT (binds, i)(*((const_cast<tree *> (tree_vec_elt_check ((binds), (i ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1861, __FUNCTION__))))) = arg; |
1862 | } |
1863 | parms = TREE_CHAIN (parms)((contains_struct_check ((parms), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1863, __FUNCTION__))->common.chain); |
1864 | } |
1865 | |
1866 | return binds; |
1867 | } |
1868 | |
1869 | /* Variables and functions to manage constexpr call expansion context. |
1870 | These do not need to be marked for PCH or GC. */ |
1871 | |
1872 | /* FIXME remember and print actual constant arguments. */ |
1873 | static vec<tree> call_stack; |
1874 | static int call_stack_tick; |
1875 | static int last_cx_error_tick; |
1876 | |
1877 | static int |
1878 | push_cx_call_context (tree call) |
1879 | { |
1880 | ++call_stack_tick; |
1881 | if (!EXPR_HAS_LOCATION (call)(((IS_ADHOC_LOC (((((call)) && ((tree_code_type_tmpl < 0>::tree_code_type[(int) (((enum tree_code) ((call))->base .code))]) >= tcc_reference && (tree_code_type_tmpl <0>::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_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((call))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((call))->base.code))]) <= tcc_expression )) ? (call)->exp.locus : ((location_t) 0))) : (((((call)) && ((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((call))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) ((call))->base.code))]) <= tcc_expression)) ? (call)->exp.locus : ((location_t) 0)))) != ((location_t ) 0))) |
1882 | SET_EXPR_LOCATION (call, input_location)(expr_check (((call)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1882, __FUNCTION__))->exp.locus = (input_location); |
1883 | call_stack.safe_push (call); |
1884 | int len = call_stack.length (); |
1885 | if (len > max_constexpr_depthglobal_options.x_max_constexpr_depth) |
1886 | return false; |
1887 | return len; |
1888 | } |
1889 | |
1890 | static void |
1891 | pop_cx_call_context (void) |
1892 | { |
1893 | ++call_stack_tick; |
1894 | call_stack.pop (); |
1895 | } |
1896 | |
1897 | vec<tree> |
1898 | cx_error_context (void) |
1899 | { |
1900 | vec<tree> r = vNULL; |
1901 | if (call_stack_tick != last_cx_error_tick |
1902 | && !call_stack.is_empty ()) |
1903 | r = call_stack; |
1904 | last_cx_error_tick = call_stack_tick; |
1905 | return r; |
1906 | } |
1907 | |
1908 | /* E is an operand of a failed assertion, fold it either with or without |
1909 | constexpr context. */ |
1910 | |
1911 | static tree |
1912 | fold_operand (tree e, const constexpr_ctx *ctx) |
1913 | { |
1914 | if (ctx) |
1915 | { |
1916 | bool new_non_constant_p = false, new_overflow_p = false; |
1917 | e = cxx_eval_constant_expression (ctx, e, vc_prvalue, |
1918 | &new_non_constant_p, |
1919 | &new_overflow_p); |
1920 | } |
1921 | else |
1922 | e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true); |
1923 | return e; |
1924 | } |
1925 | |
1926 | /* If we have a condition in conjunctive normal form (CNF), find the first |
1927 | failing clause. In other words, given an expression like |
1928 | |
1929 | true && true && false && true && false |
1930 | |
1931 | return the first 'false'. EXPR is the expression. */ |
1932 | |
1933 | static tree |
1934 | find_failing_clause_r (const constexpr_ctx *ctx, tree expr) |
1935 | { |
1936 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == TRUTH_ANDIF_EXPR) |
1937 | { |
1938 | /* First check the left side... */ |
1939 | tree e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1939, __FUNCTION__)))))); |
1940 | if (e == NULL_TREE(tree) __null) |
1941 | /* ...if we didn't find a false clause, check the right side. */ |
1942 | e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1942, __FUNCTION__)))))); |
1943 | return e; |
1944 | } |
1945 | tree e = contextual_conv_bool (expr, tf_none); |
1946 | e = fold_operand (e, ctx); |
1947 | if (integer_zerop (e)) |
1948 | /* This is the failing clause. */ |
1949 | return expr; |
1950 | return NULL_TREE(tree) __null; |
1951 | } |
1952 | |
1953 | /* Wrapper for find_failing_clause_r. */ |
1954 | |
1955 | tree |
1956 | find_failing_clause (const constexpr_ctx *ctx, tree expr) |
1957 | { |
1958 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == TRUTH_ANDIF_EXPR) |
1959 | if (tree e = find_failing_clause_r (ctx, expr)) |
1960 | expr = e; |
1961 | return expr; |
1962 | } |
1963 | |
1964 | /* Emit additional diagnostics for failing condition BAD. |
1965 | Used by finish_static_assert and IFN_ASSUME constexpr diagnostics. |
1966 | If SHOW_EXPR_P is true, print the condition (because it was |
1967 | instantiation-dependent). */ |
1968 | |
1969 | void |
1970 | diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p, |
1971 | const constexpr_ctx *ctx /* = nullptr */) |
1972 | { |
1973 | /* Nobody wants to see the artificial (bool) cast. */ |
1974 | bad = tree_strip_nop_conversions (bad); |
1975 | if (TREE_CODE (bad)((enum tree_code) (bad)->base.code) == CLEANUP_POINT_EXPR) |
1976 | bad = TREE_OPERAND (bad, 0)(*((const_cast<tree*> (tree_operand_check ((bad), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1976, __FUNCTION__))))); |
1977 | |
1978 | /* Actually explain the failure if this is a concept check or a |
1979 | requires-expression. */ |
1980 | if (concept_check_p (bad) || TREE_CODE (bad)((enum tree_code) (bad)->base.code) == REQUIRES_EXPR) |
1981 | diagnose_constraints (cloc, bad, NULL_TREE(tree) __null); |
1982 | else if (COMPARISON_CLASS_P (bad)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (bad)->base.code))] == tcc_comparison) |
1983 | && ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))((((enum tree_code) (((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((bad), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((bad), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) || ((enum tree_code) (((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((bad), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE || ((enum tree_code) (((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((bad), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1983, __FUNCTION__))->typed.type))->base.code) == COMPLEX_TYPE )) |
1984 | { |
1985 | tree op0 = fold_operand (TREE_OPERAND (bad, 0)(*((const_cast<tree*> (tree_operand_check ((bad), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1985, __FUNCTION__))))), ctx); |
1986 | tree op1 = fold_operand (TREE_OPERAND (bad, 1)(*((const_cast<tree*> (tree_operand_check ((bad), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 1986, __FUNCTION__))))), ctx); |
1987 | tree cond = build2 (TREE_CODE (bad)((enum tree_code) (bad)->base.code), boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], op0, op1); |
1988 | inform (cloc, "the comparison reduces to %qE", cond); |
1989 | } |
1990 | else if (show_expr_p) |
1991 | inform (cloc, "%qE evaluates to false", bad); |
1992 | } |
1993 | |
1994 | /* Process an assert/assume of ORIG_ARG. If it's not supposed to be evaluated, |
1995 | do it without changing the current evaluation state. If it evaluates to |
1996 | false, complain and return false; otherwise, return true. */ |
1997 | |
1998 | static bool |
1999 | cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg, |
2000 | location_t loc, bool evaluated, |
2001 | bool *non_constant_p, bool *overflow_p) |
2002 | { |
2003 | if (*non_constant_p) |
2004 | return true; |
2005 | |
2006 | tree eval; |
2007 | if (!evaluated) |
2008 | { |
2009 | if (!potential_rvalue_constant_expression (arg)) |
2010 | return true; |
2011 | |
2012 | constexpr_ctx new_ctx = *ctx; |
2013 | new_ctx.quiet = true; |
2014 | bool new_non_constant_p = false, new_overflow_p = false; |
2015 | /* Avoid modification of existing values. */ |
2016 | modifiable_tracker ms (new_ctx.global); |
2017 | eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue, |
2018 | &new_non_constant_p, |
2019 | &new_overflow_p); |
2020 | } |
2021 | else |
2022 | eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue, |
2023 | non_constant_p, |
2024 | overflow_p); |
2025 | if (!*non_constant_p && integer_zerop (eval)) |
2026 | { |
2027 | if (!ctx->quiet) |
2028 | { |
2029 | /* See if we can find which clause was failing |
2030 | (for logical AND). */ |
2031 | tree bad = find_failing_clause (ctx, arg); |
2032 | /* If not, or its location is unusable, fall back to the |
2033 | previous location. */ |
2034 | location_t cloc = cp_expr_loc_or_loc (bad, loc); |
2035 | |
2036 | /* Report the error. */ |
2037 | auto_diagnostic_group d; |
2038 | error_at (cloc, msg); |
2039 | diagnose_failing_condition (bad, cloc, true, ctx); |
2040 | return bad; |
2041 | } |
2042 | *non_constant_p = true; |
2043 | return false; |
2044 | } |
2045 | |
2046 | return true; |
2047 | } |
2048 | |
2049 | /* Evaluate a call T to a GCC internal function when possible and return |
2050 | the evaluated result or, under the control of CTX, give an error, set |
2051 | NON_CONSTANT_P, and return the unevaluated call T otherwise. */ |
2052 | |
2053 | static tree |
2054 | cxx_eval_internal_function (const constexpr_ctx *ctx, tree t, |
2055 | value_cat lval, |
2056 | bool *non_constant_p, bool *overflow_p) |
2057 | { |
2058 | enum tree_code opcode = ERROR_MARK; |
2059 | |
2060 | switch (CALL_EXPR_IFN (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2060, __FUNCTION__, (CALL_EXPR)))->base.u.ifn)) |
2061 | { |
2062 | case IFN_UBSAN_NULL: |
2063 | case IFN_UBSAN_BOUNDS: |
2064 | case IFN_UBSAN_VPTR: |
2065 | case IFN_FALLTHROUGH: |
2066 | return void_nodeglobal_trees[TI_VOID]; |
2067 | |
2068 | case IFN_ASSUME: |
2069 | if (!cxx_eval_assert (ctx, CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2069, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2069, __FUNCTION__))))), |
2070 | G_("failed %<assume%> attribute assumption")"failed %<assume%> attribute assumption", |
2071 | EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)), /*eval*/false, |
2072 | non_constant_p, overflow_p)) |
2073 | return t; |
2074 | return void_nodeglobal_trees[TI_VOID]; |
2075 | |
2076 | case IFN_ADD_OVERFLOW: |
2077 | opcode = PLUS_EXPR; |
2078 | break; |
2079 | case IFN_SUB_OVERFLOW: |
2080 | opcode = MINUS_EXPR; |
2081 | break; |
2082 | case IFN_MUL_OVERFLOW: |
2083 | opcode = MULT_EXPR; |
2084 | break; |
2085 | |
2086 | case IFN_LAUNDER: |
2087 | return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2087, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2087, __FUNCTION__))))), |
2088 | vc_prvalue, non_constant_p, |
2089 | overflow_p); |
2090 | |
2091 | case IFN_VEC_CONVERT: |
2092 | { |
2093 | tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2093, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2093, __FUNCTION__))))), |
2094 | vc_prvalue, non_constant_p, |
2095 | overflow_p); |
2096 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == VECTOR_CST) |
2097 | if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2097, __FUNCTION__))->typed.type), arg)) |
2098 | return r; |
2099 | } |
2100 | /* FALLTHRU */ |
2101 | |
2102 | default: |
2103 | if (!ctx->quiet) |
2104 | error_at (cp_expr_loc_or_input_loc (t), |
2105 | "call to internal function %qE", t); |
2106 | *non_constant_p = true; |
2107 | return t; |
2108 | } |
2109 | |
2110 | /* Evaluate constant arguments using OPCODE and return a complex |
2111 | number containing the result and the overflow bit. */ |
2112 | tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2112, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2112, __FUNCTION__))))), lval, |
2113 | non_constant_p, overflow_p); |
2114 | tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2114, __FUNCTION__, (CALL_EXPR)))), ((1) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2114, __FUNCTION__))))), lval, |
2115 | non_constant_p, overflow_p); |
2116 | |
2117 | if (TREE_CODE (arg0)((enum tree_code) (arg0)->base.code) == INTEGER_CST && TREE_CODE (arg1)((enum tree_code) (arg1)->base.code) == INTEGER_CST) |
2118 | { |
2119 | location_t loc = cp_expr_loc_or_input_loc (t); |
2120 | tree type = TREE_TYPE (TREE_TYPE (t))((contains_struct_check ((((contains_struct_check ((t), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2120, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2120, __FUNCTION__))->typed.type); |
2121 | tree result = fold_binary_loc (loc, opcode, type, |
2122 | fold_convert_loc (loc, type, arg0), |
2123 | fold_convert_loc (loc, type, arg1)); |
2124 | tree ovf |
2125 | = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1)); |
2126 | /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */ |
2127 | if (TREE_OVERFLOW (result)((tree_class_check ((result), (tcc_constant), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2127, __FUNCTION__))->base.public_flag)) |
2128 | TREE_OVERFLOW (result)((tree_class_check ((result), (tcc_constant), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2128, __FUNCTION__))->base.public_flag) = 0; |
2129 | |
2130 | return build_complex (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2130, __FUNCTION__))->typed.type), result, ovf); |
2131 | } |
2132 | |
2133 | *non_constant_p = true; |
2134 | return t; |
2135 | } |
2136 | |
2137 | /* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates. */ |
2138 | |
2139 | static void |
2140 | clear_no_implicit_zero (tree ctor) |
2141 | { |
2142 | if (CONSTRUCTOR_NO_CLEARING (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2142, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) |
2143 | { |
2144 | CONSTRUCTOR_NO_CLEARING (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2144, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = false; |
2145 | for (auto &e: CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2145, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)) |
2146 | if (TREE_CODE (e.value)((enum tree_code) (e.value)->base.code) == CONSTRUCTOR) |
2147 | clear_no_implicit_zero (e.value); |
2148 | } |
2149 | } |
2150 | |
2151 | /* Complain about a const object OBJ being modified in a constant expression. |
2152 | EXPR is the MODIFY_EXPR expression performing the modification. */ |
2153 | |
2154 | static void |
2155 | modifying_const_object_error (tree expr, tree obj) |
2156 | { |
2157 | location_t loc = cp_expr_loc_or_input_loc (expr); |
2158 | auto_diagnostic_group d; |
2159 | error_at (loc, "modifying a const object %qE is not allowed in " |
2160 | "a constant expression", TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2160, __FUNCTION__)))))); |
2161 | inform (location_of (obj), "originally declared %<const%> here"); |
2162 | } |
2163 | |
2164 | /* Return true if FNDECL is a replaceable global allocation function that |
2165 | should be useable during constant expression evaluation. */ |
2166 | |
2167 | static inline bool |
2168 | cxx_replaceable_global_alloc_fn (tree fndecl) |
2169 | { |
2170 | return (cxx_dialect >= cxx20 |
2171 | && IDENTIFIER_NEWDEL_OP_P (DECL_NAME (fndecl))(((((tree_not_check2 (((tree_check ((((contains_struct_check ( (fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & (!((tree_not_check2 (((tree_check ((((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2171, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) & OVL_OP_FLAG_ALLOC) |
2172 | && CP_DECL_CONTEXT (fndecl)(!(! (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2172, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2172, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2172, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]) == global_namespacecp_global_trees[CPTI_GLOBAL] |
2173 | && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)((((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2173, __FUNCTION__, (FUNCTION_DECL)))->function_decl.decl_type ) == OPERATOR_NEW) && ((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2173, __FUNCTION__, (FUNCTION_DECL)))->function_decl.replaceable_operator )) |
2174 | || DECL_IS_OPERATOR_DELETE_P (fndecl)(((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2174, __FUNCTION__, (FUNCTION_DECL)))->function_decl.decl_type ) == OPERATOR_DELETE))); |
2175 | } |
2176 | |
2177 | /* Return true if FNDECL is a placement new function that should be |
2178 | useable during constant expression evaluation of std::construct_at. */ |
2179 | |
2180 | static inline bool |
2181 | cxx_placement_new_fn (tree fndecl) |
2182 | { |
2183 | if (cxx_dialect >= cxx20 |
2184 | && IDENTIFIER_NEW_OP_P (DECL_NAME (fndecl))(((((tree_not_check2 (((tree_check ((((contains_struct_check ( (fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & (!((tree_not_check2 (((tree_check ((((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2184, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) & (OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE) ) == OVL_OP_FLAG_ALLOC) |
2185 | && CP_DECL_CONTEXT (fndecl)(!(! (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2185, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2185, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2185, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]) == global_namespacecp_global_trees[CPTI_GLOBAL] |
2186 | && !DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)((((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2186, __FUNCTION__, (FUNCTION_DECL)))->function_decl.decl_type ) == OPERATOR_NEW) && ((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2186, __FUNCTION__, (FUNCTION_DECL)))->function_decl.replaceable_operator )) |
2187 | && TREE_CODE (TREE_TYPE (fndecl))((enum tree_code) (((contains_struct_check ((fndecl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2187, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE) |
2188 | { |
2189 | tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))((contains_struct_check ((((tree_check2 ((((contains_struct_check ((fndecl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2189, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2189, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values)), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2189, __FUNCTION__))->common.chain); |
2190 | if (TREE_VALUE (first_arg)((tree_check ((first_arg), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2190, __FUNCTION__, (TREE_LIST)))->list.value) == ptr_type_nodeglobal_trees[TI_PTR_TYPE] |
2191 | && TREE_CHAIN (first_arg)((contains_struct_check ((first_arg), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2191, __FUNCTION__))->common.chain) == void_list_nodeglobal_trees[TI_VOID_LIST_NODE]) |
2192 | return true; |
2193 | } |
2194 | return false; |
2195 | } |
2196 | |
2197 | /* Return true if FNDECL is std::construct_at. */ |
2198 | |
2199 | static inline bool |
2200 | is_std_construct_at (tree fndecl) |
2201 | { |
2202 | if (!decl_in_std_namespace_p (fndecl)) |
2203 | return false; |
2204 | |
2205 | tree name = DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2205, __FUNCTION__))->decl_minimal.name); |
2206 | return name && id_equal (name, "construct_at"); |
2207 | } |
2208 | |
2209 | /* Overload for the above taking constexpr_call*. */ |
2210 | |
2211 | static inline bool |
2212 | is_std_construct_at (const constexpr_call *call) |
2213 | { |
2214 | return (call |
2215 | && call->fundef |
2216 | && is_std_construct_at (call->fundef->decl)); |
2217 | } |
2218 | |
2219 | /* True if CTX is an instance of std::allocator. */ |
2220 | |
2221 | bool |
2222 | is_std_allocator (tree ctx) |
2223 | { |
2224 | if (ctx == NULL_TREE(tree) __null || !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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2224, __FUNCTION__))->type_common.lang_flag_5)) || !TYPE_MAIN_DECL (ctx)((((contains_struct_check (((tree_class_check ((((tree_class_check ((ctx), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2224, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2224, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2224, __FUNCTION__))->common.chain)))) |
2225 | return false; |
2226 | |
2227 | tree decl = TYPE_MAIN_DECL (ctx)((((contains_struct_check (((tree_class_check ((((tree_class_check ((ctx), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2227, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2227, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2227, __FUNCTION__))->common.chain))); |
2228 | tree name = DECL_NAME (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2228, __FUNCTION__))->decl_minimal.name); |
2229 | if (name == NULL_TREE(tree) __null || !id_equal (name, "allocator")) |
2230 | return false; |
2231 | |
2232 | return decl_in_std_namespace_p (decl); |
2233 | } |
2234 | |
2235 | /* Return true if FNDECL is std::allocator<T>::{,de}allocate. */ |
2236 | |
2237 | static inline bool |
2238 | is_std_allocator_allocate (tree fndecl) |
2239 | { |
2240 | tree name = DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2240, __FUNCTION__))->decl_minimal.name); |
2241 | if (name == NULL_TREE(tree) __null |
2242 | || !(id_equal (name, "allocate") || id_equal (name, "deallocate"))) |
2243 | return false; |
2244 | |
2245 | return is_std_allocator (DECL_CONTEXT (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2245, __FUNCTION__))->decl_minimal.context)); |
2246 | } |
2247 | |
2248 | /* Overload for the above taking constexpr_call*. */ |
2249 | |
2250 | static inline bool |
2251 | is_std_allocator_allocate (const constexpr_call *call) |
2252 | { |
2253 | return (call |
2254 | && call->fundef |
2255 | && is_std_allocator_allocate (call->fundef->decl)); |
2256 | } |
2257 | |
2258 | /* Return true if FNDECL is __dynamic_cast. */ |
2259 | |
2260 | static inline bool |
2261 | cxx_dynamic_cast_fn_p (tree fndecl) |
2262 | { |
2263 | return (cxx_dialect >= cxx20 |
2264 | && id_equal (DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2264, __FUNCTION__))->decl_minimal.name), "__dynamic_cast") |
2265 | && CP_DECL_CONTEXT (fndecl)(!(! (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2265, __FUNCTION__))->decl_minimal.context)) || ((enum tree_code ) (((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2265, __FUNCTION__))->decl_minimal.context))->base.code ) == TRANSLATION_UNIT_DECL) ? ((contains_struct_check ((fndecl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2265, __FUNCTION__))->decl_minimal.context) : cp_global_trees [CPTI_GLOBAL]) == abi_nodecp_global_trees[CPTI_ABI]); |
2266 | } |
2267 | |
2268 | /* Often, we have an expression in the form of address + offset, e.g. |
2269 | "&_ZTV1A + 16". Extract the object from it, i.e. "_ZTV1A". */ |
2270 | |
2271 | static tree |
2272 | extract_obj_from_addr_offset (tree expr) |
2273 | { |
2274 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == POINTER_PLUS_EXPR) |
2275 | expr = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2275, __FUNCTION__))))); |
2276 | STRIP_NOPS (expr)(expr) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((expr))))); |
2277 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == ADDR_EXPR) |
2278 | expr = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2278, __FUNCTION__))))); |
2279 | return expr; |
2280 | } |
2281 | |
2282 | /* Given a PATH like |
2283 | |
2284 | g.D.2181.D.2154.D.2102.D.2093 |
2285 | |
2286 | find a component with type TYPE. Return NULL_TREE if not found, and |
2287 | error_mark_node if the component is not accessible. If STOP is non-null, |
2288 | this function will return NULL_TREE if STOP is found before TYPE. */ |
2289 | |
2290 | static tree |
2291 | get_component_with_type (tree path, tree type, tree stop) |
2292 | { |
2293 | while (true) |
2294 | { |
2295 | if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path)((contains_struct_check ((path), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2295, __FUNCTION__))->typed.type), type)) |
2296 | /* Found it. */ |
2297 | return path; |
2298 | else if (stop |
2299 | && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path)((contains_struct_check ((path), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2299, __FUNCTION__))->typed.type), |
2300 | stop))) |
2301 | return NULL_TREE(tree) __null; |
2302 | else if (TREE_CODE (path)((enum tree_code) (path)->base.code) == COMPONENT_REF |
2303 | && DECL_FIELD_IS_BASE (TREE_OPERAND (path, 1))((contains_struct_check (((tree_check (((*((const_cast<tree *> (tree_operand_check ((path), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2303, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2303, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2303, __FUNCTION__))->decl_common.lang_flag_6)) |
2304 | { |
2305 | /* We need to check that the component we're accessing is in fact |
2306 | accessible. */ |
2307 | if (TREE_PRIVATE (TREE_OPERAND (path, 1))(((*((const_cast<tree*> (tree_operand_check ((path), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2307, __FUNCTION__))))))->base.private_flag) |
2308 | || TREE_PROTECTED (TREE_OPERAND (path, 1))(((*((const_cast<tree*> (tree_operand_check ((path), (1 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2308, __FUNCTION__))))))->base.protected_flag)) |
2309 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
2310 | path = TREE_OPERAND (path, 0)(*((const_cast<tree*> (tree_operand_check ((path), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2310, __FUNCTION__))))); |
2311 | } |
2312 | else |
2313 | return NULL_TREE(tree) __null; |
2314 | } |
2315 | } |
2316 | |
2317 | /* Evaluate a call to __dynamic_cast (permitted by P1327R1). |
2318 | |
2319 | The declaration of __dynamic_cast is: |
2320 | |
2321 | void* __dynamic_cast (const void* __src_ptr, |
2322 | const __class_type_info* __src_type, |
2323 | const __class_type_info* __dst_type, |
2324 | ptrdiff_t __src2dst); |
2325 | |
2326 | where src2dst has the following possible values |
2327 | |
2328 | >-1: src_type is a unique public non-virtual base of dst_type |
2329 | dst_ptr + src2dst == src_ptr |
2330 | -1: unspecified relationship |
2331 | -2: src_type is not a public base of dst_type |
2332 | -3: src_type is a multiple public non-virtual base of dst_type |
2333 | |
2334 | Since literal types can't have virtual bases, we only expect hint >=0, |
2335 | -2, or -3. */ |
2336 | |
2337 | static tree |
2338 | cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, |
2339 | bool *non_constant_p, bool *overflow_p) |
2340 | { |
2341 | /* T will be something like |
2342 | __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8) |
2343 | dismantle it. */ |
2344 | gcc_assert (call_expr_nargs (call) == 4)((void)(!((((int)((unsigned long) (*tree_int_cst_elt_check (( (tree_class_check ((call), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2344, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2344, __FUNCTION__)))) - 3) == 4) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2344, __FUNCTION__), 0 : 0)); |
2345 | tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error; |
2346 | tree obj = CALL_EXPR_ARG (call, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2346, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2346, __FUNCTION__))))); |
2347 | tree type = CALL_EXPR_ARG (call, 2)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2347, __FUNCTION__, (CALL_EXPR)))), ((2) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2347, __FUNCTION__))))); |
2348 | HOST_WIDE_INTlong hint = int_cst_value (CALL_EXPR_ARG (call, 3)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2348, __FUNCTION__, (CALL_EXPR)))), ((3) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2348, __FUNCTION__)))))); |
2349 | location_t loc = cp_expr_loc_or_input_loc (call); |
2350 | |
2351 | /* Get the target type of the dynamic_cast. */ |
2352 | gcc_assert (TREE_CODE (type) == ADDR_EXPR)((void)(!(((enum tree_code) (type)->base.code) == ADDR_EXPR ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2352, __FUNCTION__), 0 : 0)); |
2353 | type = TREE_OPERAND (type, 0)(*((const_cast<tree*> (tree_operand_check ((type), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2353, __FUNCTION__))))); |
2354 | type = TREE_TYPE (DECL_NAME (type))((contains_struct_check ((((contains_struct_check ((type), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2354, __FUNCTION__))->decl_minimal.name)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2354, __FUNCTION__))->typed.type); |
2355 | |
2356 | /* TYPE can only be either T* or T&. We can't know which of these it |
2357 | is by looking at TYPE, but OBJ will be "(T*) x" in the first case, |
2358 | and something like "(T*)(T&)(T*) x" in the second case. */ |
2359 | bool reference_p = false; |
2360 | 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) |
2361 | { |
2362 | reference_p |= TYPE_REF_P (TREE_TYPE (obj))(((enum tree_code) (((contains_struct_check ((obj), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2362, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE ); |
2363 | obj = TREE_OPERAND (obj, 0)(*((const_cast<tree*> (tree_operand_check ((obj), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2363, __FUNCTION__))))); |
2364 | } |
2365 | |
2366 | /* Evaluate the object so that we know its dynamic type. */ |
2367 | obj = cxx_eval_constant_expression (ctx, obj, vc_prvalue, non_constant_p, |
2368 | overflow_p); |
2369 | if (*non_constant_p) |
2370 | return call; |
2371 | |
2372 | /* We expect OBJ to be in form of &d.D.2102 when HINT == 0, |
2373 | but when HINT is > 0, it can also be something like |
2374 | &d.D.2102 + 18446744073709551608, which includes the BINFO_OFFSET. */ |
2375 | obj = extract_obj_from_addr_offset (obj); |
2376 | const tree objtype = TREE_TYPE (obj)((contains_struct_check ((obj), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2376, __FUNCTION__))->typed.type); |
2377 | /* If OBJ doesn't refer to a base field, we're done. */ |
2378 | if (tree t = (TREE_CODE (obj)((enum tree_code) (obj)->base.code) == COMPONENT_REF |
2379 | ? TREE_OPERAND (obj, 1)(*((const_cast<tree*> (tree_operand_check ((obj), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2379, __FUNCTION__))))) : obj)) |
2380 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) != FIELD_DECL || !DECL_FIELD_IS_BASE (t)((contains_struct_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2380, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2380, __FUNCTION__))->decl_common.lang_flag_6)) |
2381 | { |
2382 | if (reference_p) |
2383 | { |
2384 | if (!ctx->quiet) |
2385 | { |
2386 | error_at (loc, "reference %<dynamic_cast%> failed"); |
2387 | inform (loc, "dynamic type %qT of its operand does " |
2388 | "not have a base class of type %qT", |
2389 | objtype, type); |
2390 | } |
2391 | *non_constant_p = true; |
2392 | } |
2393 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2394 | } |
2395 | |
2396 | /* [class.cdtor] When a dynamic_cast is used in a constructor ... |
2397 | or in a destructor ... if the operand of the dynamic_cast refers |
2398 | to the object under construction or destruction, this object is |
2399 | considered to be a most derived object that has the type of the |
2400 | constructor or destructor's class. */ |
2401 | tree vtable = build_vfield_ref (obj, objtype); |
2402 | vtable = cxx_eval_constant_expression (ctx, vtable, vc_prvalue, |
2403 | non_constant_p, overflow_p); |
2404 | if (*non_constant_p) |
2405 | return call; |
2406 | /* With -fsanitize=vptr, we initialize all vtable pointers to null, |
2407 | so it's possible that we got a null pointer now. */ |
2408 | if (integer_zerop (vtable)) |
2409 | { |
2410 | if (!ctx->quiet) |
2411 | error_at (loc, "virtual table pointer is used uninitialized"); |
2412 | *non_constant_p = true; |
2413 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2414 | } |
2415 | /* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A. */ |
2416 | vtable = extract_obj_from_addr_offset (vtable); |
2417 | const tree mdtype = DECL_CONTEXT (vtable)((contains_struct_check ((vtable), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2417, __FUNCTION__))->decl_minimal.context); |
2418 | |
2419 | /* Given dynamic_cast<T>(v), |
2420 | |
2421 | [expr.dynamic.cast] If C is the class type to which T points or refers, |
2422 | the runtime check logically executes as follows: |
2423 | |
2424 | If, in the most derived object pointed (referred) to by v, v points |
2425 | (refers) to a public base class subobject of a C object, and if only |
2426 | one object of type C is derived from the subobject pointed (referred) |
2427 | to by v the result points (refers) to that C object. |
2428 | |
2429 | In this case, HINT >= 0 or -3. */ |
2430 | if (hint >= 0 || hint == -3) |
2431 | { |
2432 | /* Look for a component with type TYPE. */ |
2433 | tree t = get_component_with_type (obj, type, mdtype); |
2434 | /* If not accessible, give an error. */ |
2435 | if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
2436 | { |
2437 | if (reference_p) |
2438 | { |
2439 | if (!ctx->quiet) |
2440 | { |
2441 | error_at (loc, "reference %<dynamic_cast%> failed"); |
2442 | inform (loc, "static type %qT of its operand is a " |
2443 | "non-public base class of dynamic type %qT", |
2444 | objtype, type); |
2445 | |
2446 | } |
2447 | *non_constant_p = true; |
2448 | } |
2449 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2450 | } |
2451 | else if (t) |
2452 | /* The result points to the TYPE object. */ |
2453 | return cp_build_addr_expr (t, complain); |
2454 | /* Else, TYPE was not found, because the HINT turned out to be wrong. |
2455 | Fall through to the normal processing. */ |
2456 | } |
2457 | |
2458 | /* Otherwise, if v points (refers) to a public base class subobject of the |
2459 | most derived object, and the type of the most derived object has a base |
2460 | class, of type C, that is unambiguous and public, the result points |
2461 | (refers) to the C subobject of the most derived object. |
2462 | |
2463 | But it can also be an invalid case. */ |
2464 | |
2465 | /* Get the most derived object. */ |
2466 | obj = get_component_with_type (obj, mdtype, NULL_TREE(tree) __null); |
2467 | if (obj == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
2468 | { |
2469 | if (reference_p) |
2470 | { |
2471 | if (!ctx->quiet) |
2472 | { |
2473 | error_at (loc, "reference %<dynamic_cast%> failed"); |
2474 | inform (loc, "static type %qT of its operand is a non-public" |
2475 | " base class of dynamic type %qT", objtype, mdtype); |
2476 | } |
2477 | *non_constant_p = true; |
2478 | } |
2479 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2480 | } |
2481 | else |
2482 | gcc_assert (obj)((void)(!(obj) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2482, __FUNCTION__), 0 : 0)); |
2483 | |
2484 | /* Check that the type of the most derived object has a base class |
2485 | of type TYPE that is unambiguous and public. */ |
2486 | base_kind b_kind; |
2487 | tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none); |
2488 | if (!binfo || binfo == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
2489 | { |
2490 | if (reference_p) |
2491 | { |
2492 | if (!ctx->quiet) |
2493 | { |
2494 | error_at (loc, "reference %<dynamic_cast%> failed"); |
2495 | if (b_kind == bk_ambig) |
2496 | inform (loc, "%qT is an ambiguous base class of dynamic " |
2497 | "type %qT of its operand", type, mdtype); |
2498 | else |
2499 | inform (loc, "dynamic type %qT of its operand does not " |
2500 | "have an unambiguous public base class %qT", |
2501 | mdtype, type); |
2502 | } |
2503 | *non_constant_p = true; |
2504 | } |
2505 | return integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2506 | } |
2507 | /* If so, return the TYPE subobject of the most derived object. */ |
2508 | obj = convert_to_base_statically (obj, binfo); |
2509 | return cp_build_addr_expr (obj, complain); |
2510 | } |
2511 | |
2512 | /* Data structure used by replace_decl and replace_decl_r. */ |
2513 | |
2514 | struct replace_decl_data |
2515 | { |
2516 | /* The _DECL we want to replace. */ |
2517 | tree decl; |
2518 | /* The replacement for DECL. */ |
2519 | tree replacement; |
2520 | /* Trees we've visited. */ |
2521 | hash_set<tree> *pset; |
2522 | /* Whether we've performed any replacements. */ |
2523 | bool changed; |
2524 | }; |
2525 | |
2526 | /* Helper function for replace_decl, called through cp_walk_tree. */ |
2527 | |
2528 | static tree |
2529 | replace_decl_r (tree *tp, int *walk_subtrees, void *data) |
2530 | { |
2531 | replace_decl_data *d = (replace_decl_data *) data; |
2532 | |
2533 | if (*tp == d->decl) |
2534 | { |
2535 | *tp = unshare_expr (d->replacement); |
2536 | d->changed = true; |
2537 | *walk_subtrees = 0; |
2538 | } |
2539 | else if (TYPE_P (*tp)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*tp)->base.code))] == tcc_type) |
2540 | || d->pset->add (*tp)) |
2541 | *walk_subtrees = 0; |
2542 | |
2543 | return NULL_TREE(tree) __null; |
2544 | } |
2545 | |
2546 | /* Replace every occurrence of DECL with (an unshared copy of) |
2547 | REPLACEMENT within the expression *TP. Returns true iff a |
2548 | replacement was performed. */ |
2549 | |
2550 | bool |
2551 | replace_decl (tree *tp, tree decl, tree replacement) |
2552 | { |
2553 | gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p((void)(!(same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2554, __FUNCTION__))->typed.type), ((contains_struct_check ((replacement), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2554, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2554, __FUNCTION__), 0 : 0)) |
2554 | (TREE_TYPE (decl), TREE_TYPE (replacement)))((void)(!(same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2554, __FUNCTION__))->typed.type), ((contains_struct_check ((replacement), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2554, __FUNCTION__))->typed.type))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2554, __FUNCTION__), 0 : 0)); |
2555 | hash_set<tree> pset; |
2556 | replace_decl_data data = { decl, replacement, &pset, false }; |
2557 | cp_walk_tree (tp, replace_decl_r, &data, NULL)walk_tree_1 (tp, replace_decl_r, &data, __null, cp_walk_subtrees ); |
2558 | return data.changed; |
2559 | } |
2560 | |
2561 | /* Evaluate the call T to virtual function thunk THUNK_FNDECL. */ |
2562 | |
2563 | static tree |
2564 | cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl, |
2565 | value_cat lval, |
2566 | bool *non_constant_p, bool *overflow_p) |
2567 | { |
2568 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2568, __FUNCTION__, (TEMPLATE_DECL))))))))->result : thunk_fndecl )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2568, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2568, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2568, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2568, __FUNCTION__); <->u.fn; })->befriending_classes ); |
2569 | |
2570 | if (THUNK_VIRTUAL_OFFSET (thunk_fndecl)(__extension__ ({ struct lang_decl *lt = ((contains_struct_check (((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__))->decl_common.lang_specific); if (!( (((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == VAR_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == FUNCTION_DECL ) || ((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == FIELD_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == CONST_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == TYPE_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == TEMPLATE_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == USING_DECL || ((enum tree_code) ((tree_check ((thunk_fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__, (FUNCTION_DECL))))->base.code) == CONCEPT_DECL )) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2570, __FUNCTION__); <->u.min; })->access)) |
2571 | { |
2572 | if (!ctx->quiet) |
2573 | { |
2574 | if (!DECL_DECLARED_CONSTEXPR_P (function)((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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2574, __FUNCTION__, (TEMPLATE_DECL))))))))->result : function )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2574, __FUNCTION__, (VAR_DECL), (FUNCTION_DECL)))), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2574, __FUNCTION__))->decl_common.lang_flag_8)) |
2575 | { |
2576 | error ("call to non-%<constexpr%> function %qD", function); |
2577 | explain_invalid_constexpr_fn (function); |
2578 | } |
2579 | else |
2580 | /* virtual_offset is only set for virtual bases, which make the |
2581 | class non-literal, so we don't need to handle it here. */ |
2582 | error ("calling constexpr member function %qD through virtual " |
2583 | "base subobject", function); |
2584 | } |
2585 | *non_constant_p = true; |
2586 | return t; |
2587 | } |
2588 | |
2589 | tree new_call = copy_node (t); |
2590 | CALL_EXPR_FN (new_call)(*((const_cast<tree*> (tree_operand_check (((tree_check ((new_call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2590, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2590, __FUNCTION__))))) = function; |
2591 | TREE_TYPE (new_call)((contains_struct_check ((new_call), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2591, __FUNCTION__))->typed.type) = TREE_TYPE (TREE_TYPE (function))((contains_struct_check ((((contains_struct_check ((function) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2591, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2591, __FUNCTION__))->typed.type); |
2592 | |
2593 | 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, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2593, __FUNCTION__, 0); __t; })), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2593, __FUNCTION__))->decl_common.lang_specific)->u.fn .u5.fixed_offset), stk_sizetype); |
2594 | |
2595 | if (DECL_THIS_THUNK_P (thunk_fndecl)((((enum tree_code) (thunk_fndecl)->base.code) == FUNCTION_DECL && ((contains_struct_check ((thunk_fndecl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __FUNCTION__, (TEMPLATE_DECL))))))))->result : thunk_fndecl )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __FUNCTION__, (TEMPLATE_DECL))))))))->result : thunk_fndecl )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((thunk_fndecl ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2595, __FUNCTION__); <->u.fn; })->this_thunk_p)) |
2596 | { |
2597 | /* 'this'-adjusting thunk. */ |
2598 | tree this_arg = CALL_EXPR_ARG (t, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2598, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2598, __FUNCTION__))))); |
2599 | this_arg = build2 (POINTER_PLUS_EXPR, TREE_TYPE (this_arg)((contains_struct_check ((this_arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2599, __FUNCTION__))->typed.type), |
2600 | this_arg, offset); |
2601 | CALL_EXPR_ARG (new_call, 0)(*((const_cast<tree*> (tree_operand_check (((tree_check ((new_call), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2601, __FUNCTION__, (CALL_EXPR)))), ((0) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2601, __FUNCTION__))))) = this_arg; |
2602 | } |
2603 | else |
2604 | /* Return-adjusting thunk. */ |
2605 | new_call = build2 (POINTER_PLUS_EXPR, TREE_TYPE (new_call)((contains_struct_check ((new_call), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2605, __FUNCTION__))->typed.type), |
2606 | new_call, offset); |
2607 | |
2608 | return cxx_eval_constant_expression (ctx, new_call, lval, |
2609 | non_constant_p, overflow_p); |
2610 | } |
2611 | |
2612 | /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set |
2613 | its TREE_READONLY flag according to READONLY_P. Used for constexpr |
2614 | 'tors to detect modifying const objects in a constexpr context. */ |
2615 | |
2616 | static void |
2617 | cxx_set_object_constness (const constexpr_ctx *ctx, tree object, |
2618 | bool readonly_p, bool *non_constant_p, |
2619 | bool *overflow_p) |
2620 | { |
2621 | if (CLASS_TYPE_P (TREE_TYPE (object))(((((enum tree_code) (((contains_struct_check ((object), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2621, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((object), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2621, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((object ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2621, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2621, __FUNCTION__))->type_common.lang_flag_5)) |
2622 | && CP_TYPE_CONST_P (TREE_TYPE (object))((cp_type_quals (((contains_struct_check ((object), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2622, __FUNCTION__))->typed.type)) & TYPE_QUAL_CONST ) != 0)) |
2623 | { |
2624 | /* Subobjects might not be stored in ctx->global->values but we |
2625 | can get its CONSTRUCTOR by evaluating *this. */ |
2626 | tree e = cxx_eval_constant_expression (ctx, object, vc_prvalue, |
2627 | non_constant_p, overflow_p); |
2628 | if (TREE_CODE (e)((enum tree_code) (e)->base.code) == CONSTRUCTOR && !*non_constant_p) |
2629 | TREE_READONLY (e)((non_type_check ((e), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2629, __FUNCTION__))->base.readonly_flag) = readonly_p; |
2630 | } |
2631 | } |
2632 | |
2633 | /* Subroutine of cxx_eval_constant_expression. |
2634 | Evaluate the call expression tree T in the context of OLD_CALL expression |
2635 | evaluation. */ |
2636 | |
2637 | static tree |
2638 | cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, |
2639 | value_cat lval, |
2640 | bool *non_constant_p, bool *overflow_p) |
2641 | { |
2642 | /* Handle concept checks separately. */ |
2643 | if (concept_check_p (t)) |
2644 | return evaluate_concept_check (t); |
2645 | |
2646 | location_t loc = cp_expr_loc_or_input_loc (t); |
2647 | tree fun = get_function_named_in_call (t); |
2648 | constexpr_call new_call |
2649 | = { NULL__null, NULL__null, NULL__null, 0, ctx->manifestly_const_eval }; |
2650 | int depth_ok; |
2651 | |
2652 | if (fun == NULL_TREE(tree) __null) |
2653 | return cxx_eval_internal_function (ctx, t, lval, |
2654 | non_constant_p, overflow_p); |
2655 | |
2656 | if (TREE_CODE (fun)((enum tree_code) (fun)->base.code) != FUNCTION_DECL) |
2657 | { |
2658 | /* Might be a constexpr function pointer. */ |
2659 | fun = cxx_eval_constant_expression (ctx, fun, vc_prvalue, |
2660 | non_constant_p, overflow_p); |
2661 | STRIP_NOPS (fun)(fun) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((fun))))); |
2662 | if (TREE_CODE (fun)((enum tree_code) (fun)->base.code) == ADDR_EXPR) |
2663 | fun = TREE_OPERAND (fun, 0)(*((const_cast<tree*> (tree_operand_check ((fun), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2663, __FUNCTION__))))); |
2664 | /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no |
2665 | indirection, the called expression is a pointer into the |
2666 | virtual table which should contain FDESC_EXPR. Extract the |
2667 | FUNCTION_DECL from there. */ |
2668 | else if (TARGET_VTABLE_USES_DESCRIPTORS0 |
2669 | && TREE_CODE (fun)((enum tree_code) (fun)->base.code) == POINTER_PLUS_EXPR |
2670 | && TREE_CODE (TREE_OPERAND (fun, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((fun), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2670, __FUNCTION__))))))->base.code) == ADDR_EXPR |
2671 | && TREE_CODE (TREE_OPERAND (fun, 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((fun), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2671, __FUNCTION__))))))->base.code) == INTEGER_CST) |
2672 | { |
2673 | tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((fun), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2673, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2673, __FUNCTION__))))); |
2674 | if (VAR_P (d)(((enum tree_code) (d)->base.code) == VAR_DECL) |
2675 | && DECL_VTABLE_OR_VTT_P (d)((contains_struct_check (((tree_check ((d), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2675, __FUNCTION__, (VAR_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2675, __FUNCTION__))->decl_common.virtual_flag) |
2676 | && TREE_CODE (TREE_TYPE (d))((enum tree_code) (((contains_struct_check ((d), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2676, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE |
2677 | && TREE_TYPE (TREE_TYPE (d))((contains_struct_check ((((contains_struct_check ((d), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2677, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2677, __FUNCTION__))->typed.type) == vtable_entry_typecp_global_trees[CPTI_VTABLE_ENTRY_TYPE] |
2678 | && DECL_INITIAL (d)((contains_struct_check ((d), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2678, __FUNCTION__))->decl_common.initial) |
2679 | && TREE_CODE (DECL_INITIAL (d))((enum tree_code) (((contains_struct_check ((d), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2679, __FUNCTION__))->decl_common.initial))->base.code ) == CONSTRUCTOR) |
2680 | { |
2681 | tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1)(*((const_cast<tree*> (tree_operand_check ((fun), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2681, __FUNCTION__))))), |
2682 | TYPE_SIZE_UNIT (vtable_entry_type)((tree_class_check ((cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]) , (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2682, __FUNCTION__))->type_common.size_unit)); |
2683 | HOST_WIDE_INTlong idx = find_array_ctor_elt (DECL_INITIAL (d)((contains_struct_check ((d), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2683, __FUNCTION__))->decl_common.initial), i); |
2684 | if (idx >= 0) |
2685 | { |
2686 | tree fdesc |
2687 | = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d))((tree_check ((((contains_struct_check ((d), (TS_DECL_COMMON) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2687, __FUNCTION__))->decl_common.initial)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2687, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[idx].value; |
2688 | if (TREE_CODE (fdesc)((enum tree_code) (fdesc)->base.code) == FDESC_EXPR |
2689 | && integer_zerop (TREE_OPERAND (fdesc, 1)(*((const_cast<tree*> (tree_operand_check ((fdesc), (1) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2689, __FUNCTION__))))))) |
2690 | fun = TREE_OPERAND (fdesc, 0)(*((const_cast<tree*> (tree_operand_check ((fdesc), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2690, __FUNCTION__))))); |
2691 | } |
2692 | } |
2693 | } |
2694 | } |
2695 | if (TREE_CODE (fun)((enum tree_code) (fun)->base.code) != FUNCTION_DECL) |
2696 | { |
2697 | if (!ctx->quiet && !*non_constant_p) |
2698 | error_at (loc, "expression %qE does not designate a %<constexpr%> " |
2699 | "function", fun); |
2700 | *non_constant_p = true; |
2701 | return t; |
2702 | } |
2703 | if (DECL_CLONED_FUNCTION_P (fun)(((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__))->decl_minimal.name) && ((!( (tree_not_check2 (((tree_check ((((contains_struct_check ((fun ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & ((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1)) && !((((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_CTOR_IDENTIFIER]) || (((contains_struct_check ((fun), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_DTOR_IDENTIFIER]))) && !DECL_DELETING_DESTRUCTOR_P (fun)(((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2703, __FUNCTION__))->decl_minimal.name) == cp_global_trees [CPTI_DELETING_DTOR_IDENTIFIER])) |
2704 | fun = DECL_CLONED_FUNCTION (fun)(((contains_struct_check (((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2704, __FUNCTION__, (FUNCTION_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2704, __FUNCTION__))->decl_common.lang_specific)->u.fn .u5.cloned_function); |
2705 | |
2706 | if (is_ubsan_builtin_p (fun)) |
2707 | return void_nodeglobal_trees[TI_VOID]; |
2708 | |
2709 | if (fndecl_built_in_p (fun)) |
2710 | return cxx_eval_builtin_function_call (ctx, t, fun, |
2711 | lval, non_constant_p, overflow_p); |
2712 | if (DECL_THUNK_P (fun)(((enum tree_code) (fun)->base.code) == FUNCTION_DECL && ((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2712, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2712, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2712, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2712, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((fun) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2712, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == FUNCTION_DECL)) || lt->u.base.selector != lds_fn ) lang_check_failed ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2712, __FUNCTION__); <->u.fn; })->thunk_p)) |
2713 | return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p); |
2714 | if (!maybe_constexpr_fn (fun)) |
2715 | { |
2716 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR |
2717 | && cxx_replaceable_global_alloc_fn (fun) |
2718 | && (CALL_FROM_NEW_OR_DELETE_P (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2718, __FUNCTION__, (CALL_EXPR)))->base.protected_flag) |
2719 | || is_std_allocator_allocate (ctx->call))) |
2720 | { |
2721 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2721, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2721, __FUNCTION__)))) - 3); |
2722 | tree arg0 = NULL_TREE(tree) __null; |
2723 | for (int i = 0; i < nargs; ++i) |
2724 | { |
2725 | tree arg = CALL_EXPR_ARG (t, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2725, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2725, __FUNCTION__))))); |
2726 | arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue, |
2727 | non_constant_p, overflow_p); |
2728 | VERIFY_CONSTANT (arg)do { if (verify_constant ((arg), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
2729 | if (i == 0) |
2730 | arg0 = arg; |
2731 | } |
2732 | gcc_assert (arg0)((void)(!(arg0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2732, __FUNCTION__), 0 : 0)); |
2733 | if (IDENTIFIER_NEW_OP_P (DECL_NAME (fun))(((((tree_not_check2 (((tree_check ((((contains_struct_check ( (fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & (!((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2733, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) & (OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE) ) == OVL_OP_FLAG_ALLOC)) |
2734 | { |
2735 | tree type = build_array_type_nelts (char_type_nodeinteger_types[itk_char], |
2736 | tree_to_uhwi (arg0)); |
2737 | tree var = build_decl (loc, VAR_DECL, |
2738 | (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2738, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2738, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2738, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2738, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2738, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) |
2739 | & OVL_OP_FLAG_VEC) |
2740 | ? heap_vec_uninit_identifiercp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER] |
2741 | : heap_uninit_identifiercp_global_trees[CPTI_HEAP_UNINIT_IDENTIFIER], |
2742 | type); |
2743 | DECL_ARTIFICIAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2743, __FUNCTION__))->decl_common.artificial_flag) = 1; |
2744 | TREE_STATIC (var)((var)->base.static_flag) = 1; |
2745 | // Temporarily register the artificial var in varpool, |
2746 | // so that comparisons of its address against NULL are folded |
2747 | // through nonzero_address even with |
2748 | // -fno-delete-null-pointer-checks or that comparison of |
2749 | // addresses of different heap artificial vars is folded too. |
2750 | // See PR98988 and PR99031. |
2751 | varpool_node::finalize_decl (var); |
2752 | ctx->global->heap_vars.safe_push (var); |
2753 | ctx->global->put_value (var, NULL_TREE(tree) __null); |
2754 | return fold_convert (ptr_type_node, build_address (var))fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE] , build_address (var)); |
2755 | } |
2756 | else |
2757 | { |
2758 | STRIP_NOPS (arg0)(arg0) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((arg0))))); |
2759 | if (TREE_CODE (arg0)((enum tree_code) (arg0)->base.code) == ADDR_EXPR |
2760 | && VAR_P (TREE_OPERAND (arg0, 0))(((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((arg0), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2760, __FUNCTION__))))))->base.code) == VAR_DECL)) |
2761 | { |
2762 | tree var = TREE_OPERAND (arg0, 0)(*((const_cast<tree*> (tree_operand_check ((arg0), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2762, __FUNCTION__))))); |
2763 | if (DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2763, __FUNCTION__))->decl_minimal.name) == heap_uninit_identifiercp_global_trees[CPTI_HEAP_UNINIT_IDENTIFIER] |
2764 | || DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2764, __FUNCTION__))->decl_minimal.name) == heap_identifiercp_global_trees[CPTI_HEAP_IDENTIFIER]) |
2765 | { |
2766 | if (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2766, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2766, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2766, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2766, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2766, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) |
2767 | & OVL_OP_FLAG_VEC) |
2768 | { |
2769 | if (!ctx->quiet) |
2770 | { |
2771 | error_at (loc, "array deallocation of object " |
2772 | "allocated with non-array " |
2773 | "allocation"); |
2774 | inform (DECL_SOURCE_LOCATION (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2774, __FUNCTION__))->decl_minimal.locus), |
2775 | "allocation performed here"); |
2776 | } |
2777 | *non_constant_p = true; |
2778 | return t; |
2779 | } |
2780 | DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2780, __FUNCTION__))->decl_minimal.name) = heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]; |
2781 | ctx->global->remove_value (var); |
2782 | ctx->global->heap_dealloc_count++; |
2783 | return void_nodeglobal_trees[TI_VOID]; |
2784 | } |
2785 | else if (DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2785, __FUNCTION__))->decl_minimal.name) == heap_vec_uninit_identifiercp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER] |
2786 | || DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2786, __FUNCTION__))->decl_minimal.name) == heap_vec_identifiercp_global_trees[CPTI_HEAP_VEC_IDENTIFIER]) |
2787 | { |
2788 | if ((IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))((&ovl_op_info[((tree_not_check2 (((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2788, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2788, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2788, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0)][((tree_check ((((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2788, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2788, __FUNCTION__, (IDENTIFIER_NODE)))->base.u.bits.address_space )])->flags) |
2789 | & OVL_OP_FLAG_VEC) == 0) |
2790 | { |
2791 | if (!ctx->quiet) |
2792 | { |
2793 | error_at (loc, "non-array deallocation of " |
2794 | "object allocated with array " |
2795 | "allocation"); |
2796 | inform (DECL_SOURCE_LOCATION (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2796, __FUNCTION__))->decl_minimal.locus), |
2797 | "allocation performed here"); |
2798 | } |
2799 | *non_constant_p = true; |
2800 | return t; |
2801 | } |
2802 | DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2802, __FUNCTION__))->decl_minimal.name) = heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]; |
2803 | ctx->global->remove_value (var); |
2804 | ctx->global->heap_dealloc_count++; |
2805 | return void_nodeglobal_trees[TI_VOID]; |
2806 | } |
2807 | else if (DECL_NAME (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2807, __FUNCTION__))->decl_minimal.name) == heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]) |
2808 | { |
2809 | if (!ctx->quiet) |
2810 | error_at (loc, "deallocation of already deallocated " |
2811 | "storage"); |
2812 | *non_constant_p = true; |
2813 | return t; |
2814 | } |
2815 | } |
2816 | if (!ctx->quiet) |
2817 | error_at (loc, "deallocation of storage that was " |
2818 | "not previously allocated"); |
2819 | *non_constant_p = true; |
2820 | return t; |
2821 | } |
2822 | } |
2823 | /* Allow placement new in std::construct_at, just return the second |
2824 | argument. */ |
2825 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR |
2826 | && cxx_placement_new_fn (fun) |
2827 | && is_std_construct_at (ctx->call)) |
2828 | { |
2829 | const int nargs = call_expr_nargs (t)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check ((t), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2829, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2829, __FUNCTION__)))) - 3); |
2830 | tree arg1 = NULL_TREE(tree) __null; |
2831 | for (int i = 0; i < nargs; ++i) |
2832 | { |
2833 | tree arg = CALL_EXPR_ARG (t, i)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2833, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2833, __FUNCTION__))))); |
2834 | arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue, |
2835 | non_constant_p, overflow_p); |
2836 | if (i == 1) |
2837 | arg1 = arg; |
2838 | else |
2839 | VERIFY_CONSTANT (arg)do { if (verify_constant ((arg), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
2840 | } |
2841 | gcc_assert (arg1)((void)(!(arg1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2841, __FUNCTION__), 0 : 0)); |
2842 | return arg1; |
2843 | } |
2844 | else if (cxx_dynamic_cast_fn_p (fun)) |
2845 | return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p); |
2846 | |
2847 | if (!ctx->quiet) |
2848 | { |
2849 | if (!lambda_static_thunk_p (fun)) |
2850 | error_at (loc, "call to non-%<constexpr%> function %qD", fun); |
2851 | explain_invalid_constexpr_fn (fun); |
2852 | } |
2853 | *non_constant_p = true; |
2854 | return t; |
2855 | } |
2856 | |
2857 | constexpr_ctx new_ctx = *ctx; |
2858 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2858, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2858, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ) && !ctx->object |
2859 | && TREE_CODE (t)((enum tree_code) (t)->base.code) == AGGR_INIT_EXPR) |
2860 | { |
2861 | /* We want to have an initialization target for an AGGR_INIT_EXPR. |
2862 | If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */ |
2863 | new_ctx.object = AGGR_INIT_EXPR_SLOT (t)(*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2863, __FUNCTION__, (AGGR_INIT_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2863, __FUNCTION__))))); |
2864 | tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2864, __FUNCTION__))->decl_minimal.context), NULL__null); |
2865 | CONSTRUCTOR_NO_CLEARING (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2865, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = true; |
2866 | ctx->global->put_value (new_ctx.object, ctor); |
2867 | ctx = &new_ctx; |
2868 | } |
2869 | |
2870 | /* We used to shortcut trivial constructor/op= here, but nowadays |
2871 | we can only get a trivial function here with -fno-elide-constructors. */ |
2872 | gcc_checking_assert (!trivial_fn_p (fun)((void)(!(!trivial_fn_p (fun) || !global_options.x_flag_elide_constructors || scope_chain->noexcept_operand) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2876, __FUNCTION__), 0 : 0)) |
2873 | || !flag_elide_constructors((void)(!(!trivial_fn_p (fun) || !global_options.x_flag_elide_constructors || scope_chain->noexcept_operand) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2876, __FUNCTION__), 0 : 0)) |
2874 | /* We don't elide constructors when processing((void)(!(!trivial_fn_p (fun) || !global_options.x_flag_elide_constructors || scope_chain->noexcept_operand) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2876, __FUNCTION__), 0 : 0)) |
2875 | a noexcept-expression. */((void)(!(!trivial_fn_p (fun) || !global_options.x_flag_elide_constructors || scope_chain->noexcept_operand) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2876, __FUNCTION__), 0 : 0)) |
2876 | || cp_noexcept_operand)((void)(!(!trivial_fn_p (fun) || !global_options.x_flag_elide_constructors || scope_chain->noexcept_operand) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2876, __FUNCTION__), 0 : 0)); |
2877 | |
2878 | bool non_constant_args = false; |
2879 | new_call.bindings |
2880 | = cxx_bind_parameters_in_call (ctx, t, fun, non_constant_p, |
2881 | overflow_p, &non_constant_args); |
2882 | |
2883 | /* We build up the bindings list before we know whether we already have this |
2884 | call cached. If we don't end up saving these bindings, ggc_free them when |
2885 | this function exits. */ |
2886 | class free_bindings |
2887 | { |
2888 | tree *bindings; |
2889 | public: |
2890 | free_bindings (tree &b): bindings (&b) { } |
2891 | ~free_bindings () { if (bindings) ggc_free (*bindings); } |
2892 | void preserve () { bindings = NULL__null; } |
2893 | } fb (new_call.bindings); |
2894 | |
2895 | if (*non_constant_p) |
2896 | return t; |
2897 | |
2898 | /* We can't defer instantiating the function any longer. */ |
2899 | if (!DECL_INITIAL (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2899, __FUNCTION__))->decl_common.initial) |
2900 | && DECL_TEMPLOID_INSTANTIATION (fun)(((((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2900, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template) & 1) || (((contains_struct_check ((fun), ( TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2900, __FUNCTION__))->decl_common.lang_specific) && (((contains_struct_check ((template_info_decl_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2900, __FUNCTION__)), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2900, __FUNCTION__))->decl_common.lang_specific) ->u. min.template_info) && !(((contains_struct_check ((fun ), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2900, __FUNCTION__))->decl_common.lang_specific)->u.base .use_template))) |
2901 | && !uid_sensitive_constexpr_evaluation_p ()) |
2902 | { |
2903 | location_t save_loc = input_location; |
2904 | input_location = loc; |
2905 | ++function_depth; |
2906 | if (ctx->manifestly_const_eval == mce_true) |
2907 | FNDECL_MANIFESTLY_CONST_EVALUATED (fun)((tree_not_check2 (((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2907, __FUNCTION__, (FUNCTION_DECL)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2907, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_4) = true; |
2908 | instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false); |
2909 | --function_depth; |
2910 | input_location = save_loc; |
2911 | } |
2912 | |
2913 | /* If in direct recursive call, optimize definition search. */ |
2914 | if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun) |
2915 | new_call.fundef = ctx->call->fundef; |
2916 | else |
2917 | { |
2918 | new_call.fundef = retrieve_constexpr_fundef (fun); |
2919 | if (new_call.fundef == NULL__null || new_call.fundef->body == NULL__null |
2920 | || new_call.fundef->result == error_mark_nodeglobal_trees[TI_ERROR_MARK] |
2921 | || fun == current_function_decl) |
2922 | { |
2923 | if (!ctx->quiet) |
2924 | { |
2925 | /* We need to check for current_function_decl here in case we're |
2926 | being called during cp_fold_function, because at that point |
2927 | DECL_INITIAL is set properly and we have a fundef but we |
2928 | haven't lowered invisirefs yet (c++/70344). */ |
2929 | if (DECL_INITIAL (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2929, __FUNCTION__))->decl_common.initial) == error_mark_nodeglobal_trees[TI_ERROR_MARK] |
2930 | || fun == current_function_decl) |
2931 | error_at (loc, "%qD called in a constant expression before its " |
2932 | "definition is complete", fun); |
2933 | else if (DECL_INITIAL (fun)((contains_struct_check ((fun), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2933, __FUNCTION__))->decl_common.initial)) |
2934 | { |
2935 | /* The definition of fun was somehow unsuitable. But pretend |
2936 | that lambda static thunks don't exist. */ |
2937 | if (!lambda_static_thunk_p (fun)) |
2938 | error_at (loc, "%qD called in a constant expression", fun); |
2939 | explain_invalid_constexpr_fn (fun); |
2940 | } |
2941 | else |
2942 | error_at (loc, "%qD used before its definition", fun); |
2943 | } |
2944 | *non_constant_p = true; |
2945 | return t; |
2946 | } |
2947 | } |
2948 | |
2949 | depth_ok = push_cx_call_context (t); |
2950 | |
2951 | /* Remember the object we are constructing or destructing. */ |
2952 | tree new_obj = NULL_TREE(tree) __null; |
2953 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2953, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2953, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2953, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2953, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) |
2954 | { |
2955 | /* In a cdtor, it should be the first `this' argument. |
2956 | At this point it has already been evaluated in the call |
2957 | to cxx_bind_parameters_in_call. */ |
2958 | new_obj = TREE_VEC_ELT (new_call.bindings, 0)(*((const_cast<tree *> (tree_vec_elt_check ((new_call.bindings ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2958, __FUNCTION__))))); |
2959 | new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun)((contains_struct_check ((fun), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2959, __FUNCTION__))->decl_minimal.context), new_obj); |
2960 | |
2961 | if (ctx->call && ctx->call->fundef |
2962 | && 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2962, __FUNCTION__, (TEMPLATE_DECL))))))))->result : ctx ->call->fundef->decl)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2962, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
2963 | { |
2964 | tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0)(*((const_cast<tree *> (tree_vec_elt_check ((ctx->call ->bindings), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2964, __FUNCTION__))))); |
2965 | STRIP_NOPS (cur_obj)(cur_obj) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((cur_obj))))); |
2966 | if (TREE_CODE (cur_obj)((enum tree_code) (cur_obj)->base.code) == ADDR_EXPR) |
2967 | cur_obj = TREE_OPERAND (cur_obj, 0)(*((const_cast<tree*> (tree_operand_check ((cur_obj), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 2967, __FUNCTION__))))); |
2968 | if (new_obj == cur_obj) |
2969 | /* We're calling the target constructor of a delegating |
2970 | constructor, or accessing a base subobject through a |
2971 | NOP_EXPR as part of a call to a base constructor, so |
2972 | there is no new (sub)object. */ |
2973 | new_obj = NULL_TREE(tree) __null; |
2974 | } |
2975 | } |
2976 | |
2977 | tree result = NULL_TREE(tree) __null; |
2978 | |
2979 | constexpr_call *entry = NULL__null; |
2980 | if (depth_ok && !non_constant_args && ctx->strict) |
2981 | { |
2982 | new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef); |
2983 | new_call.hash |
2984 | = iterative_hash_template_arg (new_call.bindings, new_call.hash); |
2985 | new_call.hash |
2986 | = iterative_hash_object (ctx->manifestly_const_eval, new_call.hash)iterative_hash (&ctx->manifestly_const_eval, sizeof (ctx ->manifestly_const_eval), new_call.hash); |
2987 | |
2988 | /* If we have seen this call before, we are done. */ |
2989 | maybe_initialize_constexpr_call_table (); |
2990 | bool insert = depth_ok < constexpr_cache_depthglobal_options.x_constexpr_cache_depth; |
2991 | constexpr_call **slot |
2992 | = constexpr_call_table->find_slot (&new_call, |
2993 | insert ? INSERT : NO_INSERT); |
2994 | entry = slot ? *slot : NULL__null; |
2995 | if (entry == NULL__null) |
2996 | { |
2997 | /* Only cache up to constexpr_cache_depth to limit memory use. */ |
2998 | if (insert) |
2999 | { |
3000 | /* We need to keep a pointer to the entry, not just the slot, as |
3001 | the slot can move during evaluation of the body. */ |
3002 | *slot = entry = ggc_alloc<constexpr_call> (); |
3003 | *entry = new_call; |
3004 | fb.preserve (); |
3005 | } |
3006 | } |
3007 | /* Calls that are in progress have their result set to NULL, so that we |
3008 | can detect circular dependencies. Now that we only cache up to |
3009 | constexpr_cache_depth this won't catch circular dependencies that |
3010 | start deeper, but they'll hit the recursion or ops limit. */ |
3011 | else if (entry->result == NULL__null) |
3012 | { |
3013 | if (!ctx->quiet) |
3014 | error ("call has circular dependency"); |
3015 | *non_constant_p = true; |
3016 | entry->result = result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3017 | } |
3018 | else |
3019 | result = entry->result; |
3020 | } |
3021 | |
3022 | if (!depth_ok) |
3023 | { |
3024 | if (!ctx->quiet) |
3025 | error ("%<constexpr%> evaluation depth exceeds maximum of %d (use " |
3026 | "%<-fconstexpr-depth=%> to increase the maximum)", |
3027 | max_constexpr_depthglobal_options.x_max_constexpr_depth); |
3028 | *non_constant_p = true; |
3029 | result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3030 | } |
3031 | else |
3032 | { |
3033 | bool cacheable = true; |
3034 | if (result && result != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
3035 | /* OK */; |
3036 | else if (!DECL_SAVED_TREE (fun)((tree_check ((fun), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3036, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree )) |
3037 | { |
3038 | /* When at_eof >= 2, cgraph has started throwing away |
3039 | DECL_SAVED_TREE, so fail quietly. FIXME we get here because of |
3040 | late code generation for VEC_INIT_EXPR, which needs to be |
3041 | completely reconsidered. */ |
3042 | gcc_assert (at_eof >= 2 && ctx->quiet)((void)(!(at_eof >= 2 && ctx->quiet) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3042, __FUNCTION__), 0 : 0)); |
3043 | *non_constant_p = true; |
3044 | } |
3045 | else if (tree copy = get_fundef_copy (new_call.fundef)) |
3046 | { |
3047 | tree body, parms, res; |
3048 | releasing_vec ctors; |
3049 | |
3050 | /* Reuse or create a new unshared copy of this function's body. */ |
3051 | body = TREE_PURPOSE (copy)((tree_check ((copy), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3051, __FUNCTION__, (TREE_LIST)))->list.purpose); |
3052 | parms = TREE_VALUE (copy)((tree_check ((copy), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3052, __FUNCTION__, (TREE_LIST)))->list.value); |
3053 | res = TREE_TYPE (copy)((contains_struct_check ((copy), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3053, __FUNCTION__))->typed.type); |
3054 | |
3055 | /* Associate the bindings with the remapped parms. */ |
3056 | tree bound = new_call.bindings; |
3057 | tree remapped = parms; |
3058 | for (int i = 0; i < TREE_VEC_LENGTH (bound)((tree_check ((bound), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3058, __FUNCTION__, (TREE_VEC)))->base.u.length); ++i) |
3059 | { |
3060 | tree arg = TREE_VEC_ELT (bound, i)(*((const_cast<tree *> (tree_vec_elt_check ((bound), (i ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3060, __FUNCTION__))))); |
3061 | if (entry) |
3062 | { |
3063 | /* Unshare args going into the hash table to separate them |
3064 | from the caller's context, for better GC and to avoid |
3065 | problems with verify_gimple. */ |
3066 | arg = unshare_expr_without_location (arg); |
3067 | TREE_VEC_ELT (bound, i)(*((const_cast<tree *> (tree_vec_elt_check ((bound), (i ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3067, __FUNCTION__))))) = arg; |
3068 | |
3069 | /* And then unshare again so the callee doesn't change the |
3070 | argument values in the hash table. XXX Could we unshare |
3071 | lazily in cxx_eval_store_expression? */ |
3072 | arg = unshare_constructor (arg); |
3073 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == CONSTRUCTOR) |
3074 | vec_safe_push (ctors, arg); |
3075 | } |
3076 | ctx->global->put_value (remapped, arg); |
3077 | remapped = DECL_CHAIN (remapped)(((contains_struct_check (((contains_struct_check ((remapped) , (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3077, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3077, __FUNCTION__))->common.chain)); |
3078 | } |
3079 | /* Add the RESULT_DECL to the values map, too. */ |
3080 | gcc_assert (!DECL_BY_REFERENCE (res))((void)(!(!((tree_check3 ((res), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3080, __FUNCTION__, (VAR_DECL), (PARM_DECL), (RESULT_DECL)) )->decl_common.decl_by_reference_flag)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3080, __FUNCTION__), 0 : 0)); |
3081 | ctx->global->put_value (res, NULL_TREE(tree) __null); |
3082 | |
3083 | /* Track the callee's evaluated SAVE_EXPRs and TARGET_EXPRs so that |
3084 | we can forget their values after the call. */ |
3085 | constexpr_ctx ctx_with_save_exprs = *ctx; |
3086 | auto_vec<tree, 10> save_exprs; |
3087 | ctx_with_save_exprs.save_exprs = &save_exprs; |
3088 | ctx_with_save_exprs.call = &new_call; |
3089 | unsigned save_heap_alloc_count = ctx->global->heap_vars.length (); |
3090 | unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count; |
3091 | |
3092 | /* If this is a constexpr destructor, the object's const and volatile |
3093 | semantics are no longer in effect; see [class.dtor]p5. */ |
3094 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3094, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3094, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) |
3095 | cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false, |
3096 | non_constant_p, overflow_p); |
3097 | |
3098 | tree jump_target = NULL_TREE(tree) __null; |
3099 | cxx_eval_constant_expression (&ctx_with_save_exprs, body, |
3100 | vc_discard, non_constant_p, overflow_p, |
3101 | &jump_target); |
3102 | |
3103 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3103, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3103, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
3104 | { |
3105 | /* This can be null for a subobject constructor call, in |
3106 | which case what we care about is the initialization |
3107 | side-effects rather than the value. We could get at the |
3108 | value by evaluating *this, but we don't bother; there's |
3109 | no need to put such a call in the hash table. */ |
3110 | result = lval ? ctx->object : ctx->ctor; |
3111 | |
3112 | /* If we've just evaluated a subobject constructor call for an |
3113 | empty union member, it might not have produced a side effect |
3114 | that actually activated the union member. So produce such a |
3115 | side effect now to ensure the union appears initialized. */ |
3116 | if (!result && new_obj |
3117 | && TREE_CODE (new_obj)((enum tree_code) (new_obj)->base.code) == COMPONENT_REF |
3118 | && TREE_CODE (TREE_TYPE((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((new_obj), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3119, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3119, __FUNCTION__))->typed.type))->base.code) |
3119 | (TREE_OPERAND (new_obj, 0)))((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((new_obj), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3119, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3119, __FUNCTION__))->typed.type))->base.code) == UNION_TYPE |
3120 | && is_really_empty_class (TREE_TYPE (new_obj)((contains_struct_check ((new_obj), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3120, __FUNCTION__))->typed.type), |
3121 | /*ignore_vptr*/false)) |
3122 | { |
3123 | tree activate = build2 (MODIFY_EXPR, TREE_TYPE (new_obj)((contains_struct_check ((new_obj), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3123, __FUNCTION__))->typed.type), |
3124 | new_obj, |
3125 | build_constructor (TREE_TYPE (new_obj)((contains_struct_check ((new_obj), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3125, __FUNCTION__))->typed.type), |
3126 | NULL__null)); |
3127 | cxx_eval_constant_expression (ctx, activate, lval, |
3128 | non_constant_p, overflow_p); |
3129 | ggc_free (activate); |
3130 | } |
3131 | } |
3132 | else if (VOID_TYPE_P (TREE_TYPE (res))(((enum tree_code) (((contains_struct_check ((res), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3132, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
3133 | result = void_nodeglobal_trees[TI_VOID]; |
3134 | else |
3135 | { |
3136 | result = ctx->global->get_value (res); |
3137 | if (result == NULL_TREE(tree) __null && !*non_constant_p |
3138 | && !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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3138, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3138, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) |
3139 | { |
3140 | if (!ctx->quiet) |
3141 | error ("%<constexpr%> call flows off the end " |
3142 | "of the function"); |
3143 | *non_constant_p = true; |
3144 | } |
3145 | } |
3146 | |
3147 | /* At this point, the object's constructor will have run, so |
3148 | the object is no longer under construction, and its possible |
3149 | 'const' semantics now apply. Make a note of this fact by |
3150 | marking the CONSTRUCTOR TREE_READONLY. */ |
3151 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3151, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3151, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor )) |
3152 | cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true, |
3153 | non_constant_p, overflow_p); |
3154 | |
3155 | /* Forget the saved values of the callee's SAVE_EXPRs and |
3156 | TARGET_EXPRs. */ |
3157 | for (tree save_expr : save_exprs) |
3158 | ctx->global->remove_value (save_expr); |
3159 | |
3160 | /* Remove the parms/result from the values map. Is it worth |
3161 | bothering to do this when the map itself is only live for |
3162 | one constexpr evaluation? If so, maybe also clear out |
3163 | other vars from call, maybe in BIND_EXPR handling? */ |
3164 | ctx->global->remove_value (res); |
3165 | for (tree parm = parms; parm; parm = TREE_CHAIN (parm)((contains_struct_check ((parm), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3165, __FUNCTION__))->common.chain)) |
3166 | ctx->global->remove_value (parm); |
3167 | |
3168 | /* Free any parameter CONSTRUCTORs we aren't returning directly. */ |
3169 | while (!ctors->is_empty ()) |
3170 | { |
3171 | tree c = ctors->pop (); |
3172 | if (c != result) |
3173 | free_constructor (c); |
3174 | } |
3175 | |
3176 | /* Make the unshared function copy we used available for re-use. */ |
3177 | save_fundef_copy (fun, copy); |
3178 | |
3179 | /* If the call allocated some heap object that hasn't been |
3180 | deallocated during the call, or if it deallocated some heap |
3181 | object it has not allocated, the call isn't really stateless |
3182 | for the constexpr evaluation and should not be cached. |
3183 | It is fine if the call allocates something and deallocates it |
3184 | too. */ |
3185 | if (entry |
3186 | && (save_heap_alloc_count != ctx->global->heap_vars.length () |
3187 | || (save_heap_dealloc_count |
3188 | != ctx->global->heap_dealloc_count))) |
3189 | { |
3190 | tree heap_var; |
3191 | unsigned int i; |
3192 | if ((ctx->global->heap_vars.length () |
3193 | - ctx->global->heap_dealloc_count) |
3194 | != save_heap_alloc_count - save_heap_dealloc_count) |
3195 | cacheable = false; |
3196 | else |
3197 | 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)) |
3198 | save_heap_alloc_count)for (i = (save_heap_alloc_count); (ctx->global->heap_vars ).iterate ((i), &(heap_var)); ++(i)) |
3199 | if (DECL_NAME (heap_var)((contains_struct_check ((heap_var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3199, __FUNCTION__))->decl_minimal.name) != heap_deleted_identifiercp_global_trees[CPTI_HEAP_DELETED_IDENTIFIER]) |
3200 | { |
3201 | cacheable = false; |
3202 | break; |
3203 | } |
3204 | /* Also don't cache a call that returns a deallocated pointer. */ |
3205 | if (cacheable && (cp_walk_tree_without_duplicateswalk_tree_without_duplicates_1 (&result, find_heap_var_refs , __null, cp_walk_subtrees) |
3206 | (&result, find_heap_var_refs, NULL)walk_tree_without_duplicates_1 (&result, find_heap_var_refs , __null, cp_walk_subtrees))) |
3207 | cacheable = false; |
3208 | } |
3209 | |
3210 | /* Rewrite all occurrences of the function's RESULT_DECL with the |
3211 | current object under construction. */ |
3212 | if (!*non_constant_p && ctx->object |
3213 | && CLASS_TYPE_P (TREE_TYPE (res))(((((enum tree_code) (((contains_struct_check ((res), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3213, __FUNCTION__))->typed.type))->base.code)) == RECORD_TYPE || (((enum tree_code) (((contains_struct_check ((res), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3213, __FUNCTION__))->typed.type))->base.code)) == UNION_TYPE ) && ((tree_class_check ((((contains_struct_check ((res ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3213, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3213, __FUNCTION__))->type_common.lang_flag_5)) |
3214 | && !is_empty_class (TREE_TYPE (res)((contains_struct_check ((res), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3214, __FUNCTION__))->typed.type))) |
3215 | if (replace_decl (&result, res, ctx->object)) |
3216 | cacheable = false; |
3217 | } |
3218 | else |
3219 | /* Couldn't get a function copy to evaluate. */ |
3220 | *non_constant_p = true; |
3221 | |
3222 | if (result == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
3223 | *non_constant_p = true; |
3224 | if (*non_constant_p || *overflow_p) |
3225 | result = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3226 | else if (!result) |
3227 | result = void_nodeglobal_trees[TI_VOID]; |
3228 | if (entry) |
3229 | entry->result = cacheable ? result : error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
3230 | } |
3231 | |
3232 | /* The result of a constexpr function must be completely initialized. |
3233 | |
3234 | However, in C++20, a constexpr constructor doesn't necessarily have |
3235 | to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING |
3236 | in order to detect reading an unitialized object in constexpr instead |
3237 | of value-initializing it. (reduced_constant_expression_p is expected to |
3238 | take care of clearing the flag.) */ |
3239 | if (TREE_CODE (result)((enum tree_code) (result)->base.code) == CONSTRUCTOR |
3240 | && (cxx_dialect < cxx20 |
3241 | || !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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3241, __FUNCTION__, (TEMPLATE_DECL))))))))->result : fun )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3241, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_constructor ))) |
3242 | clear_no_implicit_zero (result); |
3243 | |
3244 | pop_cx_call_context (); |
3245 | return result; |
3246 | } |
3247 | |
3248 | /* Return true if T is a valid constant initializer. If a CONSTRUCTOR |
3249 | initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be |
3250 | cleared. |
3251 | FIXME speed this up, it's taking 16% of compile time on sieve testcase. */ |
3252 | |
3253 | bool |
3254 | reduced_constant_expression_p (tree t) |
3255 | { |
3256 | if (t == NULL_TREE(tree) __null) |
3257 | return false; |
3258 | |
3259 | switch (TREE_CODE (t)((enum tree_code) (t)->base.code)) |
3260 | { |
3261 | case PTRMEM_CST: |
3262 | /* Even if we can't lower this yet, it's constant. */ |
3263 | return true; |
3264 | |
3265 | case CONSTRUCTOR: |
3266 | /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */ |
3267 | tree field; |
3268 | if (TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3268, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE) |
3269 | /* An initialized vector would have a VECTOR_CST. */ |
3270 | return false; |
3271 | if (CONSTRUCTOR_NO_CLEARING (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3271, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) |
3272 | { |
3273 | if (TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3273, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE) |
3274 | { |
3275 | /* There must be a valid constant initializer at every array |
3276 | index. */ |
3277 | tree min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (t)))((tree_check5 ((((tree_check ((((contains_struct_check ((t), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3277, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3277, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3277, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval ); |
3278 | tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)))((tree_check5 ((((tree_check ((((contains_struct_check ((t), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3278, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3278, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3278, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ); |
3279 | tree cursor = min; |
3280 | for (auto &e: CONSTRUCTOR_ELTS (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3280, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)) |
3281 | { |
3282 | if (!reduced_constant_expression_p (e.value)) |
3283 | return false; |
3284 | if (array_index_cmp (cursor, e.index) != 0) |
3285 | return false; |
3286 | if (TREE_CODE (e.index)((enum tree_code) (e.index)->base.code) == RANGE_EXPR) |
3287 | cursor = TREE_OPERAND (e.index, 1)(*((const_cast<tree*> (tree_operand_check ((e.index), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3287, __FUNCTION__))))); |
3288 | cursor = int_const_binop (PLUS_EXPR, cursor, size_one_nodeglobal_trees[TI_SIZE_ONE]); |
3289 | } |
3290 | if (find_array_ctor_elt (t, max) == -1) |
3291 | return false; |
3292 | goto ok; |
3293 | } |
3294 | else if (cxx_dialect >= cxx20 |
3295 | && TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3295, __FUNCTION__))->typed.type))->base.code) == UNION_TYPE) |
3296 | { |
3297 | if (CONSTRUCTOR_NELTS (t)(vec_safe_length (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3297, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) == 0) |
3298 | /* An initialized union has a constructor element. */ |
3299 | return false; |
3300 | /* And it only initializes one member. */ |
3301 | field = NULL_TREE(tree) __null; |
3302 | } |
3303 | else |
3304 | field = next_subobject_field (TYPE_FIELDS (TREE_TYPE (t))((tree_check3 ((((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3304, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3304, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values)); |
3305 | } |
3306 | else |
3307 | field = NULL_TREE(tree) __null; |
3308 | for (auto &e: CONSTRUCTOR_ELTS (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3308, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)) |
3309 | { |
3310 | /* If VAL is null, we're in the middle of initializing this |
3311 | element. */ |
3312 | if (!reduced_constant_expression_p (e.value)) |
3313 | return false; |
3314 | /* We want to remove initializers for empty fields in a struct to |
3315 | avoid confusing output_constructor. */ |
3316 | if (is_empty_field (e.index) |
3317 | && TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3317, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE) |
3318 | return false; |
3319 | /* Check for non-empty fields between initialized fields when |
3320 | CONSTRUCTOR_NO_CLEARING. */ |
3321 | for (; field && e.index != field; |
3322 | field = next_subobject_field (DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3322, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3322, __FUNCTION__))->common.chain)))) |
3323 | if (!is_really_empty_class (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3323, __FUNCTION__))->typed.type), |
3324 | /*ignore_vptr*/false)) |
3325 | return false; |
3326 | if (field) |
3327 | field = next_subobject_field (DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3327, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3327, __FUNCTION__))->common.chain))); |
3328 | } |
3329 | /* There could be a non-empty field at the end. */ |
3330 | for (; field; field = next_subobject_field (DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3330, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3330, __FUNCTION__))->common.chain)))) |
3331 | if (!is_really_empty_class (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3331, __FUNCTION__))->typed.type), /*ignore_vptr*/false)) |
3332 | return false; |
3333 | ok: |
3334 | if (CONSTRUCTOR_NO_CLEARING (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3334, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) |
3335 | /* All the fields are initialized. */ |
3336 | CONSTRUCTOR_NO_CLEARING (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3336, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag) = false; |
3337 | return true; |
3338 | |
3339 | default: |
3340 | /* FIXME are we calling this too much? */ |
3341 | return initializer_constant_valid_p (t, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3341, __FUNCTION__))->typed.type)) != NULL_TREE(tree) __null; |
3342 | } |
3343 | } |
3344 | |
3345 | /* Some expressions may have constant operands but are not constant |
3346 | themselves, such as 1/0. Call this function to check for that |
3347 | condition. |
3348 | |
3349 | We only call this in places that require an arithmetic constant, not in |
3350 | places where we might have a non-constant expression that can be a |
3351 | component of a constant expression, such as the address of a constexpr |
3352 | variable that might be dereferenced later. */ |
3353 | |
3354 | static bool |
3355 | verify_constant (tree t, bool allow_non_constant, bool *non_constant_p, |
3356 | bool *overflow_p) |
3357 | { |
3358 | if (!*non_constant_p && !reduced_constant_expression_p (t) |
3359 | && t != void_nodeglobal_trees[TI_VOID]) |
3360 | { |
3361 | if (!allow_non_constant) |
3362 | error ("%q+E is not a constant expression", t); |
3363 | *non_constant_p = true; |
3364 | } |
3365 | if (TREE_OVERFLOW_P (t)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (t)->base.code))] == tcc_constant) && ( (tree_class_check ((t), (tcc_constant), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3365, __FUNCTION__))->base.public_flag))) |
3366 | { |
3367 | if (!allow_non_constant) |
3368 | { |
3369 | permerror (input_location, "overflow in constant expression"); |
3370 | /* If we're being permissive (and are in an enforcing |
3371 | context), ignore the overflow. */ |
3372 | if (flag_permissiveglobal_options.x_flag_permissive) |
3373 | return *non_constant_p; |
3374 | } |
3375 | *overflow_p = true; |
3376 | } |
3377 | return *non_constant_p; |
3378 | } |
3379 | |
3380 | /* Check whether the shift operation with code CODE and type TYPE on LHS |
3381 | and RHS is undefined. If it is, give an error with an explanation, |
3382 | and return true; return false otherwise. */ |
3383 | |
3384 | static bool |
3385 | cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx, |
3386 | enum tree_code code, tree type, tree lhs, tree rhs) |
3387 | { |
3388 | if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR) |
3389 | || TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) != INTEGER_CST |
3390 | || TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) != INTEGER_CST) |
3391 | return false; |
3392 | |
3393 | tree lhstype = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3393, __FUNCTION__))->typed.type); |
3394 | unsigned HOST_WIDE_INTlong uprec = TYPE_PRECISION (TREE_TYPE (lhs))((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3394, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3394, __FUNCTION__))->type_common.precision); |
3395 | |
3396 | /* [expr.shift] The behavior is undefined if the right operand |
3397 | is negative, or greater than or equal to the length in bits |
3398 | of the promoted left operand. */ |
3399 | if (tree_int_cst_sgn (rhs) == -1) |
3400 | { |
3401 | if (!ctx->quiet) |
3402 | permerror (loc, "right operand of shift expression %q+E is negative", |
3403 | build2_loc (loc, code, type, lhs, rhs)); |
3404 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); |
3405 | } |
3406 | if (compare_tree_int (rhs, uprec) >= 0) |
3407 | { |
3408 | if (!ctx->quiet) |
3409 | permerror (loc, "right operand of shift expression %q+E is greater " |
3410 | "than or equal to the precision %wu of the left operand", |
3411 | build2_loc (loc, code, type, lhs, rhs), uprec); |
3412 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); |
3413 | } |
3414 | |
3415 | /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...] |
3416 | if E1 has a signed type and non-negative value, and E1x2^E2 is |
3417 | representable in the corresponding unsigned type of the result type, |
3418 | then that value, converted to the result type, is the resulting value; |
3419 | otherwise, the behavior is undefined. |
3420 | For C++20: |
3421 | The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo |
3422 | 2^N, where N is the range exponent of the type of the result. */ |
3423 | if (code == LSHIFT_EXPR |
3424 | && !TYPE_OVERFLOW_WRAPS (lhstype)((((enum tree_code) (lhstype)->base.code) == POINTER_TYPE || ((enum tree_code) (lhstype)->base.code) == REFERENCE_TYPE ) ? global_options.x_flag_wrapv_pointer : ((any_integral_type_check ((lhstype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3424, __FUNCTION__))->base.u.bits.unsigned_flag || global_options .x_flag_wrapv)) |
3425 | && cxx_dialect >= cxx11 |
3426 | && cxx_dialect < cxx20) |
3427 | { |
3428 | if (tree_int_cst_sgn (lhs) == -1) |
3429 | { |
3430 | if (!ctx->quiet) |
3431 | permerror (loc, |
3432 | "left operand of shift expression %q+E is negative", |
3433 | build2_loc (loc, code, type, lhs, rhs)); |
3434 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); |
3435 | } |
3436 | /* For signed x << y the following: |
3437 | (unsigned) x >> ((prec (lhs) - 1) - y) |
3438 | if > 1, is undefined. The right-hand side of this formula |
3439 | is the highest bit of the LHS that can be set (starting from 0), |
3440 | so that the shift doesn't overflow. We then right-shift the LHS |
3441 | to see whether any other bit is set making the original shift |
3442 | undefined -- the result is not representable in the corresponding |
3443 | unsigned type. */ |
3444 | tree t = build_int_cst (unsigned_type_nodeinteger_types[itk_unsigned_int], uprec - 1); |
3445 | 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 ); |
3446 | tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs)fold_convert_loc (((location_t) 0), unsigned_type_for (lhstype ), lhs); |
3447 | t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t)fold_build2_loc (((location_t) 0), RSHIFT_EXPR, ((contains_struct_check ((ulhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3447, __FUNCTION__))->typed.type), ulhs, t ); |
3448 | if (tree_int_cst_lt (integer_one_nodeglobal_trees[TI_INTEGER_ONE], t)) |
3449 | { |
3450 | if (!ctx->quiet) |
3451 | permerror (loc, "shift expression %q+E overflows", |
3452 | build2_loc (loc, code, type, lhs, rhs)); |
3453 | return (!flag_permissiveglobal_options.x_flag_permissive || ctx->quiet); |
3454 | } |
3455 | } |
3456 | return false; |
3457 | } |
3458 | |
3459 | /* Subroutine of cxx_eval_constant_expression. |
3460 | Attempt to reduce the unary expression tree T to a compile time value. |
3461 | If successful, return the value. Otherwise issue a diagnostic |
3462 | and return error_mark_node. */ |
3463 | |
3464 | static tree |
3465 | cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t, |
3466 | bool /*lval*/, |
3467 | bool *non_constant_p, bool *overflow_p) |
3468 | { |
3469 | tree r; |
3470 | tree orig_arg = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3470, __FUNCTION__))))); |
3471 | tree arg = cxx_eval_constant_expression (ctx, orig_arg, vc_prvalue, |
3472 | non_constant_p, overflow_p); |
3473 | VERIFY_CONSTANT (arg)do { if (verify_constant ((arg), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
3474 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); |
3475 | enum tree_code code = TREE_CODE (t)((enum tree_code) (t)->base.code); |
3476 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3476, __FUNCTION__))->typed.type); |
3477 | r = fold_unary_loc (loc, code, type, arg); |
3478 | if (r == NULL_TREE(tree) __null) |
3479 | { |
3480 | if (arg == orig_arg) |
3481 | r = t; |
3482 | else |
3483 | r = build1_loc (loc, code, type, arg); |
3484 | } |
3485 | VERIFY_CONSTANT (r)do { if (verify_constant ((r), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0); |
3486 | return r; |
3487 | } |
3488 | |
3489 | /* Helper function for cxx_eval_binary_expression. Try to optimize |
3490 | original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the |
3491 | generic folding should be used. */ |
3492 | |
3493 | static tree |
3494 | cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t, |
3495 | tree lhs, tree rhs, bool *non_constant_p, |
3496 | bool *overflow_p) |
3497 | { |
3498 | STRIP_NOPS (lhs)(lhs) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((lhs))))); |
3499 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) != ADDR_EXPR) |
3500 | return NULL_TREE(tree) __null; |
3501 | |
3502 | lhs = TREE_OPERAND (lhs, 0)(*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3502, __FUNCTION__))))); |
3503 | |
3504 | /* &A[i] p+ j => &A[i + j] */ |
3505 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == ARRAY_REF |
3506 | && TREE_CODE (TREE_OPERAND (lhs, 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3506, __FUNCTION__))))))->base.code) == INTEGER_CST |
3507 | && TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == INTEGER_CST |
3508 | && TYPE_SIZE_UNIT (TREE_TYPE (lhs))((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3508, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3508, __FUNCTION__))->type_common.size_unit) |
3509 | && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))((enum tree_code) (((tree_class_check ((((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3509, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3509, __FUNCTION__))->type_common.size_unit))->base.code ) == INTEGER_CST) |
3510 | { |
3511 | tree orig_type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3511, __FUNCTION__))->typed.type); |
3512 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); |
3513 | tree type = TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3513, __FUNCTION__))->typed.type); |
3514 | |
3515 | t = fold_convert_loc (loc, ssizetypesizetype_tab[(int) stk_ssizetype], TREE_OPERAND (lhs, 1)(*((const_cast<tree*> (tree_operand_check ((lhs), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3515, __FUNCTION__)))))); |
3516 | tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3516, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3516, __FUNCTION__))->typed.type)); |
3517 | nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue, |
3518 | non_constant_p, overflow_p); |
3519 | if (*non_constant_p) |
3520 | return NULL_TREE(tree) __null; |
3521 | /* Don't fold an out-of-bound access. */ |
3522 | if (!tree_int_cst_le (t, nelts)) |
3523 | return NULL_TREE(tree) __null; |
3524 | rhs = cp_fold_convert (ssizetypesizetype_tab[(int) stk_ssizetype], rhs); |
3525 | /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT. |
3526 | constexpr int A[1]; ... (char *)&A[0] + 1 */ |
3527 | if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetypesizetype_tab[(int) stk_sizetype], |
3528 | rhs, TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3528, __FUNCTION__))->type_common.size_unit)))) |
3529 | return NULL_TREE(tree) __null; |
3530 | /* Make sure to treat the second operand of POINTER_PLUS_EXPR |
3531 | as signed. */ |
3532 | rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetypesizetype_tab[(int) stk_ssizetype], rhs, |
3533 | TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3533, __FUNCTION__))->type_common.size_unit)); |
3534 | t = size_binop_loc (loc, PLUS_EXPR, rhs, t); |
3535 | t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0)(*((const_cast<tree*> (tree_operand_check ((lhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3535, __FUNCTION__))))), |
3536 | t, NULL_TREE(tree) __null, NULL_TREE(tree) __null); |
3537 | t = cp_build_addr_expr (t, tf_warning_or_error); |
3538 | t = cp_fold_convert (orig_type, t); |
3539 | return cxx_eval_constant_expression (ctx, t, vc_prvalue, |
3540 | non_constant_p, overflow_p); |
3541 | } |
3542 | |
3543 | return NULL_TREE(tree) __null; |
3544 | } |
3545 | |
3546 | /* Try to fold expressions like |
3547 | (struct S *) (&a[0].D.2378 + 12) |
3548 | into |
3549 | &MEM <struct T> [(void *)&a + 12B] |
3550 | This is something normally done by gimple_fold_stmt_to_constant_1 |
3551 | on GIMPLE, but is undesirable on GENERIC if we are e.g. going to |
3552 | dereference the address because some details are lost. |
3553 | For pointer comparisons we want such folding though so that |
3554 | match.pd address_compare optimization works. */ |
3555 | |
3556 | static tree |
3557 | cxx_maybe_fold_addr_pointer_plus (tree t) |
3558 | { |
3559 | while (CONVERT_EXPR_P (t)((((enum tree_code) (t)->base.code)) == NOP_EXPR || (((enum tree_code) (t)->base.code)) == CONVERT_EXPR) |
3560 | && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))(((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3560, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3560, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3560, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3560, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
3561 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3561, __FUNCTION__))))); |
3562 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) != POINTER_PLUS_EXPR) |
3563 | return NULL_TREE(tree) __null; |
3564 | tree op0 = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3564, __FUNCTION__))))); |
3565 | tree op1 = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3565, __FUNCTION__))))); |
3566 | if (TREE_CODE (op1)((enum tree_code) (op1)->base.code) != INTEGER_CST) |
3567 | return NULL_TREE(tree) __null; |
3568 | while (CONVERT_EXPR_P (op0)((((enum tree_code) (op0)->base.code)) == NOP_EXPR || (((enum tree_code) (op0)->base.code)) == CONVERT_EXPR) |
3569 | && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))(((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((op0), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3569, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3569, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check (((*((const_cast <tree*> (tree_operand_check ((op0), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3569, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3569, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
3570 | op0 = TREE_OPERAND (op0, 0)(*((const_cast<tree*> (tree_operand_check ((op0), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3570, __FUNCTION__))))); |
3571 | if (TREE_CODE (op0)((enum tree_code) (op0)->base.code) != ADDR_EXPR) |
3572 | return NULL_TREE(tree) __null; |
3573 | op1 = fold_convert (ptr_type_node, op1)fold_convert_loc (((location_t) 0), global_trees[TI_PTR_TYPE] , op1); |
3574 | tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1)fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check ((((contains_struct_check ((op0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3574, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3574, __FUNCTION__))->typed.type), op0, op1 ); |
3575 | return build1_loc (EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)), ADDR_EXPR, TREE_TYPE (op0)((contains_struct_check ((op0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3575, __FUNCTION__))->typed.type), r); |
3576 | } |
3577 | |
3578 | /* Subroutine of cxx_eval_constant_expression. |
3579 | Like cxx_eval_unary_expression, except for binary expressions. */ |
3580 | |
3581 | static tree |
3582 | cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, |
3583 | value_cat lval, |
3584 | bool *non_constant_p, bool *overflow_p) |
3585 | { |
3586 | tree r = NULL_TREE(tree) __null; |
3587 | tree orig_lhs = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3587, __FUNCTION__))))); |
3588 | tree orig_rhs = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3588, __FUNCTION__))))); |
3589 | tree lhs, rhs; |
3590 | lhs = cxx_eval_constant_expression (ctx, orig_lhs, vc_prvalue, |
3591 | non_constant_p, overflow_p); |
3592 | /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer |
3593 | subtraction. */ |
3594 | if (*non_constant_p) |
3595 | return t; |
3596 | rhs = cxx_eval_constant_expression (ctx, orig_rhs, vc_prvalue, |
3597 | non_constant_p, overflow_p); |
3598 | if (*non_constant_p) |
3599 | return t; |
3600 | |
3601 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); |
3602 | enum tree_code code = TREE_CODE (t)((enum tree_code) (t)->base.code); |
3603 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3603, __FUNCTION__))->typed.type); |
3604 | |
3605 | if (code == EQ_EXPR || code == NE_EXPR) |
3606 | { |
3607 | bool is_code_eq = (code == EQ_EXPR); |
3608 | |
3609 | if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == PTRMEM_CST |
3610 | && TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == PTRMEM_CST) |
3611 | { |
3612 | tree lmem = PTRMEM_CST_MEMBER (lhs)(((ptrmem_cst_t)(tree_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3612, __FUNCTION__, (PTRMEM_CST))))->member); |
3613 | tree rmem = PTRMEM_CST_MEMBER (rhs)(((ptrmem_cst_t)(tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3613, __FUNCTION__, (PTRMEM_CST))))->member); |
3614 | bool eq; |
3615 | if (TREE_CODE (lmem)((enum tree_code) (lmem)->base.code) == TREE_CODE (rmem)((enum tree_code) (rmem)->base.code) |
3616 | && TREE_CODE (lmem)((enum tree_code) (lmem)->base.code) == FIELD_DECL |
3617 | && TREE_CODE (DECL_CONTEXT (lmem))((enum tree_code) (((contains_struct_check ((lmem), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3617, __FUNCTION__))->decl_minimal.context))->base.code ) == UNION_TYPE |
3618 | && same_type_p (DECL_CONTEXT (lmem),comptypes ((((contains_struct_check ((lmem), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3618, __FUNCTION__))->decl_minimal.context)), (((contains_struct_check ((rmem), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3619, __FUNCTION__))->decl_minimal.context)), 0) |
3619 | DECL_CONTEXT (rmem))comptypes ((((contains_struct_check ((lmem), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3618, __FUNCTION__))->decl_minimal.context)), (((contains_struct_check ((rmem), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3619, __FUNCTION__))->decl_minimal.context)), 0)) |
3620 | /* If both refer to (possibly different) members of the same union |
3621 | (12.3), they compare equal. */ |
3622 | eq = true; |
3623 | else |
3624 | eq = cp_tree_equal (lhs, rhs); |
3625 | r = constant_boolean_node (eq == is_code_eq, type); |
3626 | } |
3627 | else if ((TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == PTRMEM_CST |
3628 | || TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == PTRMEM_CST) |
3629 | && (null_member_pointer_value_p (lhs) |
3630 | || null_member_pointer_value_p (rhs))) |
3631 | r = constant_boolean_node (!is_code_eq, type); |
3632 | else if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == PTRMEM_CST) |
3633 | lhs = cplus_expand_constant (lhs); |
3634 | else if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == PTRMEM_CST) |
3635 | rhs = cplus_expand_constant (rhs); |
3636 | } |
3637 | if (r == NULL_TREE(tree) __null |
3638 | && TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)] == tcc_comparison |
3639 | && POINTER_TYPE_P (TREE_TYPE (lhs))(((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3639, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3639, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
3640 | { |
3641 | if (tree lhso = cxx_maybe_fold_addr_pointer_plus (lhs)) |
3642 | lhs = fold_convert (TREE_TYPE (lhs), lhso)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3642, __FUNCTION__))->typed.type), lhso); |
3643 | if (tree rhso = cxx_maybe_fold_addr_pointer_plus (rhs)) |
3644 | rhs = fold_convert (TREE_TYPE (rhs), rhso)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3644, __FUNCTION__))->typed.type), rhso); |
3645 | } |
3646 | if (code == POINTER_PLUS_EXPR && !*non_constant_p |
3647 | && integer_zerop (lhs) && !integer_zerop (rhs)) |
3648 | { |
3649 | if (!ctx->quiet) |
3650 | error ("arithmetic involving a null pointer in %qE", lhs); |
3651 | *non_constant_p = true; |
3652 | return t; |
3653 | } |
3654 | else if (code == POINTER_PLUS_EXPR) |
3655 | r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p, |
3656 | overflow_p); |
3657 | else if (code == SPACESHIP_EXPR) |
3658 | { |
3659 | r = genericize_spaceship (loc, type, lhs, rhs); |
3660 | return cxx_eval_constant_expression (ctx, r, lval, non_constant_p, |
3661 | overflow_p); |
3662 | } |
3663 | |
3664 | if (r == NULL_TREE(tree) __null) |
3665 | { |
3666 | if (ctx->manifestly_const_eval == mce_true |
3667 | && (flag_constexpr_fp_exceptglobal_options.x_flag_constexpr_fp_except |
3668 | || TREE_CODE (type)((enum tree_code) (type)->base.code) != REAL_TYPE)) |
3669 | { |
3670 | auto ofcc = make_temp_override (folding_cxx_constexpr, true); |
3671 | r = fold_binary_initializer_loc (loc, code, type, lhs, rhs); |
3672 | } |
3673 | else |
3674 | r = fold_binary_loc (loc, code, type, lhs, rhs); |
3675 | } |
3676 | |
3677 | if (r == NULL_TREE(tree) __null |
3678 | && (code == LSHIFT_EXPR || code == RSHIFT_EXPR) |
3679 | && TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == INTEGER_CST |
3680 | && TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == INTEGER_CST |
3681 | && wi::neg_p (wi::to_wide (rhs))) |
3682 | { |
3683 | /* For diagnostics and -fpermissive emulate previous behavior of |
3684 | handling shifts by negative amount. */ |
3685 | tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3685, __FUNCTION__))->typed.type), rhs); |
3686 | if (nrhs) |
3687 | r = fold_binary_loc (loc, |
3688 | code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR, |
3689 | type, lhs, nrhs); |
3690 | } |
3691 | |
3692 | if (r == NULL_TREE(tree) __null) |
3693 | { |
3694 | if (lhs == orig_lhs && rhs == orig_rhs) |
3695 | r = t; |
3696 | else |
3697 | r = build2_loc (loc, code, type, lhs, rhs); |
3698 | } |
3699 | else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs)) |
3700 | *non_constant_p = true; |
3701 | /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to |
3702 | a local array in a constexpr function. */ |
3703 | bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs))((((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3703, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE ) || (((enum tree_code) (((contains_struct_check ((lhs), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3703, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )); |
3704 | if (!ptr) |
3705 | VERIFY_CONSTANT (r)do { if (verify_constant ((r), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0); |
3706 | return r; |
3707 | } |
3708 | |
3709 | /* Subroutine of cxx_eval_constant_expression. |
3710 | Attempt to evaluate condition expressions. Dead branches are not |
3711 | looked into. */ |
3712 | |
3713 | static tree |
3714 | cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, |
3715 | value_cat lval, |
3716 | bool *non_constant_p, bool *overflow_p, |
3717 | tree *jump_target) |
3718 | { |
3719 | tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3719, __FUNCTION__))))), |
3720 | vc_prvalue, |
3721 | non_constant_p, overflow_p); |
3722 | VERIFY_CONSTANT (val)do { if (verify_constant ((val), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
3723 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == IF_STMT && IF_STMT_CONSTEVAL_P (t)((tree_not_check2 (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3723, __FUNCTION__, (IF_STMT)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3723, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) |
3724 | { |
3725 | /* Evaluate the condition as if it was |
3726 | if (__builtin_is_constant_evaluated ()), i.e. defer it if not |
3727 | ctx->manifestly_const_eval (as sometimes we try to constant evaluate |
3728 | without manifestly_const_eval even expressions or parts thereof which |
3729 | will later be manifestly const_eval evaluated), otherwise fold it to |
3730 | true. */ |
3731 | if (ctx->manifestly_const_eval == mce_unknown) |
3732 | { |
3733 | *non_constant_p = true; |
3734 | return t; |
3735 | } |
3736 | val = constant_boolean_node (ctx->manifestly_const_eval == mce_true, |
3737 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]); |
3738 | } |
3739 | /* Don't VERIFY_CONSTANT the other operands. */ |
3740 | if (integer_zerop (val)) |
3741 | val = TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3741, __FUNCTION__))))); |
3742 | else |
3743 | val = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3743, __FUNCTION__))))); |
3744 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == IF_STMT && !val) |
3745 | val = void_nodeglobal_trees[TI_VOID]; |
3746 | /* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still |
3747 | serve as the initializer for the same object as the outer TARGET_EXPR, |
3748 | as in |
3749 | A a = true ? A{} : A{}; |
3750 | so strip the inner TARGET_EXPR so we don't materialize a temporary. */ |
3751 | if (TREE_CODE (val)((enum tree_code) (val)->base.code) == TARGET_EXPR) |
3752 | val = TARGET_EXPR_INITIAL (val)(*(tree_operand_check_code ((val), (TARGET_EXPR), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3752, __FUNCTION__))); |
3753 | return cxx_eval_constant_expression (ctx, val, lval, non_constant_p, |
3754 | overflow_p, jump_target); |
3755 | } |
3756 | |
3757 | /* Subroutine of cxx_eval_constant_expression. |
3758 | Attempt to evaluate vector condition expressions. Unlike |
3759 | cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal |
3760 | ternary arithmetics operation, where all 3 arguments have to be |
3761 | evaluated as constants and then folding computes the result from |
3762 | them. */ |
3763 | |
3764 | static tree |
3765 | cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t, |
3766 | bool *non_constant_p, bool *overflow_p) |
3767 | { |
3768 | tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3768, __FUNCTION__))))), |
3769 | vc_prvalue, |
3770 | non_constant_p, overflow_p); |
3771 | VERIFY_CONSTANT (arg1)do { if (verify_constant ((arg1), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
3772 | tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3772, __FUNCTION__))))), |
3773 | vc_prvalue, |
3774 | non_constant_p, overflow_p); |
3775 | VERIFY_CONSTANT (arg2)do { if (verify_constant ((arg2), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
3776 | tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3776, __FUNCTION__))))), |
3777 | vc_prvalue, |
3778 | non_constant_p, overflow_p); |
3779 | VERIFY_CONSTANT (arg3)do { if (verify_constant ((arg3), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
3780 | location_t loc = EXPR_LOCATION (t)((((t)) && ((tree_code_type_tmpl <0>::tree_code_type [(int) (((enum tree_code) ((t))->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) ((t))->base.code))]) <= tcc_expression )) ? (t)->exp.locus : ((location_t) 0)); |
3781 | tree type = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3781, __FUNCTION__))->typed.type); |
3782 | tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3); |
3783 | if (r == NULL_TREE(tree) __null) |
3784 | { |
3785 | if (arg1 == TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3785, __FUNCTION__))))) |
3786 | && arg2 == TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3786, __FUNCTION__))))) |
3787 | && arg3 == TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3787, __FUNCTION__)))))) |
3788 | r = t; |
3789 | else |
3790 | r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3); |
3791 | } |
3792 | VERIFY_CONSTANT (r)do { if (verify_constant ((r), ctx->quiet, non_constant_p, overflow_p)) return t; } while (0); |
3793 | return r; |
3794 | } |
3795 | |
3796 | /* Returns less than, equal to, or greater than zero if KEY is found to be |
3797 | less than, to match, or to be greater than the constructor_elt's INDEX. */ |
3798 | |
3799 | static int |
3800 | array_index_cmp (tree key, tree index) |
3801 | { |
3802 | gcc_assert (TREE_CODE (key) == INTEGER_CST)((void)(!(((enum tree_code) (key)->base.code) == INTEGER_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3802, __FUNCTION__), 0 : 0)); |
3803 | |
3804 | switch (TREE_CODE (index)((enum tree_code) (index)->base.code)) |
3805 | { |
3806 | case INTEGER_CST: |
3807 | return tree_int_cst_compare (key, index); |
3808 | case RANGE_EXPR: |
3809 | { |
3810 | tree lo = TREE_OPERAND (index, 0)(*((const_cast<tree*> (tree_operand_check ((index), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3810, __FUNCTION__))))); |
3811 | tree hi = TREE_OPERAND (index, 1)(*((const_cast<tree*> (tree_operand_check ((index), (1) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3811, __FUNCTION__))))); |
3812 | if (tree_int_cst_lt (key, lo)) |
3813 | return -1; |
3814 | else if (tree_int_cst_lt (hi, key)) |
3815 | return 1; |
3816 | else |
3817 | return 0; |
3818 | } |
3819 | default: |
3820 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3820, __FUNCTION__)); |
3821 | } |
3822 | } |
3823 | |
3824 | /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1 |
3825 | if none. If INSERT is true, insert a matching element rather than fail. */ |
3826 | |
3827 | static HOST_WIDE_INTlong |
3828 | find_array_ctor_elt (tree ary, tree dindex, bool insert) |
3829 | { |
3830 | if (tree_int_cst_sgn (dindex) < 0) |
3831 | return -1; |
3832 | |
3833 | unsigned HOST_WIDE_INTlong i = tree_to_uhwi (dindex); |
3834 | vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3834, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
3835 | unsigned HOST_WIDE_INTlong len = vec_safe_length (elts); |
3836 | |
3837 | unsigned HOST_WIDE_INTlong end = len; |
3838 | unsigned HOST_WIDE_INTlong begin = 0; |
3839 | |
3840 | /* If the last element of the CONSTRUCTOR has its own index, we can assume |
3841 | that the same is true of the other elements and index directly. */ |
3842 | if (end > 0) |
3843 | { |
3844 | tree cindex = (*elts)[end - 1].index; |
3845 | if (cindex == NULL_TREE(tree) __null) |
3846 | { |
3847 | /* Verify that if the last index is missing, all indexes |
3848 | are missing. */ |
3849 | if (flag_checkingglobal_options.x_flag_checking) |
3850 | for (unsigned int j = 0; j < len - 1; ++j) |
3851 | gcc_assert ((*elts)[j].index == NULL_TREE)((void)(!((*elts)[j].index == (tree) __null) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3851, __FUNCTION__), 0 : 0)); |
3852 | if (i < end) |
3853 | return i; |
3854 | else |
3855 | { |
3856 | begin = end; |
3857 | if (i == end) |
3858 | /* If the element is to be added right at the end, |
3859 | make sure it is added with cleared index too. */ |
3860 | dindex = NULL_TREE(tree) __null; |
3861 | else if (insert) |
3862 | /* Otherwise, in order not to break the assumption |
3863 | that CONSTRUCTOR either has all indexes or none, |
3864 | we need to add indexes to all elements. */ |
3865 | for (unsigned int j = 0; j < len; ++j) |
3866 | (*elts)[j].index = build_int_cst (TREE_TYPE (dindex)((contains_struct_check ((dindex), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3866, __FUNCTION__))->typed.type), j); |
3867 | } |
3868 | } |
3869 | else if (TREE_CODE (cindex)((enum tree_code) (cindex)->base.code) == INTEGER_CST |
3870 | && compare_tree_int (cindex, end - 1) == 0) |
3871 | { |
3872 | if (i < end) |
3873 | return i; |
3874 | else |
3875 | begin = end; |
3876 | } |
3877 | } |
3878 | |
3879 | /* Otherwise, find a matching index by means of a binary search. */ |
3880 | while (begin != end) |
3881 | { |
3882 | unsigned HOST_WIDE_INTlong middle = (begin + end) / 2; |
3883 | constructor_elt &elt = (*elts)[middle]; |
3884 | tree idx = elt.index; |
3885 | |
3886 | int cmp = array_index_cmp (dindex, idx); |
3887 | if (cmp < 0) |
3888 | end = middle; |
3889 | else if (cmp > 0) |
3890 | begin = middle + 1; |
3891 | else |
3892 | { |
3893 | if (insert && TREE_CODE (idx)((enum tree_code) (idx)->base.code) == RANGE_EXPR) |
3894 | { |
3895 | /* We need to split the range. */ |
3896 | constructor_elt e; |
3897 | tree lo = TREE_OPERAND (idx, 0)(*((const_cast<tree*> (tree_operand_check ((idx), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3897, __FUNCTION__))))); |
3898 | tree hi = TREE_OPERAND (idx, 1)(*((const_cast<tree*> (tree_operand_check ((idx), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3898, __FUNCTION__))))); |
3899 | tree value = elt.value; |
3900 | dindex = fold_convert (sizetype, dindex)fold_convert_loc (((location_t) 0), sizetype_tab[(int) stk_sizetype ], dindex); |
3901 | if (tree_int_cst_lt (lo, dindex)) |
3902 | { |
3903 | /* There are still some lower elts; shorten the range. */ |
3904 | tree new_hi = int_const_binop (MINUS_EXPR, dindex, |
3905 | size_one_nodeglobal_trees[TI_SIZE_ONE]); |
3906 | if (tree_int_cst_equal (lo, new_hi)) |
3907 | /* Only one element left, no longer a range. */ |
3908 | elt.index = lo; |
3909 | else |
3910 | TREE_OPERAND (idx, 1)(*((const_cast<tree*> (tree_operand_check ((idx), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3910, __FUNCTION__))))) = new_hi; |
3911 | /* Append the element we want to insert. */ |
3912 | ++middle; |
3913 | e.index = dindex; |
3914 | e.value = unshare_constructor (value); |
3915 | vec_safe_insert (CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3915, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), middle, e); |
3916 | } |
3917 | else |
3918 | /* No lower elts, the range elt is now ours. */ |
3919 | elt.index = dindex; |
3920 | |
3921 | if (tree_int_cst_lt (dindex, hi)) |
3922 | { |
3923 | /* There are still some higher elts; append a range. */ |
3924 | tree new_lo = int_const_binop (PLUS_EXPR, dindex, |
3925 | size_one_nodeglobal_trees[TI_SIZE_ONE]); |
3926 | if (tree_int_cst_equal (new_lo, hi)) |
3927 | e.index = hi; |
3928 | else |
3929 | e.index = build2 (RANGE_EXPR, sizetypesizetype_tab[(int) stk_sizetype], new_lo, hi); |
3930 | e.value = unshare_constructor (value); |
3931 | vec_safe_insert (CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3931, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), middle + 1, e); |
3932 | } |
3933 | } |
3934 | return middle; |
3935 | } |
3936 | } |
3937 | |
3938 | if (insert) |
3939 | { |
3940 | constructor_elt e = { dindex, NULL_TREE(tree) __null }; |
3941 | vec_safe_insert (CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3941, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), end, e); |
3942 | return end; |
3943 | } |
3944 | |
3945 | return -1; |
3946 | } |
3947 | |
3948 | /* Return a pointer to the constructor_elt of CTOR which matches INDEX. If no |
3949 | matching constructor_elt exists, then add one to CTOR. |
3950 | |
3951 | As an optimization, if POS_HINT is non-negative then it is used as a guess |
3952 | for the (integer) index of the matching constructor_elt within CTOR. */ |
3953 | |
3954 | static constructor_elt * |
3955 | get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1) |
3956 | { |
3957 | /* Check the hint first. */ |
3958 | if (pos_hint >= 0 && (unsigned)pos_hint < CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3958, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) |
3959 | && CONSTRUCTOR_ELT (ctor, pos_hint)(&(*((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3959, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ pos_hint])->index == index) |
3960 | return CONSTRUCTOR_ELT (ctor, pos_hint)(&(*((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3960, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ pos_hint]); |
3961 | |
3962 | tree type = TREE_TYPE (ctor)((contains_struct_check ((ctor), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3962, __FUNCTION__))->typed.type); |
3963 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == VECTOR_TYPE && index == NULL_TREE(tree) __null) |
3964 | { |
3965 | CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (ctor), index, NULL_TREE)do { constructor_elt _ce___ = {index, (tree) __null}; vec_safe_push ((((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3965, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)), _ce___); } while (0); |
3966 | return &CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3966, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)->last(); |
3967 | } |
3968 | else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == ARRAY_TYPE || TREE_CODE (type)((enum tree_code) (type)->base.code) == VECTOR_TYPE) |
3969 | { |
3970 | if (TREE_CODE (index)((enum tree_code) (index)->base.code) == RANGE_EXPR) |
3971 | { |
3972 | /* Support for RANGE_EXPR index lookups is currently limited to |
3973 | accessing an existing element via POS_HINT, or appending a new |
3974 | element to the end of CTOR. ??? Support for other access |
3975 | patterns may also be needed. */ |
3976 | vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3976, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts); |
3977 | if (vec_safe_length (elts)) |
3978 | { |
3979 | tree lo = TREE_OPERAND (index, 0)(*((const_cast<tree*> (tree_operand_check ((index), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3979, __FUNCTION__))))); |
3980 | gcc_assert (array_index_cmp (elts->last().index, lo) < 0)((void)(!(array_index_cmp (elts->last().index, lo) < 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3980, __FUNCTION__), 0 : 0)); |
3981 | } |
3982 | CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE)do { constructor_elt _ce___ = {index, (tree) __null}; vec_safe_push ((elts), _ce___); } while (0); |
3983 | return &elts->last(); |
3984 | } |
3985 | |
3986 | HOST_WIDE_INTlong i = find_array_ctor_elt (ctor, index, /*insert*/true); |
3987 | gcc_assert (i >= 0)((void)(!(i >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3987, __FUNCTION__), 0 : 0)); |
3988 | constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i)(&(*((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3988, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i]); |
3989 | gcc_assert (cep->index == NULL_TREE((void)(!(cep->index == (tree) __null || ((enum tree_code) (cep->index)->base.code) != RANGE_EXPR) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3990, __FUNCTION__), 0 : 0)) |
3990 | || TREE_CODE (cep->index) != RANGE_EXPR)((void)(!(cep->index == (tree) __null || ((enum tree_code) (cep->index)->base.code) != RANGE_EXPR) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3990, __FUNCTION__), 0 : 0)); |
3991 | return cep; |
3992 | } |
3993 | else |
3994 | { |
3995 | gcc_assert (TREE_CODE (index) == FIELD_DECL((void)(!(((enum tree_code) (index)->base.code) == FIELD_DECL && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((index), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__))->decl_minimal.context), ((contains_struct_check ((ctor), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__))->typed.type)))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__), 0 : 0)) |
3996 | && (same_type_ignoring_top_level_qualifiers_p((void)(!(((enum tree_code) (index)->base.code) == FIELD_DECL && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((index), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__))->decl_minimal.context), ((contains_struct_check ((ctor), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__))->typed.type)))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__), 0 : 0)) |
3997 | (DECL_CONTEXT (index), TREE_TYPE (ctor))))((void)(!(((enum tree_code) (index)->base.code) == FIELD_DECL && (same_type_ignoring_top_level_qualifiers_p (((contains_struct_check ((index), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__))->decl_minimal.context), ((contains_struct_check ((ctor), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__))->typed.type)))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 3997, __FUNCTION__), 0 : 0)); |
3998 | |
3999 | /* We must keep the CONSTRUCTOR's ELTS in FIELD order. |
4000 | Usually we meet initializers in that order, but it is |
4001 | possible for base types to be placed not in program |
4002 | order. */ |
4003 | tree fields = TYPE_FIELDS (DECL_CONTEXT (index))((tree_check3 ((((contains_struct_check ((index), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4003, __FUNCTION__))->decl_minimal.context)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4003, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); |
4004 | unsigned HOST_WIDE_INTlong idx = 0; |
4005 | constructor_elt *cep = NULL__null; |
4006 | |
4007 | /* Check if we're changing the active member of a union. */ |
4008 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == UNION_TYPE && CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4008, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) |
4009 | && CONSTRUCTOR_ELT (ctor, 0)(&(*((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4009, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0])->index != index) |
4010 | vec_safe_truncate (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4010, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), 0); |
4011 | /* If the bit offset of INDEX is larger than that of the last |
4012 | constructor_elt, then we can just immediately append a new |
4013 | constructor_elt to the end of CTOR. */ |
4014 | else if (CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4014, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) |
4015 | && tree_int_cst_compare (bit_position (index), |
4016 | bit_position (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4016, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts) |
4017 | ->last().index)) > 0) |
4018 | { |
4019 | idx = CONSTRUCTOR_NELTS (ctor)(vec_safe_length (((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4019, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))); |
4020 | goto insert; |
4021 | } |
4022 | |
4023 | /* Otherwise, we need to iterate over CTOR to find or insert INDEX |
4024 | appropriately. */ |
4025 | |
4026 | for (; vec_safe_iterate (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4026, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), idx, &cep); |
4027 | idx++, fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4027, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4027, __FUNCTION__))->common.chain))) |
4028 | { |
4029 | if (index == cep->index) |
4030 | goto found; |
4031 | |
4032 | /* The field we're initializing must be on the field |
4033 | list. Look to see if it is present before the |
4034 | field the current ELT initializes. */ |
4035 | for (; fields != cep->index; fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4035, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4035, __FUNCTION__))->common.chain))) |
4036 | if (index == fields) |
4037 | goto insert; |
4038 | } |
4039 | /* We fell off the end of the CONSTRUCTOR, so insert a new |
4040 | entry at the end. */ |
4041 | |
4042 | insert: |
4043 | { |
4044 | constructor_elt ce = { index, NULL_TREE(tree) __null }; |
4045 | |
4046 | vec_safe_insert (CONSTRUCTOR_ELTS (ctor)((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4046, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts), idx, ce); |
4047 | cep = CONSTRUCTOR_ELT (ctor, idx)(&(*((tree_check ((ctor), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4047, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ idx]); |
4048 | } |
4049 | found:; |
4050 | |
4051 | return cep; |
4052 | } |
4053 | } |
4054 | |
4055 | /* Under the control of CTX, issue a detailed diagnostic for |
4056 | an out-of-bounds subscript INDEX into the expression ARRAY. */ |
4057 | |
4058 | static void |
4059 | diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree index) |
4060 | { |
4061 | if (!ctx->quiet) |
4062 | { |
4063 | tree arraytype = TREE_TYPE (array)((contains_struct_check ((array), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4063, __FUNCTION__))->typed.type); |
4064 | |
4065 | /* Convert the unsigned array subscript to a signed integer to avoid |
4066 | printing huge numbers for small negative values. */ |
4067 | tree sidx = fold_convert (ssizetype, index)fold_convert_loc (((location_t) 0), sizetype_tab[(int) stk_ssizetype ], index); |
4068 | STRIP_ANY_LOCATION_WRAPPER (array)(array) = tree_strip_any_location_wrapper ((const_cast<union tree_node *> (((array))))); |
4069 | if (DECL_P (array)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (array)->base.code))] == tcc_declaration)) |
4070 | { |
4071 | if (TYPE_DOMAIN (arraytype)((tree_check ((arraytype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4071, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )) |
4072 | error_at (loc, "array subscript value %qE is outside the bounds " |
4073 | "of array %qD of type %qT", sidx, array, arraytype); |
4074 | else |
4075 | error_at (loc, "nonzero array subscript %qE is used with array %qD of " |
4076 | "type %qT with unknown bounds", sidx, array, arraytype); |
4077 | inform (DECL_SOURCE_LOCATION (array)((contains_struct_check ((array), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4077, __FUNCTION__))->decl_minimal.locus), "declared here"); |
4078 | } |
4079 | else if (TYPE_DOMAIN (arraytype)((tree_check ((arraytype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4079, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )) |
4080 | error_at (loc, "array subscript value %qE is outside the bounds " |
4081 | "of array type %qT", sidx, arraytype); |
4082 | else |
4083 | error_at (loc, "nonzero array subscript %qE is used with array of type %qT " |
4084 | "with unknown bounds", sidx, arraytype); |
4085 | } |
4086 | } |
4087 | |
4088 | /* Return the number of elements for TYPE (which is an ARRAY_TYPE or |
4089 | a VECTOR_TYPE). */ |
4090 | |
4091 | static tree |
4092 | get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type, |
4093 | bool *non_constant_p, bool *overflow_p) |
4094 | { |
4095 | tree nelts; |
4096 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == ARRAY_TYPE) |
4097 | { |
4098 | if (TYPE_DOMAIN (type)((tree_check ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4098, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values )) |
4099 | nelts = array_type_nelts_top (type); |
4100 | else |
4101 | nelts = size_zero_nodeglobal_trees[TI_SIZE_ZERO]; |
4102 | } |
4103 | else if (VECTOR_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE)) |
4104 | nelts = size_int (TYPE_VECTOR_SUBPARTS (type))size_int_kind (TYPE_VECTOR_SUBPARTS (type), stk_sizetype); |
4105 | else |
4106 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4106, __FUNCTION__)); |
4107 | |
4108 | /* For VLAs, the number of elements won't be an integer constant. */ |
4109 | nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue, |
4110 | non_constant_p, overflow_p); |
4111 | return nelts; |
4112 | } |
4113 | |
4114 | /* Extract element INDEX consisting of CHARS_PER_ELT chars from |
4115 | STRING_CST STRING. */ |
4116 | |
4117 | static tree |
4118 | extract_string_elt (tree string, unsigned chars_per_elt, unsigned index) |
4119 | { |
4120 | tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string))((contains_struct_check ((((contains_struct_check ((string), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4120, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4120, __FUNCTION__))->typed.type)); |
4121 | tree r; |
4122 | |
4123 | if (chars_per_elt == 1) |
4124 | r = build_int_cst (type, TREE_STRING_POINTER (string)((const char *)((tree_check ((string), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4124, __FUNCTION__, (STRING_CST)))->string.str))[index]); |
4125 | else |
4126 | { |
4127 | const unsigned char *ptr |
4128 | = ((const unsigned char *)TREE_STRING_POINTER (string)((const char *)((tree_check ((string), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4128, __FUNCTION__, (STRING_CST)))->string.str)) |
4129 | + index * chars_per_elt); |
4130 | r = native_interpret_expr (type, ptr, chars_per_elt); |
4131 | } |
4132 | return r; |
4133 | } |
4134 | |
4135 | /* Subroutine of cxx_eval_array_reference. T is an ARRAY_REF; evaluate the |
4136 | subscript, diagnose any problems with it, and return the result. */ |
4137 | |
4138 | static tree |
4139 | eval_and_check_array_index (const constexpr_ctx *ctx, |
4140 | tree t, bool allow_one_past, |
4141 | bool *non_constant_p, bool *overflow_p) |
4142 | { |
4143 | location_t loc = cp_expr_loc_or_input_loc (t); |
4144 | tree ary = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4144, __FUNCTION__))))); |
4145 | t = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4145, __FUNCTION__))))); |
4146 | tree index = cxx_eval_constant_expression (ctx, t, vc_prvalue, |
4147 | non_constant_p, overflow_p); |
4148 | VERIFY_CONSTANT (index)do { if (verify_constant ((index), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
4149 | |
4150 | if (!tree_fits_shwi_p (index) |
4151 | || tree_int_cst_sgn (index) < 0) |
4152 | { |
4153 | diag_array_subscript (loc, ctx, ary, index); |
4154 | *non_constant_p = true; |
4155 | return t; |
4156 | } |
4157 | |
4158 | tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary)((contains_struct_check ((ary), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4158, __FUNCTION__))->typed.type), non_constant_p, |
4159 | overflow_p); |
4160 | VERIFY_CONSTANT (nelts)do { if (verify_constant ((nelts), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
4161 | if (allow_one_past |
4162 | ? !tree_int_cst_le (index, nelts) |
4163 | : !tree_int_cst_lt (index, nelts)) |
4164 | { |
4165 | diag_array_subscript (loc, ctx, ary, index); |
4166 | *non_constant_p = true; |
4167 | return t; |
4168 | } |
4169 | |
4170 | return index; |
4171 | } |
4172 | |
4173 | /* Subroutine of cxx_eval_constant_expression. |
4174 | Attempt to reduce a reference to an array slot. */ |
4175 | |
4176 | static tree |
4177 | cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, |
4178 | value_cat lval, |
4179 | bool *non_constant_p, bool *overflow_p) |
4180 | { |
4181 | tree oldary = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4181, __FUNCTION__))))); |
4182 | tree ary = cxx_eval_constant_expression (ctx, oldary, |
4183 | lval, |
4184 | non_constant_p, overflow_p); |
4185 | if (*non_constant_p) |
4186 | return t; |
4187 | if (!lval |
4188 | && TREE_CODE (ary)((enum tree_code) (ary)->base.code) == VIEW_CONVERT_EXPR |
4189 | && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))(((enum tree_code) (((contains_struct_check (((*((const_cast< tree*> (tree_operand_check ((ary), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4189, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4189, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE ) |
4190 | && TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4190, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4190, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4190, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4190, __FUNCTION__))->typed.type)) |
4191 | ary = TREE_OPERAND (ary, 0)(*((const_cast<tree*> (tree_operand_check ((ary), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4191, __FUNCTION__))))); |
4192 | |
4193 | tree oldidx = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4193, __FUNCTION__))))); |
4194 | tree index = eval_and_check_array_index (ctx, t, lval, |
4195 | non_constant_p, overflow_p); |
4196 | if (*non_constant_p) |
4197 | return t; |
4198 | |
4199 | if (lval && ary == oldary && index == oldidx) |
4200 | return t; |
4201 | else if (lval == vc_discard) |
4202 | return t; |
4203 | else if (lval) |
4204 | return build4 (ARRAY_REF, TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4204, __FUNCTION__))->typed.type), ary, index, NULL__null, NULL__null); |
4205 | |
4206 | unsigned len = 0, elem_nchars = 1; |
4207 | tree elem_type = TREE_TYPE (TREE_TYPE (ary))((contains_struct_check ((((contains_struct_check ((ary), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4207, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4207, __FUNCTION__))->typed.type); |
4208 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR) |
4209 | len = CONSTRUCTOR_NELTS (ary)(vec_safe_length (((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4209, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))); |
4210 | else if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == STRING_CST) |
4211 | { |
4212 | elem_nchars = (TYPE_PRECISION (elem_type)((tree_class_check ((elem_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4212, __FUNCTION__))->type_common.precision) |
4213 | / TYPE_PRECISION (char_type_node)((tree_class_check ((integer_types[itk_char]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4213, __FUNCTION__))->type_common.precision)); |
4214 | len = (unsigned) TREE_STRING_LENGTH (ary)((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4214, __FUNCTION__, (STRING_CST)))->string.length) / elem_nchars; |
4215 | } |
4216 | else if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == VECTOR_CST) |
4217 | /* We don't create variable-length VECTOR_CSTs. */ |
4218 | len = VECTOR_CST_NELTS (ary)(TYPE_VECTOR_SUBPARTS (((contains_struct_check ((ary), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4218, __FUNCTION__))->typed.type))).to_constant (); |
4219 | else |
4220 | { |
4221 | /* We can't do anything with other tree codes, so use |
4222 | VERIFY_CONSTANT to complain and fail. */ |
4223 | VERIFY_CONSTANT (ary)do { if (verify_constant ((ary), ctx->quiet, non_constant_p , overflow_p)) return t; } while (0); |
4224 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4224, __FUNCTION__)); |
4225 | } |
4226 | |
4227 | bool found; |
4228 | HOST_WIDE_INTlong i = 0; |
4229 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR) |
4230 | { |
4231 | HOST_WIDE_INTlong ix = find_array_ctor_elt (ary, index); |
4232 | found = (ix >= 0); |
4233 | if (found) |
4234 | i = ix; |
4235 | } |
4236 | else |
4237 | { |
4238 | i = tree_to_shwi (index); |
4239 | found = (i < len); |
4240 | } |
4241 | |
4242 | if (found) |
4243 | { |
4244 | tree r; |
4245 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR) |
4246 | r = (*CONSTRUCTOR_ELTS (ary)((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4246, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[i].value; |
4247 | else if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == VECTOR_CST) |
4248 | r = VECTOR_CST_ELT (ary, i)vector_cst_elt (ary, i); |
4249 | else |
4250 | r = extract_string_elt (ary, elem_nchars, i); |
4251 | |
4252 | if (r) |
4253 | /* Don't VERIFY_CONSTANT here. */ |
4254 | return r; |
4255 | |
4256 | /* Otherwise the element doesn't have a value yet. */ |
4257 | } |
4258 | |
4259 | /* Not found. */ |
4260 | |
4261 | if (TREE_CODE (ary)((enum tree_code) (ary)->base.code) == CONSTRUCTOR |
4262 | && CONSTRUCTOR_NO_CLEARING (ary)((tree_check ((ary), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4262, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) |
4263 | { |
4264 | /* 'ary' is part of the aggregate initializer we're currently |
4265 | building; if there's no initializer for this element yet, |
4266 | that's an error. */ |
4267 | if (!ctx->quiet) |
4268 | error ("accessing uninitialized array element"); |
4269 | *non_constant_p = true; |
4270 | return t; |
4271 | } |
4272 | |
4273 | /* If it's within the array bounds but doesn't have an explicit |
4274 | initializer, it's initialized from {}. But use build_value_init |
4275 | directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */ |
4276 | tree val; |
4277 | constexpr_ctx new_ctx; |
4278 | if (is_really_empty_class (elem_type, /*ignore_vptr*/false)) |
4279 | return build_constructor (elem_type, NULL__null); |
4280 | else 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4280, __FUNCTION__))->type_common.lang_flag_5)) && (((tree_class_check ((elem_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4280, __FUNCTION__))->type_common.size) != (tree) __null ) && !((((tree_class_check ((elem_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4280, __FUNCTION__))->type_with_lang_specific.lang_specific ))->non_aggregate)))) |
4281 | { |
4282 | tree empty_ctor = build_constructor (init_list_type_nodecp_global_trees[CPTI_INIT_LIST_TYPE], NULL__null); |
4283 | val = digest_init (elem_type, empty_ctor, tf_warning_or_error); |
4284 | } |
4285 | else |
4286 | val = build_value_init (elem_type, tf_warning_or_error); |
4287 | |
4288 | if (!SCALAR_TYPE_P (elem_type)((((enum tree_code) (elem_type)->base.code) == OFFSET_TYPE ) || ((enum tree_code) (elem_type)->base.code) == ENUMERAL_TYPE || ((((enum tree_code) (elem_type)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (elem_type)->base.code) == INTEGER_TYPE ) || ((enum tree_code) (elem_type)->base.code) == REAL_TYPE || ((enum tree_code) (elem_type)->base.code) == COMPLEX_TYPE ) || (((enum tree_code) (elem_type)->base.code) == POINTER_TYPE ) || (((enum tree_code) (elem_type)->base.code) == RECORD_TYPE && (((tree_class_check (((tree_check ((elem_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4288, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4288, __FUNCTION__))->type_common.lang_flag_2))) || (((enum tree_code) (elem_type)->base.code) == NULLPTR_TYPE))) |
4289 | { |
4290 | new_ctx = *ctx; |
4291 | new_ctx.ctor = build_constructor (elem_type, NULL__null); |
4292 | ctx = &new_ctx; |
4293 | } |
4294 | t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p, |
4295 | overflow_p); |
4296 | if (!SCALAR_TYPE_P (elem_type)((((enum tree_code) (elem_type)->base.code) == OFFSET_TYPE ) || ((enum tree_code) (elem_type)->base.code) == ENUMERAL_TYPE || ((((enum tree_code) (elem_type)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (elem_type)->base.code) == INTEGER_TYPE ) || ((enum tree_code) (elem_type)->base.code) == REAL_TYPE || ((enum tree_code) (elem_type)->base.code) == COMPLEX_TYPE ) || (((enum tree_code) (elem_type)->base.code) == POINTER_TYPE ) || (((enum tree_code) (elem_type)->base.code) == RECORD_TYPE && (((tree_class_check (((tree_check ((elem_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4296, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4296, __FUNCTION__))->type_common.lang_flag_2))) || (((enum tree_code) (elem_type)->base.code) == NULLPTR_TYPE)) && t != ctx->ctor) |
4297 | free_constructor (ctx->ctor); |
4298 | return t; |
4299 | } |
4300 | |
4301 | /* Subroutine of cxx_eval_constant_expression. |
4302 | Attempt to reduce a field access of a value of class type. */ |
4303 | |
4304 | static tree |
4305 | cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, |
4306 | value_cat lval, |
4307 | bool *non_constant_p, bool *overflow_p) |
4308 | { |
4309 | unsigned HOST_WIDE_INTlong i; |
4310 | tree field; |
4311 | tree value; |
4312 | tree part = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4312, __FUNCTION__))))); |
4313 | tree orig_whole = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4313, __FUNCTION__))))); |
4314 | tree whole = cxx_eval_constant_expression (ctx, orig_whole, |
4315 | lval, |
4316 | non_constant_p, overflow_p); |
4317 | if (*non_constant_p) |
4318 | return t; |
4319 | if (INDIRECT_REF_P (whole)(((enum tree_code) (whole)->base.code) == INDIRECT_REF) |
4320 | && integer_zerop (TREE_OPERAND (whole, 0)(*((const_cast<tree*> (tree_operand_check ((whole), (0) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4320, __FUNCTION__))))))) |
4321 | { |
4322 | if (!ctx->quiet) |
4323 | error ("dereferencing a null pointer in %qE", orig_whole); |
4324 | *non_constant_p = true; |
4325 | return t; |
4326 | } |
4327 | |
4328 | if (TREE_CODE (whole)((enum tree_code) (whole)->base.code) == PTRMEM_CST) |
4329 | whole = cplus_expand_constant (whole); |
4330 | if (whole == orig_whole) |
4331 | return t; |
4332 | if (lval == vc_discard) |
4333 | return t; |
4334 | if (lval) |
4335 | return fold_build3 (COMPONENT_REF, TREE_TYPE (t),fold_build3_loc (((location_t) 0), COMPONENT_REF, ((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4335, __FUNCTION__))->typed.type), whole, part, (tree) __null ) |
4336 | whole, part, NULL_TREE)fold_build3_loc (((location_t) 0), COMPONENT_REF, ((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4335, __FUNCTION__))->typed.type), whole, part, (tree) __null ); |
4337 | /* Don't VERIFY_CONSTANT here; we only want to check that we got a |
4338 | CONSTRUCTOR. */ |
4339 | if (TREE_CODE (whole)((enum tree_code) (whole)->base.code) != CONSTRUCTOR) |
4340 | { |
4341 | if (!ctx->quiet) |
4342 | error ("%qE is not a constant expression", orig_whole); |
4343 | *non_constant_p = true; |
4344 | return t; |
4345 | } |
4346 | if ((cxx_dialect < cxx14 || CONSTRUCTOR_MUTABLE_POISON (whole)(((tree_not_check2 (((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4346, __FUNCTION__, (CONSTRUCTOR)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4346, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2))) |
4347 | && DECL_MUTABLE_P (part)(((contains_struct_check (((tree_check ((part), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4347, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4347, __FUNCTION__))->decl_common.lang_flag_0))) |
4348 | { |
4349 | if (!ctx->quiet) |
4350 | error ("mutable %qD is not usable in a constant expression", part); |
4351 | *non_constant_p = true; |
4352 | return t; |
4353 | } |
4354 | bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole))(((enum tree_code) (((contains_struct_check ((whole), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4354, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && (((tree_class_check (((tree_check ((((contains_struct_check ((whole), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4354, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4354, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4354, __FUNCTION__))->type_common.lang_flag_2))); |
4355 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)for (i = 0; (i >= vec_safe_length (((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4355, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : (((void) (value = (*((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4355, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].value)), (field = (*((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4355, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].index), true); (i)++) |
4356 | { |
4357 | /* Use name match for PMF fields, as a variant will have a |
4358 | different FIELD_DECL with a different type. */ |
4359 | if (pmf ? DECL_NAME (field)((contains_struct_check ((field), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4359, __FUNCTION__))->decl_minimal.name) == DECL_NAME (part)((contains_struct_check ((part), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4359, __FUNCTION__))->decl_minimal.name) |
4360 | : field == part) |
4361 | { |
4362 | if (value) |
4363 | { |
4364 | STRIP_ANY_LOCATION_WRAPPER (value)(value) = tree_strip_any_location_wrapper ((const_cast<union tree_node *> (((value))))); |
4365 | return value; |
4366 | } |
4367 | else |
4368 | /* We're in the middle of initializing it. */ |
4369 | break; |
4370 | } |
4371 | } |
4372 | if (TREE_CODE (TREE_TYPE (whole))((enum tree_code) (((contains_struct_check ((whole), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4372, __FUNCTION__))->typed.type))->base.code) == UNION_TYPE |
4373 | && CONSTRUCTOR_NELTS (whole)(vec_safe_length (((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4373, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) > 0) |
4374 | { |
4375 | /* DR 1188 says we don't have to deal with this. */ |
4376 | if (!ctx->quiet) |
4377 | { |
4378 | constructor_elt *cep = CONSTRUCTOR_ELT (whole, 0)(&(*((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4378, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ 0]); |
4379 | if (cep->value == NULL_TREE(tree) __null) |
4380 | error ("accessing uninitialized member %qD", part); |
4381 | else |
4382 | error ("accessing %qD member instead of initialized %qD member in " |
4383 | "constant expression", part, cep->index); |
4384 | } |
4385 | *non_constant_p = true; |
4386 | return t; |
4387 | } |
4388 | |
4389 | /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty |
4390 | classes never get represented; throw together a value now. */ |
4391 | if (is_really_empty_class (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4391, __FUNCTION__))->typed.type), /*ignore_vptr*/false)) |
4392 | return build_constructor (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4392, __FUNCTION__))->typed.type), NULL__null); |
4393 | |
4394 | gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)))((void)(!(((contains_struct_check ((part), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4394, __FUNCTION__))->decl_minimal.context) == ((tree_class_check ((((contains_struct_check ((whole), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4394, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4394, __FUNCTION__))->type_common.main_variant)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4394, __FUNCTION__), 0 : 0)); |
4395 | |
4396 | if (CONSTRUCTOR_NO_CLEARING (whole)((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4396, __FUNCTION__, (CONSTRUCTOR)))->base.public_flag)) |
4397 | { |
4398 | /* 'whole' is part of the aggregate initializer we're currently |
4399 | building; if there's no initializer for this member yet, that's an |
4400 | error. */ |
4401 | if (!ctx->quiet) |
4402 | error ("accessing uninitialized member %qD", part); |
4403 | *non_constant_p = true; |
4404 | return t; |
4405 | } |
4406 | |
4407 | /* If there's no explicit init for this field, it's value-initialized. */ |
4408 | value = build_value_init (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4408, __FUNCTION__))->typed.type), tf_warning_or_error); |
4409 | return cxx_eval_constant_expression (ctx, value, |
4410 | lval, |
4411 | non_constant_p, overflow_p); |
4412 | } |
4413 | |
4414 | /* Subroutine of cxx_eval_constant_expression. |
4415 | Attempt to reduce a field access of a value of class type that is |
4416 | expressed as a BIT_FIELD_REF. */ |
4417 | |
4418 | static tree |
4419 | cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t, |
4420 | value_cat lval, |
4421 | bool *non_constant_p, bool *overflow_p) |
4422 | { |
4423 | tree orig_whole = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4423, __FUNCTION__))))); |
4424 | tree retval, fldval, utype, mask; |
4425 | bool fld_seen = false; |
4426 | HOST_WIDE_INTlong istart, isize; |
4427 | tree whole = cxx_eval_constant_expression (ctx, orig_whole, |
4428 | lval, |
4429 | non_constant_p, overflow_p); |
4430 | tree start, field, value; |
4431 | unsigned HOST_WIDE_INTlong i; |
4432 | |
4433 | if (whole == orig_whole) |
4434 | return t; |
4435 | /* Don't VERIFY_CONSTANT here; we only want to check that we got a |
4436 | CONSTRUCTOR. */ |
4437 | if (!*non_constant_p |
4438 | && TREE_CODE (whole)((enum tree_code) (whole)->base.code) != VECTOR_CST |
4439 | && TREE_CODE (whole)((enum tree_code) (whole)->base.code) != CONSTRUCTOR) |
4440 | { |
4441 | if (!ctx->quiet) |
4442 | error ("%qE is not a constant expression", orig_whole); |
4443 | *non_constant_p = true; |
4444 | } |
4445 | if (*non_constant_p) |
4446 | return t; |
4447 | |
4448 | if (TREE_CODE (whole)((enum tree_code) (whole)->base.code) == VECTOR_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t))(((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4448, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((t), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4448, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((t), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4448, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE )) |
4449 | { |
4450 | if (tree r = fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,fold_ternary_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4450, __FUNCTION__))->typed.type), whole, (*((const_cast <tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4451, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4451, __FUNCTION__)))))) |
4451 | TREE_OPERAND (t, 1), TREE_OPERAND (t, 2))fold_ternary_loc (((location_t) 0), BIT_FIELD_REF, ((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4450, __FUNCTION__))->typed.type), whole, (*((const_cast <tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4451, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4451, __FUNCTION__))))))) |
4452 | return r; |
4453 | if (!ctx->quiet) |
4454 | error ("%qE is not a constant expression", orig_whole); |
4455 | *non_constant_p = true; |
4456 | return t; |
4457 | } |
4458 | |
4459 | start = TREE_OPERAND (t, 2)(*((const_cast<tree*> (tree_operand_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4459, __FUNCTION__))))); |
4460 | istart = tree_to_shwi (start); |
4461 | isize = tree_to_shwi (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4461, __FUNCTION__)))))); |
4462 | utype = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4462, __FUNCTION__))->typed.type); |
4463 | if (!TYPE_UNSIGNED (utype)((tree_class_check ((utype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4463, __FUNCTION__))->base.u.bits.unsigned_flag)) |
4464 | utype = build_nonstandard_integer_type (TYPE_PRECISION (utype)((tree_class_check ((utype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4464, __FUNCTION__))->type_common.precision), 1); |
4465 | retval = build_int_cst (utype, 0); |
4466 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)for (i = 0; (i >= vec_safe_length (((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4466, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : (((void) (value = (*((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4466, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].value)), (field = (*((tree_check ((whole), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4466, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].index), true); (i)++) |
4467 | { |
4468 | tree bitpos = bit_position (field); |
4469 | STRIP_ANY_LOCATION_WRAPPER (value)(value) = tree_strip_any_location_wrapper ((const_cast<union tree_node *> (((value))))); |
4470 | if (bitpos == start && DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4470, __FUNCTION__))->decl_common.size) == TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4470, __FUNCTION__)))))) |
4471 | return value; |
4472 | if (TREE_CODE (TREE_TYPE (field))((enum tree_code) (((contains_struct_check ((field), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4472, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE |
4473 | && TREE_CODE (value)((enum tree_code) (value)->base.code) == INTEGER_CST |
4474 | && tree_fits_shwi_p (bitpos) |
4475 | && tree_fits_shwi_p (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4475, __FUNCTION__))->decl_common.size))) |
4476 | { |
4477 | HOST_WIDE_INTlong bit = tree_to_shwi (bitpos); |
4478 | HOST_WIDE_INTlong sz = tree_to_shwi (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4478, __FUNCTION__))->decl_common.size)); |
4479 | HOST_WIDE_INTlong shift; |
4480 | if (bit >= istart && bit + sz <= istart + isize) |
4481 | { |
4482 | fldval = fold_convert (utype, value)fold_convert_loc (((location_t) 0), utype, value); |
4483 | mask = build_int_cst_type (utype, -1); |
4484 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4485, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ) |
4485 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4485, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ); |
4486 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4487, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ) |
4487 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4487, __FUNCTION__))->type_common.precision) - sz, stk_sizetype ) ); |
4488 | fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask)fold_build2_loc (((location_t) 0), BIT_AND_EXPR, utype, fldval , mask ); |
4489 | shift = bit - istart; |
4490 | if (BYTES_BIG_ENDIAN0) |
4491 | shift = TYPE_PRECISION (utype)((tree_class_check ((utype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4491, __FUNCTION__))->type_common.precision) - shift - sz; |
4492 | fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,fold_build2_loc (((location_t) 0), LSHIFT_EXPR, utype, fldval , size_int_kind (shift, stk_sizetype) ) |
4493 | size_int (shift))fold_build2_loc (((location_t) 0), LSHIFT_EXPR, utype, fldval , size_int_kind (shift, stk_sizetype) ); |
4494 | retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval)fold_build2_loc (((location_t) 0), BIT_IOR_EXPR, utype, retval , fldval ); |
4495 | fld_seen = true; |
4496 | } |
4497 | } |
4498 | } |
4499 | if (fld_seen) |
4500 | return fold_convert (TREE_TYPE (t), retval)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4500, __FUNCTION__))->typed.type), retval); |
4501 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4501, __FUNCTION__)); |
4502 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4503 | } |
4504 | |
4505 | /* Helper for cxx_eval_bit_cast. |
4506 | Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From |
4507 | types and types of all subobjects have is_union_v<T>, is_pointer_v<T>, |
4508 | is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static |
4509 | data members of reference type. */ |
4510 | |
4511 | static bool |
4512 | check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type, |
4513 | tree orig_type) |
4514 | { |
4515 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == UNION_TYPE) |
4516 | { |
4517 | if (!ctx->quiet) |
4518 | { |
4519 | if (type == orig_type) |
4520 | error_at (loc, "%qs is not a constant expression because %qT is " |
4521 | "a union type", "__builtin_bit_cast", type); |
4522 | else |
4523 | error_at (loc, "%qs is not a constant expression because %qT " |
4524 | "contains a union type", "__builtin_bit_cast", |
4525 | orig_type); |
4526 | } |
4527 | return true; |
4528 | } |
4529 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == POINTER_TYPE) |
4530 | { |
4531 | if (!ctx->quiet) |
4532 | { |
4533 | if (type == orig_type) |
4534 | error_at (loc, "%qs is not a constant expression because %qT is " |
4535 | "a pointer type", "__builtin_bit_cast", type); |
4536 | else |
4537 | error_at (loc, "%qs is not a constant expression because %qT " |
4538 | "contains a pointer type", "__builtin_bit_cast", |
4539 | orig_type); |
4540 | } |
4541 | return true; |
4542 | } |
4543 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == REFERENCE_TYPE) |
4544 | { |
4545 | if (!ctx->quiet) |
4546 | { |
4547 | if (type == orig_type) |
4548 | error_at (loc, "%qs is not a constant expression because %qT is " |
4549 | "a reference type", "__builtin_bit_cast", type); |
4550 | else |
4551 | error_at (loc, "%qs is not a constant expression because %qT " |
4552 | "contains a reference type", "__builtin_bit_cast", |
4553 | orig_type); |
4554 | } |
4555 | return true; |
4556 | } |
4557 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4557, __FUNCTION__, (RECORD_TYPE)))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4557, __FUNCTION__))->type_common.lang_flag_2))))) |
4558 | { |
4559 | if (!ctx->quiet) |
4560 | { |
4561 | if (type == orig_type) |
4562 | error_at (loc, "%qs is not a constant expression because %qT is " |
4563 | "a pointer to member type", "__builtin_bit_cast", |
4564 | type); |
4565 | else |
4566 | error_at (loc, "%qs is not a constant expression because %qT " |
4567 | "contains a pointer to member type", |
4568 | "__builtin_bit_cast", orig_type); |
4569 | } |
4570 | return true; |
4571 | } |
4572 | if (TYPE_VOLATILE (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4572, __FUNCTION__))->base.volatile_flag)) |
4573 | { |
4574 | if (!ctx->quiet) |
4575 | { |
4576 | if (type == orig_type) |
4577 | error_at (loc, "%qs is not a constant expression because %qT is " |
4578 | "volatile", "__builtin_bit_cast", type); |
4579 | else |
4580 | error_at (loc, "%qs is not a constant expression because %qT " |
4581 | "contains a volatile subobject", |
4582 | "__builtin_bit_cast", orig_type); |
4583 | } |
4584 | return true; |
4585 | } |
4586 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE) |
4587 | for (tree field = TYPE_FIELDS (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4587, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4587, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4587, __FUNCTION__))->common.chain))) |
4588 | if (TREE_CODE (field)((enum tree_code) (field)->base.code) == FIELD_DECL |
4589 | && check_bit_cast_type (ctx, loc, TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4589, __FUNCTION__))->typed.type), orig_type)) |
4590 | return true; |
4591 | return false; |
4592 | } |
4593 | |
4594 | /* Helper function for cxx_eval_bit_cast. For unsigned char or |
4595 | std::byte members of CONSTRUCTOR (recursively) if they contain |
4596 | some indeterminate bits (as set in MASK), remove the ctor elts, |
4597 | mark the CONSTRUCTOR as CONSTRUCTOR_NO_CLEARING and clear the |
4598 | bits in MASK. */ |
4599 | |
4600 | static void |
4601 | clear_uchar_or_std_byte_in_mask (location_t loc, tree t, unsigned char *mask) |
4602 | { |
4603 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) != CONSTRUCTOR) |
4604 | return; |
4605 | |
4606 | unsigned i, j = 0; |
4607 | tree index, value; |
4608 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, index, value)for (i = 0; (i >= vec_safe_length (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4608, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ? false : (((void) (value = (*((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4608, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].value)), (index = (*((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4608, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[ i].index), true); (i)++) |
4609 | { |
4610 | tree type = TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4610, __FUNCTION__))->typed.type); |
4611 | if (TREE_CODE (TREE_TYPE (t))((enum tree_code) (((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4611, __FUNCTION__))->typed.type))->base.code) != ARRAY_TYPE |
4612 | && DECL_BIT_FIELD_TYPE (index)((tree_check ((index), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4612, __FUNCTION__, (FIELD_DECL)))->field_decl.bit_field_type ) != NULL_TREE(tree) __null) |
4613 | { |
4614 | if (is_byte_access_type_not_plain_char (DECL_BIT_FIELD_TYPE (index)((tree_check ((index), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constexpr.cc" , 4614, __FUNCTION__, (FIELD_DECL)))->field_decl.bit_field_type ))) |
4615 |