{
if (ptds.saved)
{
- gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr));
+ gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr)
+ || (DECL_CONTEXT (expr)
+ != current_function_decl));
/* DECL_HAS_VALUE_EXPR_P is always set if
- processing_template_decl. If lookup_decomp_type
+ processing_template_decl at least for structured bindings
+ within the template. If lookup_decomp_type
returns non-NULL, it is the tuple case. */
if (tree ret = lookup_decomp_type (expr))
return ret;
+ gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr));
}
if (DECL_HAS_VALUE_EXPR_P (expr))
/* Expr is an array or struct subobject proxy, handle
--- /dev/null
+// PR c++/123667
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ template <int I> int &get () { return i; }
+};
+
+template <> struct std::tuple_size <A> { static const int value = 2; };
+template <int I> struct std::tuple_element <I,A> { using type = int; };
+
+int
+main ()
+{
+ auto [ x, y ] = A { 0 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ [] (auto t) { using z = decltype (x); } (1);
+}
--- /dev/null
+// PR c++/123667
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+namespace std {
+ template <typename T> struct tuple_size;
+ template <int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ template <int I> int &get () { return i; }
+};
+
+template <> struct std::tuple_size <A> { static const int value = 2; };
+template <int I> struct std::tuple_element <I,A> { using type = int; };
+
+auto [ x, y ] = A { 0 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+
+template <int N>
+void
+foo ()
+{
+ using a = decltype (x);
+ auto [ x, y ] = A { 0 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ using b = decltype (x);
+}
+
+void
+bar ()
+{
+ foo <42> ();
+}