aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.cc19
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C15
2 files changed, 33 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 38e3a16..b9933ec 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13016,17 +13016,26 @@ public:
/* 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);
@@ -13118,6 +13127,14 @@ static tree
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;
}
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C
new file mode 100644
index 0000000..d2bf022
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda5.C
@@ -0,0 +1,15 @@
+// PR c++/100295
+// { dg-do compile { target c++17 } }
+
+template<typename... Ts>
+void f(Ts... ts) {
+ auto lambda = [=](auto x) {
+ if constexpr (sizeof((ts+x) + ...) != 0)
+ (..., ts);
+ };
+ lambda(0);
+}
+
+int main() {
+ f(0, 'a');
+}