[PATCH] c++: Add missing verify_type_context call [PR97904]

Jason Merrill jason@redhat.com
Fri Nov 20 22:10:28 GMT 2020


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.
>   
> 



More information about the Gcc-patches mailing list