File: | build/gcc/cp/constexpr.cc |
Warning: | line 481, column 36 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" , 445 |