{
if (!processing_template_decl
&& !error_operand_p (decl)
- && DECL_NAMESPACE_SCOPE_P (decl))
+ && TREE_STATIC (decl))
{
auto_vec<tree, 16> v;
v.safe_grow (count);
DECL_HAS_VALUE_EXPR_P (v[i]) = 0;
}
if (!processing_template_decl)
- cp_finish_decl (v[i], init, /*constexpr*/false,
- /*asm*/NULL_TREE, LOOKUP_NORMAL);
+ {
+ TREE_PUBLIC (v[i]) = TREE_PUBLIC (decl);
+ TREE_STATIC (v[i]) = TREE_STATIC (decl);
+ DECL_COMMON (v[i]) = DECL_COMMON (decl);
+ DECL_COMDAT (v[i]) = DECL_COMDAT (decl);
+ if (TREE_STATIC (v[i]))
+ {
+ CP_DECL_THREAD_LOCAL_P (v[i])
+ = CP_DECL_THREAD_LOCAL_P (decl);
+ set_decl_tls_model (v[i], DECL_TLS_MODEL (decl));
+ if (DECL_ONE_ONLY (decl))
+ make_decl_one_only (v[i], cxx_comdat_group (v[i]));
+ if (TREE_PUBLIC (decl))
+ DECL_WEAK (v[i]) = DECL_WEAK (decl);
+ DECL_VISIBILITY (v[i]) = DECL_VISIBILITY (decl);
+ DECL_VISIBILITY_SPECIFIED (v[i])
+ = DECL_VISIBILITY_SPECIFIED (decl);
+ }
+ cp_finish_decl (v[i], init, /*constexpr*/false,
+ /*asm*/NULL_TREE, LOOKUP_NORMAL);
+ }
}
/* Ignore reads from the underlying decl performed during initialization
of the individual variables. If those will be read, we'll mark
? declarator->declarator->id_loc : declarator->id_loc);
if (inlinep)
error_at (declspecs->locations[ds_inline],
- "structured binding declaration cannot be %<inline%>");
+ "structured binding declaration cannot be %qs", "inline");
if (typedef_p)
error_at (declspecs->locations[ds_typedef],
- "structured binding declaration cannot be %<typedef%>");
+ "structured binding declaration cannot be %qs", "typedef");
if (constexpr_p)
error_at (declspecs->locations[ds_constexpr], "structured "
- "binding declaration cannot be %<constexpr%>");
- if (thread_p)
- error_at (declspecs->locations[ds_thread],
- "structured binding declaration cannot be %qs",
- declspecs->gnu_thread_keyword_p
- ? "__thread" : "thread_local");
+ "binding declaration cannot be %qs", "constexpr");
+ if (thread_p && cxx_dialect < cxx2a)
+ pedwarn (declspecs->locations[ds_thread], 0,
+ "structured binding declaration can be %qs only in "
+ "%<-std=c++2a%> or %<-std=gnu++2a%>",
+ declspecs->gnu_thread_keyword_p
+ ? "__thread" : "thread_local");
if (concept_p)
error_at (declspecs->locations[ds_concept],
- "structured binding declaration cannot be %<concept%>");
+ "structured binding declaration cannot be %qs", "concept");
switch (storage_class)
{
case sc_none:
break;
case sc_register:
- error_at (loc, "structured binding declaration cannot be "
- "%<register%>");
+ error_at (loc, "structured binding declaration cannot be %qs",
+ "register");
break;
case sc_static:
- error_at (loc, "structured binding declaration cannot be "
- "%<static%>");
+ if (cxx_dialect < cxx2a)
+ pedwarn (loc, 0,
+ "structured binding declaration can be %qs only in "
+ "%<-std=c++2a%> or %<-std=gnu++2a%>", "static");
break;
case sc_extern:
- error_at (loc, "structured binding declaration cannot be "
- "%<extern%>");
+ error_at (loc, "structured binding declaration cannot be %qs",
+ "extern");
break;
case sc_mutable:
- error_at (loc, "structured binding declaration cannot be "
- "%<mutable%>");
+ error_at (loc, "structured binding declaration cannot be %qs",
+ "mutable");
break;
case sc_auto:
error_at (loc, "structured binding declaration cannot be "
inlinep = 0;
typedef_p = 0;
constexpr_p = 0;
- thread_p = 0;
concept_p = 0;
- storage_class = sc_none;
- staticp = 0;
- declspecs->storage_class = sc_none;
- declspecs->locations[ds_thread] = UNKNOWN_LOCATION;
+ if (storage_class != sc_static)
+ {
+ storage_class = sc_none;
+ declspecs->storage_class = sc_none;
+ }
}
/* Static anonymous unions are dealt with here. */
// { dg-warning "structured bindings only available with '-std=c..17' or '-std=gnu..17'" "" { target c++14_down } .-1 }
explicit auto [ w ] = c; // { dg-error "'explicit' outside class declaration" }
// { dg-warning "structured bindings only available with '-std=c..17' or '-std=gnu..17'" "" { target c++14_down } .-1 }
- static auto [ x ] = c; // { dg-error "structured binding declaration cannot be 'static'" }
+ static auto [ x ] = c; // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } }
// { dg-warning "structured bindings only available with '-std=c..17' or '-std=gnu..17'" "" { target c++14_down } .-1 }
extern auto [ y ] { c }; // { dg-error "structured binding declaration cannot be 'extern'" }
// { dg-warning "structured bindings only available with '-std=c..17' or '-std=gnu..17'" "" { target c++14_down } .-1 }
+ thread_local auto [ z ] = c; // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with '-std=c..17' or '-std=gnu..17'" "" { target c++14_down } .-1 }
}
+__thread auto [ z2 ] = B (); // { dg-warning "structured binding declaration can be '__thread' only in" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with '-std=c..17' or '-std=gnu..17'" "" { target c++14_down } .-1 }
+
void
test2 (auto & [ p ] = bar ()) // { dg-error "'p' was not declared in this scope" }
{ // { dg-warning "auto" "" { target { ! concepts } } .-1 }
--- /dev/null
+// P1091R3
+// { dg-do compile { target { c++17 && c++14_down } } }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ A(int x) : i(x) {}
+ template <int I> int& get() { return i; }
+};
+struct B { int a, b, c; };
+
+template<> struct std::tuple_size<A> { static const int value = 2; };
+template<int I> struct std::tuple_element<I,A> { using type = int; };
+
+B s = { 1, 2, 3 };
+
+#line 1
+static auto [ d, e, f ] = s;
+static auto [ g, h ] = A (42);
+
+int &
+foo (int x)
+{
+ switch (x)
+ {
+ case 0: return d;
+ case 1: return e;
+ case 2: return f;
+ case 3: return g;
+ default: return h;
+ }
+}
+
+int
+bar (int x)
+{
+#line 3
+ static auto [ m, n, o ] = s;
+ static auto [ p, q ] = A (43);
+ switch (x)
+ {
+ case 0: return ++m;
+ case 1: return ++n;
+ case 2: return ++o;
+ case 3: return ++p;
+ default: return ++q;
+ }
+}
--- /dev/null
+// P1091R3
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+// { dg-additional-sources decomp1-aux.cc }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ A(int x) : i(x) {}
+ template <int I> int& get() { return i; }
+};
+struct B { int a, b, c; };
+
+template<> struct std::tuple_size<A> { static const int value = 2; };
+template<int I> struct std::tuple_element<I,A> { using type = int; };
+
+extern int &foo (int);
+extern int bar (int);
+extern B s;
+extern "C" void abort ();
+B t = { 4, 5, 6 };
+
+static auto [ d, e, f ] = t; // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+static auto [ g, h ] = A (44); // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+// The following warnings are in decomp1-aux.cc with #line directive.
+// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 1 }
+// { dg-warning "structured bindings only available with" "" { target c++14_down } 1 }
+// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 2 }
+// { dg-warning "structured bindings only available with" "" { target c++14_down } 2 }
+// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 3 }
+// { dg-warning "structured bindings only available with" "" { target c++14_down } 3 }
+// { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } 4 }
+// { dg-warning "structured bindings only available with" "" { target c++14_down } 4 }
+
+int &
+baz (int x)
+{
+ switch (x)
+ {
+ case 0: return d;
+ case 1: return e;
+ case 2: return f;
+ case 3: return g;
+ default: return h;
+ }
+}
+
+int
+qux (int x)
+{
+ static auto [ m, n, o ] = t; // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ static auto [ p, q ] = A (45); // { dg-warning "structured binding declaration can be 'static' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ switch (x)
+ {
+ case 0: return ++m;
+ case 1: return ++n;
+ case 2: return ++o;
+ case 3: return ++p;
+ default: return ++q;
+ }
+}
+
+int
+main ()
+{
+ int *a[10];
+ for (int i = 0; i < 5; ++i)
+ {
+ a[i] = &foo (i);
+ a[i + 5] = &baz (i);
+ }
+ for (int i = 0; i < 10; ++i)
+ for (int j = i + 1; j < 10; ++j)
+ if (a[i] == a[j] && (j != i + 1 || (i % 5) != 3))
+ abort ();
+ if (a[1] != a[0] + 1 || a[2] != a[0] + 2 || a[4] != a[3]
+ || a[6] != a[5] + 1 || a[7] != a[5] + 2 || a[9] != a[8])
+ abort ();
+ int b[] = { 1, 2, 3, 43, 43 + 6, 4, 5, 6, 45, 45 + 11 };
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 3 + i; ++j)
+ if ((i < 5 ? bar (i) : qux (i - 5)) != b[i] + 1 + j)
+ abort ();
+}
--- /dev/null
+// P1091R3
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+// { dg-require-effective-target tls }
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+struct A {
+ int i;
+ A(int x) : i(x) {}
+ template <int I> int& get() { return i; }
+};
+struct B { int a, b, c; };
+
+template<> struct std::tuple_size<A> { static const int value = 2; };
+template<int I> struct std::tuple_element<I,A> { using type = int; };
+
+extern "C" void abort ();
+B t = { 4, 5, 6 };
+
+thread_local auto [ d, e, f ] = t; // { dg-warning "structured binding declaration can be 'thread_local' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+thread_local auto [ g, h ] = A (44); // { dg-warning "structured binding declaration can be 'thread_local' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+
+int &
+baz (int x)
+{
+ switch (x)
+ {
+ case 0: return d;
+ case 1: return e;
+ case 2: return f;
+ case 3: return g;
+ default: return h;
+ }
+}
+
+int
+qux (int x)
+{
+ thread_local auto [ m, n, o ] = t; // { dg-warning "structured binding declaration can be 'thread_local' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ thread_local auto [ p, q ] = A (45); // { dg-warning "structured binding declaration can be 'thread_local' only" "" { target c++17_down } }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ switch (x)
+ {
+ case 0: return ++m;
+ case 1: return ++n;
+ case 2: return ++o;
+ case 3: return ++p;
+ default: return ++q;
+ }
+}
+
+int
+main ()
+{
+ int *a[5];
+ for (int i = 0; i < 5; ++i)
+ a[i] = &baz (i);
+ for (int i = 0; i < 5; ++i)
+ for (int j = i + 1; j < 5; ++j)
+ if (a[i] == a[j] && (j != i + 1 || i != 3))
+ abort ();
+ if (a[1] != a[0] + 1 || a[2] != a[0] + 2 || a[4] != a[3])
+ abort ();
+ int b[] = { 4, 5, 6, 45, 45 + 6 };
+ for (int i = 0; i < 5; ++i)
+ for (int j = 0; j < 3 + i; ++j)
+ if (qux (i) != b[i] + 1 + j)
+ abort ();
+}
--- /dev/null
+// P1381R1
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct Foo { int a : 1; int b; };
+
+int main() {
+ auto[a, b] = Foo(); // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+
+ auto f1 = [&] { return a; }; // { dg-error "cannot bind bitfield" }
+ auto f2 = [&a = a] { return a; }; // { dg-error "cannot bind bitfield" }
+ // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 }
+ auto f3 = [&a] { return a; }; // { dg-error "cannot bind bitfield" }
+
+ auto g1 = [&] { return b; };
+ auto g2 = [&b = b] { return b; }; // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
+ auto g3 = [&b] { return b; };
+
+ auto h1 = [=] { return a; };
+ auto h2 = [a = a] { return a; }; // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
+ auto h3 = [a] { return a; };
+
+ auto i1 = [=] { return b; };
+ auto i2 = [b = b] { return b; }; // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } }
+ auto i3 = [b] { return b; };
+}