diff mbox series

c++: Add missing verify_type_context call [PR97904]

Message ID mptzh3bkev9.fsf@arm.com
State New
Headers show
Series c++: Add missing verify_type_context call [PR97904] | expand

Commit Message

Richard Sandiford Nov. 20, 2020, 7:27 p.m. UTC
When adding the verify_type_context target hook, I'd missed
a site that needs to check an array element type.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK for master
and GCC 10 branch?

Thanks,
Richard


gcc/cp/
	PR c++/97904
	* pt.c (tsubst): Use verify_type_context to check the type
	of an array element.

gcc/testsuite/
	PR c++/97904
	* g++.dg/ext/sve-sizeless-1.C: Add more template tests.
	* g++.dg/ext/sve-sizeless-2.C: Likewise.
---
 gcc/cp/pt.c                               |  4 +++
 gcc/testsuite/g++.dg/ext/sve-sizeless-1.C | 33 +++++++++++++++++++++--
 gcc/testsuite/g++.dg/ext/sve-sizeless-2.C | 33 +++++++++++++++++++++--
 3 files changed, 66 insertions(+), 4 deletions(-)

Comments

Marek Polacek Nov. 20, 2020, 7:36 p.m. UTC | #1
On Fri, Nov 20, 2020 at 07:27:54PM +0000, Richard Sandiford via Gcc-patches wrote:
> When adding the verify_type_context target hook, I'd missed
> a site that needs to check an array element type.
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK for master
> and GCC 10 branch?

Not an approval, but looks fine to me, and matches the other uses of
verify_type_context I've checked in the C++ FE.

