/* Ensure DECL_VALUE_EXPR is created for all the decls but
the underlying DECL. */
cp_finish_decomp (decl, &decomp);
+ if (decl_spec_seq_has_spec_p (decl_specifiers, ds_thread))
+ pedwarn (decl_specifiers->locations[ds_thread],
+ 0, "for-range-declaration cannot be %qs",
+ decl_specifiers->gnu_thread_keyword_p
+ ? "__thread" : "thread_local");
+ else if (decl_specifiers->storage_class == sc_static)
+ pedwarn (decl_specifiers->locations[ds_storage_class],
+ 0, "for-range-declaration cannot be %qs",
+ "static");
}
if (pushed_scope)
&& token->type != CPP_SEMICOLON)
{
if (maybe_range_for_decl && *maybe_range_for_decl != error_mark_node)
- range_for_decl_p = true;
+ {
+ range_for_decl_p = true;
+ if (decl_spec_seq_has_spec_p (decl_specifiers, ds_thread))
+ pedwarn (decl_specifiers->locations[ds_thread],
+ 0, "for-range-declaration cannot be %qs",
+ decl_specifiers->gnu_thread_keyword_p
+ ? "__thread" : "thread_local");
+ else if (decl_specifiers->storage_class == sc_static)
+ pedwarn (decl_specifiers->locations[ds_storage_class],
+ 0, "for-range-declaration cannot be %qs",
+ "static");
+ else if (decl_specifiers->storage_class == sc_extern)
+ pedwarn (decl_specifiers->locations[ds_storage_class],
+ 0, "for-range-declaration cannot be %qs",
+ "extern");
+ else if (decl_specifiers->storage_class == sc_register)
+ pedwarn (decl_specifiers->locations[ds_storage_class],
+ 0, "for-range-declaration cannot be %qs",
+ "register");
+ }
else
{
if (!maybe_range_for_decl)
--- /dev/null
+// PR c++/84009
+// { dg-do compile { target c++11 } }
+
+int z[64];
+
+void
+foo ()
+{
+ for (static auto a : z) // { dg-error "for-range-declaration cannot be 'static'" }
+ ;
+ for (thread_local auto a : z) // { dg-error "for-range-declaration cannot be 'thread_local'" }
+ ;
+ for (__thread auto a : z) // { dg-error "for-range-declaration cannot be '__thread'" }
+ ; // { dg-error "function-scope 'a' implicitly auto and declared '__thread'" "" { target *-*-* } .-1 }
+ for (register auto a : z) // { dg-error "for-range-declaration cannot be 'register'" }
+ ; // { dg-error "does not allow 'register' storage class specifier" "" { target c++17 } .-1 }
+ for (extern auto a : z) // { dg-error "for-range-declaration cannot be 'extern'" }
+ ; // { dg-error "'a' has both 'extern' and initializer" "" { target *-*-* } .-1 }
+ for (mutable auto a : z) // { dg-error "non-member 'a' cannot be declared 'mutable'" }
+ ;
+ for (virtual auto a : z) // { dg-error "'virtual' outside class declaration" }
+ ;
+ for (explicit auto a : z) // { dg-error "'explicit' outside class declaration" }
+ ;
+ for (friend auto a : z) // { dg-error "'friend' used outside of class" }
+ ;
+ for (typedef auto a : z) // { dg-error "typedef declared 'auto'" }
+ ; // { dg-error "typedef 'a' is initialized \\\(use 'decltype' instead\\\)" "" { target *-*-* } .-1 }
+#if __cplusplus >= 202002L
+ for (consteval auto a : z) // { dg-error "a variable cannot be declared 'consteval'" "" { target c++20 } }
+ ;
+ for (constinit auto a : z) // { dg-error "'constinit' can only be applied to a variable with static or thread storage duration" "" { target c++20 } }
+ ;
+#endif
+ for (inline auto a : z) // { dg-error "'inline' specifier invalid for variable 'a' declared at block scope" }
+ ;
+ for (struct S { int a; } a : z) // { dg-error "types may not be defined in a for-range-declaration" }
+ ; // { dg-error "conversion from 'int' to non-scalar type 'foo\\\(\\\)::S' requested" "" { target *-*-* } .-1 }
+ for (enum E { E0 } a : z) // { dg-error "types may not be defined in a for-range-declaration" }
+ ; // { dg-error "invalid conversion from 'int' to 'foo\\\(\\\)::E'" "" { target *-*-* } .-1 }
+}
--- /dev/null
+// PR c++/84009
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+int z[64];
+
+void
+foo ()
+{
+ for (static auto a : z) // { dg-warning "for-range-declaration cannot be 'static'" }
+ ;
+ for (thread_local auto a : z) // { dg-warning "for-range-declaration cannot be 'thread_local'" }
+ ;
+ for (__thread auto a : z) // { dg-warning "for-range-declaration cannot be '__thread'" }
+ ; // { dg-warning "function-scope 'a' implicitly auto and declared '__thread'" "" { target *-*-* } .-1 }
+ for (register auto a : z) // { dg-warning "for-range-declaration cannot be 'register'" }
+ ; // { dg-warning "does not allow 'register' storage class specifier" "" { target c++17 } .-1 }
+ for (extern auto a : z) // { dg-warning "for-range-declaration cannot be 'extern'" }
+ ; // { dg-error "'a' has both 'extern' and initializer" "" { target *-*-* } .-1 }
+ for (mutable auto a : z) // { dg-error "non-member 'a' cannot be declared 'mutable'" }
+ ;
+ for (virtual auto a : z) // { dg-error "'virtual' outside class declaration" }
+ ;
+ for (explicit auto a : z) // { dg-error "'explicit' outside class declaration" }
+ ;
+ for (friend auto a : z) // { dg-error "'friend' used outside of class" }
+ ;
+ for (typedef auto a : z) // { dg-error "typedef declared 'auto'" }
+ ; // { dg-error "typedef 'a' is initialized \\\(use 'decltype' instead\\\)" "" { target *-*-* } .-1 }
+#if __cplusplus >= 202002L
+ for (consteval auto a : z) // { dg-error "a variable cannot be declared 'consteval'" "" { target c++20 } }
+ ;
+ for (constinit auto a : z) // { dg-error "'constinit' can only be applied to a variable with static or thread storage duration" "" { target c++20 } }
+ ;
+#endif
+ for (inline auto a : z) // { dg-error "'inline' specifier invalid for variable 'a' declared at block scope" }
+ ;
+ for (struct S { int a; } a : z) // { dg-error "types may not be defined in a for-range-declaration" }
+ ; // { dg-error "conversion from 'int' to non-scalar type 'foo\\\(\\\)::S' requested" "" { target *-*-* } .-1 }
+ for (enum E { E0 } a : z) // { dg-error "types may not be defined in a for-range-declaration" }
+ ; // { dg-error "invalid conversion from 'int' to 'foo\\\(\\\)::E'" "" { target *-*-* } .-1 }
+}
--- /dev/null
+// PR c++/84009
+// { dg-do compile { target c++11 } }
+
+struct S { int y; } z[64];
+
+void
+foo ()
+{
+ for (static auto [ a ] : z) // { dg-error "for-range-declaration cannot be 'static'" }
+ ; // { dg-error "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 }
+ // { dg-error "structured bindings only available with" "" { target c++14_down } .-2 }
+ for (thread_local auto [ a ] : z) // { dg-error "for-range-declaration cannot be 'thread_local'" }
+ ; // { dg-error "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-1 }
+ // { dg-error "structured bindings only available with" "" { target c++14_down } .-2 }
+ for (__thread auto [ a ] : z) // { dg-error "for-range-declaration cannot be '__thread'" }
+ ; // { dg-error "function-scope 'structured binding' implicitly auto and declared '__thread'" "" { target *-*-* } .-1 }
+ // { dg-error "structured binding declaration can be '__thread' only in" "" { target c++17_down } .-2 }
+ // { dg-error "structured bindings only available with" "" { target c++14_down } .-3 }
+ for (register auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'register'" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (extern auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'extern'" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (mutable auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'mutable'" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (virtual auto [ a ] : z) // { dg-error "'virtual' outside class declaration" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (explicit auto [ a ] : z) // { dg-error "'explicit' outside class declaration" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (friend auto [ a ] : z) // { dg-error "'friend' used outside of class" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (typedef auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'typedef'" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+#if __cplusplus >= 202002L
+ for (consteval auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'consteval'" "" { target c++20 } }
+ ;
+ for (constinit auto [ a ] : z) // { dg-error "'constinit' can only be applied to a variable with static or thread storage duration" "" { target c++20 } }
+ ;
+#endif
+ for (inline auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'inline'" }
+ ; // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 }
+}
--- /dev/null
+// PR c++/84009
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct S { int y; } z[64];
+
+void
+foo ()
+{
+ for (static auto [ a ] : z) // { dg-warning "for-range-declaration cannot be 'static'" }
+ ; // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
+ for (thread_local auto [ a ] : z) // { dg-warning "for-range-declaration cannot be 'thread_local'" }
+ ; // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-1 }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
+ for (__thread auto [ a ] : z) // { dg-warning "for-range-declaration cannot be '__thread'" }
+ ; // { dg-warning "function-scope 'structured binding' implicitly auto and declared '__thread'" "" { target *-*-* } .-1 }
+ // { dg-warning "structured binding declaration can be '__thread' only in" "" { target c++17_down } .-2 }
+ // { dg-warning "structured bindings only available with" "" { target c++14_down } .-3 }
+ for (register auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'register'" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (extern auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'extern'" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (mutable auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'mutable'" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (virtual auto [ a ] : z) // { dg-error "'virtual' outside class declaration" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (explicit auto [ a ] : z) // { dg-error "'explicit' outside class declaration" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (friend auto [ a ] : z) // { dg-error "'friend' used outside of class" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+ for (typedef auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'typedef'" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+#if __cplusplus >= 202002L
+ for (consteval auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'consteval'" "" { target c++20 } }
+ ;
+ for (constinit auto [ a ] : z) // { dg-error "'constinit' can only be applied to a variable with static or thread storage duration" "" { target c++20 } }
+ ;
+#endif
+ for (inline auto [ a ] : z) // { dg-error "structured binding declaration cannot be 'inline'" }
+ ; // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+}