/* List of local_specializations used within the pattern. */
tree extra;
tsubst_flags_t complain;
+ /* True iff we don't want to walk into unevaluated contexts. */
+ bool skip_unevaluated_operands = false;
el_data (tsubst_flags_t c)
: extra (NULL_TREE), complain (c) {}
};
static tree
-extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_)
+extract_locals_r (tree *tp, int *walk_subtrees, void *data_)
{
el_data &data = *reinterpret_cast<el_data*>(data_);
tree *extra = &data.extra;
tsubst_flags_t complain = data.complain;
+ if (data.skip_unevaluated_operands
+ && unevaluated_p (TREE_CODE (*tp)))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
if (TYPE_P (*tp) && typedef_variant_p (*tp))
/* Remember local typedefs (85214). */
tp = &TYPE_NAME (*tp);
extract_local_specs (tree pattern, tsubst_flags_t complain)
{
el_data data (complain);
+ /* Walk the pattern twice, ignoring unevaluated operands the first time
+ around, so that if a local specialization appears in both an evaluated
+ and unevaluated context we prefer to process it in the evaluated context
+ (since e.g. process_outer_var_ref is a no-op inside an unevaluated
+ context). */
+ data.skip_unevaluated_operands = true;
+ cp_walk_tree (&pattern, extract_locals_r, &data, &data.visited);
+ data.skip_unevaluated_operands = false;
cp_walk_tree (&pattern, extract_locals_r, &data, &data.visited);
return data.extra;
}