> gcc/cp/
> 	PR c++/97904
> 	* pt.c (tsubst): Use verify_type_context to check the type
> 	of an array element.
> 
> gcc/testsuite/
> 	PR c++/97904
> 	* g++.dg/ext/sve-sizeless-1.C: Add more template tests.
> 	* g++.dg/ext/sve-sizeless-2.C: Likewise.
> ---
>  gcc/cp/pt.c                               |  4 +++
>  gcc/testsuite/g++.dg/ext/sve-sizeless-1.C | 33 +++++++++++++++++++++--
>  gcc/testsuite/g++.dg/ext/sve-sizeless-2.C | 33 +++++++++++++++++++++--
>  3 files changed, 66 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 463b1c3a57d..89fec98ad67 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -15867,6 +15867,10 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
>  	    return error_mark_node;
>  	  }
>  
> +	if (!verify_type_context (input_location, TCTX_ARRAY_ELEMENT, type,
> +				  !(complain & tf_error)))
> +	  return error_mark_node;
> +
>  	r = build_cplus_array_type (type, domain);
>  
>  	if (!valid_array_size_p (input_location, r, in_decl,
> diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
> index 7f829220c71..9f05ca5a855 100644
> --- a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
> +++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
> @@ -72,10 +72,37 @@ template class templated_struct4<svint8_t>;
>  template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
>  template class templated_struct5<svint8_t>;
>  
> +template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +template class templated_struct6<svint8_t, 2>;
> +
> +template<typename T>
> +struct templated_struct7 {
> +  static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
> +#if __cplusplus >= 201103L
> +  static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
> +#endif
> +
> +  void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +#if __cplusplus >= 201103L
> +  auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +  auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +#else
> +  void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
> +#endif
> +};
> +template class templated_struct7<svint8_t>;
> +
> +template<typename T> struct templated_struct8 { typedef int type; };
> +
> +template<typename T>
> +void sfinae_f1 (typename templated_struct8<T[2]>::type);
> +template<typename T>
> +void sfinae_f1 (T &);
> +
>  #if __cplusplus >= 201103L
>  template<int N> using typedef_sizeless1 = svint8_t;
>  template<int N> using typedef_sizeless1 = svint8_t;
> -template<typename T> using array = T[2];
> +template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
>  #endif
>  
>  // Pointers to sizeless types.
> @@ -119,7 +146,7 @@ statements (int n)
>    __alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
>  
>  #if __cplusplus >= 201103L
> -  array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
> +  array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
>  #endif
>  
>    // Initialization.
> @@ -298,6 +325,8 @@ statements (int n)
>    thrower2 ();
>  #endif
>  
> +  sfinae_f1<svint8_t> (sve_sc1);
> +
>    // Use in traits.  Doesn't use static_assert so that tests work with
>    // earlier -std=s.
>  
> diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
> index 40b65d37f8a..0b86d9e8217 100644
> --- a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
> +++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
> @@ -72,10 +72,37 @@ template class templated_struct4<svint8_t>;
>  template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
>  template class templated_struct5<svint8_t>;
>  
> +template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +template class templated_struct6<svint8_t, 2>;
> +
> +template<typename T>
> +struct templated_struct7 {
> +  static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
> +#if __cplusplus >= 201103L
> +  static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
> +#endif
> +
> +  void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +#if __cplusplus >= 201103L
> +  auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +  auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +#else
> +  void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
> +#endif
> +};
> +template class templated_struct7<svint8_t>;
> +
> +template<typename T> struct templated_struct8 { typedef int type; };
> +
> +template<typename T>
> +void sfinae_f1 (typename templated_struct8<T[2]>::type);
> +template<typename T>
> +void sfinae_f1 (T &);
> +
>  #if __cplusplus >= 201103L
>  template<int N> using typedef_sizeless1 = svint8_t;
>  template<int N> using typedef_sizeless1 = svint8_t;
> -template<typename T> using array = T[2];
> +template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
>  #endif
>  
>  // Pointers to sizeless types.
> @@ -119,7 +146,7 @@ statements (int n)
>    __alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
>  
>  #if __cplusplus >= 201103L
> -  array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
> +  array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
>  #endif
>  
>    // Initialization.
> @@ -298,6 +325,8 @@ statements (int n)
>    thrower2 ();
>  #endif
>  
> +  sfinae_f1<svint8_t> (sve_sc1);
> +
>    // Use in traits.  Doesn't use static_assert so that tests work with
>    // earlier -std=s.
>  
> 

Marek
Jason Merrill Nov. 20, 2020, 10:10 p.m. UTC | #2
On 11/20/20 2:27 PM, Richard Sandiford wrote:
> When adding the verify_type_context target hook, I'd missed
> a site that needs to check an array element type.
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK for master
> and GCC 10 branch?

OK.

> Thanks,
> Richard
> 
> 
> gcc/cp/
> 	PR c++/97904
> 	* pt.c (tsubst): Use verify_type_context to check the type
> 	of an array element.
> 
> gcc/testsuite/
> 	PR c++/97904
> 	* g++.dg/ext/sve-sizeless-1.C: Add more template tests.
> 	* g++.dg/ext/sve-sizeless-2.C: Likewise.
> ---
>   gcc/cp/pt.c                               |  4 +++
>   gcc/testsuite/g++.dg/ext/sve-sizeless-1.C | 33 +++++++++++++++++++++--
>   gcc/testsuite/g++.dg/ext/sve-sizeless-2.C | 33 +++++++++++++++++++++--
>   3 files changed, 66 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 463b1c3a57d..89fec98ad67 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -15867,6 +15867,10 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
>   	    return error_mark_node;
>   	  }
>   
> +	if (!verify_type_context (input_location, TCTX_ARRAY_ELEMENT, type,
> +				  !(complain & tf_error)))
> +	  return error_mark_node;
> +
>   	r = build_cplus_array_type (type, domain);
>   
>   	if (!valid_array_size_p (input_location, r, in_decl,
> diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
> index 7f829220c71..9f05ca5a855 100644
> --- a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
> +++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
> @@ -72,10 +72,37 @@ template class templated_struct4<svint8_t>;
>   template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
>   template class templated_struct5<svint8_t>;
>   
> +template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +template class templated_struct6<svint8_t, 2>;
> +
> +template<typename T>
> +struct templated_struct7 {
> +  static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
> +#if __cplusplus >= 201103L
> +  static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
> +#endif
> +
> +  void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +#if __cplusplus >= 201103L
> +  auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +  auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +#else
> +  void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
> +#endif
> +};
> +template class templated_struct7<svint8_t>;
> +
> +template<typename T> struct templated_struct8 { typedef int type; };
> +
> +template<typename T>
> +void sfinae_f1 (typename templated_struct8<T[2]>::type);
> +template<typename T>
> +void sfinae_f1 (T &);
> +
>   #if __cplusplus >= 201103L
>   template<int N> using typedef_sizeless1 = svint8_t;
>   template<int N> using typedef_sizeless1 = svint8_t;
> -template<typename T> using array = T[2];
> +template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
>   #endif
>   
>   // Pointers to sizeless types.
> @@ -119,7 +146,7 @@ statements (int n)
>     __alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
>   
>   #if __cplusplus >= 201103L
> -  array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
> +  array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
>   #endif
>   
>     // Initialization.
> @@ -298,6 +325,8 @@ statements (int n)
>     thrower2 ();
>   #endif
>   
> +  sfinae_f1<svint8_t> (sve_sc1);
> +
>     // Use in traits.  Doesn't use static_assert so that tests work with
>     // earlier -std=s.
>   
> diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
> index 40b65d37f8a..0b86d9e8217 100644
> --- a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
> +++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
> @@ -72,10 +72,37 @@ template class templated_struct4<svint8_t>;
>   template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
>   template class templated_struct5<svint8_t>;
>   
> +template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +template class templated_struct6<svint8_t, 2>;
> +
> +template<typename T>
> +struct templated_struct7 {
> +  static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
> +#if __cplusplus >= 201103L
> +  static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
> +#endif
> +
> +  void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
> +#if __cplusplus >= 201103L
> +  auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +  auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
> +#else
> +  void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
> +#endif
> +};
> +template class templated_struct7<svint8_t>;
> +
> +template<typename T> struct templated_struct8 { typedef int type; };
> +
> +template<typename T>
> +void sfinae_f1 (typename templated_struct8<T[2]>::type);
> +template<typename T>
> +void sfinae_f1 (T &);
> +
>   #if __cplusplus >= 201103L
>   template<int N> using typedef_sizeless1 = svint8_t;
>   template<int N> using typedef_sizeless1 = svint8_t;
> -template<typename T> using array = T[2];
> +template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
>   #endif
>   
>   // Pointers to sizeless types.
> @@ -119,7 +146,7 @@ statements (int n)
>     __alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
>   
>   #if __cplusplus >= 201103L
> -  array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
> +  array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
>   #endif
>   
>     // Initialization.
> @@ -298,6 +325,8 @@ statements (int n)
>     thrower2 ();
>   #endif
>   
> +  sfinae_f1<svint8_t> (sve_sc1);
> +
>     // Use in traits.  Doesn't use static_assert so that tests work with
>     // earlier -std=s.
>   
>
diff mbox series

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 463b1c3a57d..89fec98ad67 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15867,6 +15867,10 @@  tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	    return error_mark_node;
 	  }
 
+	if (!verify_type_context (input_location, TCTX_ARRAY_ELEMENT, type,
+				  !(complain & tf_error)))
+	  return error_mark_node;
+
 	r = build_cplus_array_type (type, domain);
 
 	if (!valid_array_size_p (input_location, r, in_decl,
diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
index 7f829220c71..9f05ca5a855 100644
--- a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
+++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
@@ -72,10 +72,37 @@  template class templated_struct4<svint8_t>;
 template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
 template class templated_struct5<svint8_t>;
 
+template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+template class templated_struct6<svint8_t, 2>;
+
+template<typename T>
+struct templated_struct7 {
+  static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
+#if __cplusplus >= 201103L
+  static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
+#endif
+
+  void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+#if __cplusplus >= 201103L
+  auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+  auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+#else
+  void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
+#endif
+};
+template class templated_struct7<svint8_t>;
+
+template<typename T> struct templated_struct8 { typedef int type; };
+
+template<typename T>
+void sfinae_f1 (typename templated_struct8<T[2]>::type);
+template<typename T>
+void sfinae_f1 (T &);
+
 #if __cplusplus >= 201103L
 template<int N> using typedef_sizeless1 = svint8_t;
 template<int N> using typedef_sizeless1 = svint8_t;
-template<typename T> using array = T[2];
+template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
 #endif
 
 // Pointers to sizeless types.
@@ -119,7 +146,7 @@  statements (int n)
   __alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
 
 #if __cplusplus >= 201103L
-  array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
+  array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
 #endif
 
   // Initialization.
@@ -298,6 +325,8 @@  statements (int n)
   thrower2 ();
 #endif
 
+  sfinae_f1<svint8_t> (sve_sc1);
+
   // Use in traits.  Doesn't use static_assert so that tests work with
   // earlier -std=s.
 
diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
index 40b65d37f8a..0b86d9e8217 100644
--- a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
+++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
@@ -72,10 +72,37 @@  template class templated_struct4<svint8_t>;
 template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
 template class templated_struct5<svint8_t>;
 
+template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+template class templated_struct6<svint8_t, 2>;
+
+template<typename T>
+struct templated_struct7 {
+  static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
+#if __cplusplus >= 201103L
+  static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
+#endif
+
+  void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+#if __cplusplus >= 201103L
+  auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+  auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+#else
+  void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
+#endif
+};
+template class templated_struct7<svint8_t>;
+
+template<typename T> struct templated_struct8 { typedef int type; };
+
+template<typename T>
+void sfinae_f1 (typename templated_struct8<T[2]>::type);
+template<typename T>
+void sfinae_f1 (T &);
+
 #if __cplusplus >= 201103L
 template<int N> using typedef_sizeless1 = svint8_t;
 template<int N> using typedef_sizeless1 = svint8_t;
-template<typename T> using array = T[2];
+template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
 #endif
 
 // Pointers to sizeless types.
@@ -119,7 +146,7 @@  statements (int n)
   __alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
 
 #if __cplusplus >= 201103L
-  array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
+  array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
 #endif
 
   // Initialization.
@@ -298,6 +325,8 @@  statements (int n)
   thrower2 ();
 #endif
 
+  sfinae_f1<svint8_t> (sve_sc1);
+
   // Use in traits.  Doesn't use static_assert so that tests work with
   // earlier -std=s.