Message ID | mptzh3bkev9.fsf@arm.com |
---|---|
State | New |
Headers | show |
Series | c++: Add missing verify_type_context call [PR97904] | expand |
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
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 --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.