c++: Apply/diagnose attributes when instatiating ARRAY/POINTER/REFERENCE_TYPE [PR118787]

Message ID Z6uRL4o0CObbTP07@tucnak
State New
Headers
Series c++: Apply/diagnose attributes when instatiating ARRAY/POINTER/REFERENCE_TYPE [PR118787] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

Jakub Jelinek Feb. 11, 2025, 6:04 p.m. UTC
  Hi!

The following testcase IMO in violation of the P2552R3 paper doesn't
pedwarn on alignas applying to dependent types or alignas with dependent
argument.

tsubst was just ignoring TYPE_ATTRIBUTES.

The following patch fixes it for the POINTER/REFERENCE_TYPE and
ARRAY_TYPE cases, but perhaps we need to do the same also for other
types (INTEGER_TYPE/REAL_TYPE and the like).  I guess I'll need to
construct more testcases.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-02-11  Jakub Jelinek  <jakub@redhat.com>

	PR c++/118787
	* pt.cc (tsubst) <case ARRAY_TYPE>: Use return t; only if it doesn't
	have any TYPE_ATTRIBUTES.  Call apply_late_template_attributes.
	<case POINTER_TYPE, case REFERENCE_TYPE>: Likewise.  Formatting fix.

	* g++.dg/cpp0x/alignas22.C: New test.


	Jakub
  

Comments

Jakub Jelinek March 3, 2025, 11:51 a.m. UTC | #1
Hi!

On Tue, Feb 11, 2025 at 07:04:31PM +0100, Jakub Jelinek wrote:
> The following testcase IMO in violation of the P2552R3 paper doesn't
> pedwarn on alignas applying to dependent types or alignas with dependent
> argument.
> 
> tsubst was just ignoring TYPE_ATTRIBUTES.
> 
> The following patch fixes it for the POINTER/REFERENCE_TYPE and
> ARRAY_TYPE cases, but perhaps we need to do the same also for other
> types (INTEGER_TYPE/REAL_TYPE and the like).  I guess I'll need to
> construct more testcases.

I'd like to ping the
https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675531.html
patch.

Thanks.

> 2025-02-11  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/118787
> 	* pt.cc (tsubst) <case ARRAY_TYPE>: Use return t; only if it doesn't
> 	have any TYPE_ATTRIBUTES.  Call apply_late_template_attributes.
> 	<case POINTER_TYPE, case REFERENCE_TYPE>: Likewise.  Formatting fix.
> 
> 	* g++.dg/cpp0x/alignas22.C: New test.

	Jakub
  
Jason Merrill March 4, 2025, 11:05 p.m. UTC | #2
On 2/11/25 1:04 PM, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase IMO in violation of the P2552R3 paper doesn't
> pedwarn on alignas applying to dependent types or alignas with dependent
> argument.
> 
> tsubst was just ignoring TYPE_ATTRIBUTES.
> 
> The following patch fixes it for the POINTER/REFERENCE_TYPE and
> ARRAY_TYPE cases, but perhaps we need to do the same also for other
> types (INTEGER_TYPE/REAL_TYPE and the like).  I guess I'll need to
> construct more testcases.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2025-02-11  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/118787
> 	* pt.cc (tsubst) <case ARRAY_TYPE>: Use return t; only if it doesn't
> 	have any TYPE_ATTRIBUTES.  Call apply_late_template_attributes.
> 	<case POINTER_TYPE, case REFERENCE_TYPE>: Likewise.  Formatting fix.
> 
> 	* g++.dg/cpp0x/alignas22.C: New test.
> 
> --- gcc/cp/pt.cc.jj	2025-02-07 17:03:13.560227281 +0100
> +++ gcc/cp/pt.cc	2025-02-10 17:17:47.651313333 +0100
> @@ -16854,7 +16854,9 @@ tsubst (tree t, tree args, tsubst_flags_
>       case POINTER_TYPE:
>       case REFERENCE_TYPE:
>         {
> -	if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE)
> +	if (type == TREE_TYPE (t)
> +	    && TREE_CODE (type) != METHOD_TYPE
> +	    && TYPE_ATTRIBUTES (t) == NULL_TREE)
>   	  return t;
>   
>   	/* [temp.deduct]
> @@ -16924,9 +16926,9 @@ tsubst (tree t, tree args, tsubst_flags_
>   	     A,' while an attempt to create the type type rvalue reference to
>   	     cv T' creates the type T"
>   	  */
> -	  r = cp_build_reference_type
> -	      (TREE_TYPE (type),
> -	       TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
> +	  r = cp_build_reference_type (TREE_TYPE (type),
> +				       TYPE_REF_IS_RVALUE (t)
> +				       && TYPE_REF_IS_RVALUE (type));
>   	else
>   	  r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
>   	r = cp_build_qualified_type (r, cp_type_quals (t), complain);
> @@ -16935,6 +16937,11 @@ tsubst (tree t, tree args, tsubst_flags_
>   	  /* Will this ever be needed for TYPE_..._TO values?  */
>   	  layout_type (r);
>   
> +	if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
> +					     /*flags=*/0,
> +					     args, complain, in_decl))
> +	  return error_mark_node;
> +
>   	return r;
>         }
>       case OFFSET_TYPE:
> @@ -17009,7 +17016,9 @@ tsubst (tree t, tree args, tsubst_flags_
>   
>   	/* As an optimization, we avoid regenerating the array type if
>   	   it will obviously be the same as T.  */
> -	if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
> +	if (type == TREE_TYPE (t)
> +	    && domain == TYPE_DOMAIN (t)
> +	    && TYPE_ATTRIBUTES (t) == NULL_TREE)
>   	  return t;
>   
>   	/* These checks should match the ones in create_array_type_for_decl.
> @@ -17048,6 +17057,11 @@ tsubst (tree t, tree args, tsubst_flags_
>   	    TYPE_USER_ALIGN (r) = 1;
>   	  }
>   
> +	if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
> +					     /*flags=*/0,
> +					     args, complain, in_decl))
> +	  return error_mark_node;
> +
>   	return r;
>         }
>   
> --- gcc/testsuite/g++.dg/cpp0x/alignas22.C.jj	2025-02-10 17:33:16.242452750 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/alignas22.C	2025-02-10 17:36:28.739046629 +0100
> @@ -0,0 +1,23 @@
> +// PR c++/118787
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-pedantic" }
> +
> +template <typename T, int N>
> +void foo (T & alignas (N));		// { dg-warning "'alignas' on a type other than class" }
> +template <typename T, int N>
> +void bar (T (&)[N] alignas (N));	// { dg-warning "'alignas' on a type other than class" }
> +template <typename T, int N>
> +using U = T * alignas (N);		// { dg-warning "'alignas' on a type other than class" }
> +template <typename T, int N>
> +using V = T[N] alignas (N);		// { dg-warning "'alignas' on a type other than class" }
> +
> +void
> +baz ()
> +{
> +  int x alignas (4) = 0;
> +  foo <int, 4> (x);
> +  int y alignas (4) [4];
> +  bar <int, 4> (y);
> +  U <int, 4> u;
> +  V <int, 4> v;
> +}
> 
> 	Jakub
>
  
Mark Wielaard March 5, 2025, 10:15 p.m. UTC | #3
Hi Jakub,

On Tue, Feb 11, 2025 at 07:04:31PM +0100, Jakub Jelinek wrote:
> The following testcase IMO in violation of the P2552R3 paper doesn't
> pedwarn on alignas applying to dependent types or alignas with dependent
> argument.
> 
> tsubst was just ignoring TYPE_ATTRIBUTES.
> 
> The following patch fixes it for the POINTER/REFERENCE_TYPE and
> ARRAY_TYPE cases, but perhaps we need to do the same also for other
> types (INTEGER_TYPE/REAL_TYPE and the like).  I guess I'll need to
> construct more testcases.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2025-02-11  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/118787
> 	* pt.cc (tsubst) <case ARRAY_TYPE>: Use return t; only if it doesn't
> 	have any TYPE_ATTRIBUTES.  Call apply_late_template_attributes.
> 	<case POINTER_TYPE, case REFERENCE_TYPE>: Likewise.  Formatting fix.
> 
> 	* g++.dg/cpp0x/alignas22.C: New test.

This seems to have broken the gcc-fedora-mingw build:
https://builder.sourceware.org/buildbot/#/builders/262/builds/11014

In file included from /home/builder/shared/bb2-1/worker/gcc-fedora-mingw/gcc-build/x86_64-w64-mingw32/libstdc++-v3/include/bits/basic_string.h:4230,
                 from /home/builder/shared/bb2-1/worker/gcc-fedora-mingw/gcc-build/x86_64-w64-mingw32/libstdc++-v3/include/string:56,
                 from /home/builder/shared/bb2-1/worker/gcc-fedora-mingw/gcc-build/x86_64-w64-mingw32/libstdc++-v3/include/bits/locale_classes.h:42,
                 from /home/builder/shared/bb2-1/worker/gcc-fedora-mingw/gcc-build/x86_64-w64-mingw32/libstdc++-v3/include/codecvt:42,
                 from ../../../../../gcc/libstdc++-v3/src/c++11/codecvt.cc:25:
/home/builder/shared/bb2-1/worker/gcc-fedora-mingw/gcc-build/x86_64-w64-mingw32/libstdc++-v3/include/ext/string_conversions.h: In substitution of 'template<class _String, class _CharT> _String __gnu_cxx::__to_xstring(int (*)(_CharT*, std::size_t, const _CharT*, char*), std::size_t, const _CharT*, ...) [with _String = std::__cxx11::basic_string<char>; _CharT = char]':
/home/builder/shared/bb2-1/worker/gcc-fedora-mingw/gcc-build/x86_64-w64-mingw32/libstdc++-v3/include/bits/basic_string.h:4483:43:   required from here
 4483 |     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
 4484 |                                            "%f", __val);
      |                                            ~~~~~~~~~~~~
/home/builder/shared/bb2-1/worker/gcc-fedora-mingw/gcc-build/x86_64-w64-mingw32/libstdc++-v3/include/ext/string_conversions.h:103:5: internal compiler error: in apply_late_template_attributes, at cp/pt.cc:12403
  103 |     __to_xstring(int (*__convf) (_CharT*, std::size_t, const _CharT*,
      |     ^~~~~~~~~~~~
0x2529c91 internal_error(char const*, ...)
	  ../../gcc/gcc/diagnostic-global-context.cc:517
0x715e09 fancy_abort(char const*, int, char const*)
	 ../../gcc/gcc/diagnostic.cc:1722
0x4a4034 apply_late_template_attributes
	 ../../gcc/gcc/cp/pt.cc:12403
0x95be8d tsubst(tree_node*, tree_node*, int, tree_node*)
	 ../../gcc/gcc/cp/pt.cc:16951
0x9741c4 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:16022
0x9740e9 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:15999
0x9740e9 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:16058
0x9740e9 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:15999
0x9740e9 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:16058
0x9740e9 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:15999
0x9740e9 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:16058
0x974561 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:15999
0x974561 tsubst_function_type
	 ../../gcc/gcc/cp/pt.cc:16176
0x95bd6a tsubst(tree_node*, tree_node*, int, tree_node*)
	 ../../gcc/gcc/cp/pt.cc:17009
0x95afd7 tsubst(tree_node*, tree_node*, int, tree_node*)
	 ../../gcc/gcc/cp/pt.cc:16521
0x9741c4 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:16022
0x974561 tsubst_arg_types
	 ../../gcc/gcc/cp/pt.cc:15999
0x974561 tsubst_function_type
	 ../../gcc/gcc/cp/pt.cc:16176
0x95bd6a tsubst(tree_node*, tree_node*, int, tree_node*)
	 ../../gcc/gcc/cp/pt.cc:17009
0x96a866 tsubst_function_decl
	 ../../gcc/gcc/cp/pt.cc:14834
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
make[5]: *** [Makefile:883: codecvt.lo] Error 1

> --- gcc/cp/pt.cc.jj	2025-02-07 17:03:13.560227281 +0100
> +++ gcc/cp/pt.cc	2025-02-10 17:17:47.651313333 +0100
> @@ -16854,7 +16854,9 @@ tsubst (tree t, tree args, tsubst_flags_
>      case POINTER_TYPE:
>      case REFERENCE_TYPE:
>        {
> -	if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE)
> +	if (type == TREE_TYPE (t)
> +	    && TREE_CODE (type) != METHOD_TYPE
> +	    && TYPE_ATTRIBUTES (t) == NULL_TREE)
>  	  return t;
>  
>  	/* [temp.deduct]
> @@ -16924,9 +16926,9 @@ tsubst (tree t, tree args, tsubst_flags_
>  	     A,' while an attempt to create the type type rvalue reference to
>  	     cv T' creates the type T"
>  	  */
> -	  r = cp_build_reference_type
> -	      (TREE_TYPE (type),
> -	       TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
> +	  r = cp_build_reference_type (TREE_TYPE (type),
> +				       TYPE_REF_IS_RVALUE (t)
> +				       && TYPE_REF_IS_RVALUE (type));
>  	else
>  	  r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
>  	r = cp_build_qualified_type (r, cp_type_quals (t), complain);
> @@ -16935,6 +16937,11 @@ tsubst (tree t, tree args, tsubst_flags_
>  	  /* Will this ever be needed for TYPE_..._TO values?  */
>  	  layout_type (r);
>  
> +	if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
> +					     /*flags=*/0,
> +					     args, complain, in_decl))
> +	  return error_mark_node;
> +
>  	return r;
>        }
>      case OFFSET_TYPE:
> @@ -17009,7 +17016,9 @@ tsubst (tree t, tree args, tsubst_flags_
>  
>  	/* As an optimization, we avoid regenerating the array type if
>  	   it will obviously be the same as T.  */
> -	if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
> +	if (type == TREE_TYPE (t)
> +	    && domain == TYPE_DOMAIN (t)
> +	    && TYPE_ATTRIBUTES (t) == NULL_TREE)
>  	  return t;
>  
>  	/* These checks should match the ones in create_array_type_for_decl.
> @@ -17048,6 +17057,11 @@ tsubst (tree t, tree args, tsubst_flags_
>  	    TYPE_USER_ALIGN (r) = 1;
>  	  }
>  
> +	if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
> +					     /*flags=*/0,
> +					     args, complain, in_decl))
> +	  return error_mark_node;
> +
>  	return r;
>        }
>  
> --- gcc/testsuite/g++.dg/cpp0x/alignas22.C.jj	2025-02-10 17:33:16.242452750 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/alignas22.C	2025-02-10 17:36:28.739046629 +0100
> @@ -0,0 +1,23 @@
> +// PR c++/118787
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-pedantic" }
> +
> +template <typename T, int N>
> +void foo (T & alignas (N));		// { dg-warning "'alignas' on a type other than class" }
> +template <typename T, int N>
> +void bar (T (&)[N] alignas (N));	// { dg-warning "'alignas' on a type other than class" }
> +template <typename T, int N>
> +using U = T * alignas (N);		// { dg-warning "'alignas' on a type other than class" }
> +template <typename T, int N>
> +using V = T[N] alignas (N);		// { dg-warning "'alignas' on a type other than class" }
> +
> +void
> +baz ()
> +{
> +  int x alignas (4) = 0;
> +  foo <int, 4> (x);
> +  int y alignas (4) [4];
> +  bar <int, 4> (y);
> +  U <int, 4> u;
> +  V <int, 4> v;
> +}
> 
> 	Jakub
>
  

Patch

--- gcc/cp/pt.cc.jj	2025-02-07 17:03:13.560227281 +0100
+++ gcc/cp/pt.cc	2025-02-10 17:17:47.651313333 +0100
@@ -16854,7 +16854,9 @@  tsubst (tree t, tree args, tsubst_flags_
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-	if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE)
+	if (type == TREE_TYPE (t)
+	    && TREE_CODE (type) != METHOD_TYPE
+	    && TYPE_ATTRIBUTES (t) == NULL_TREE)
 	  return t;
 
 	/* [temp.deduct]
@@ -16924,9 +16926,9 @@  tsubst (tree t, tree args, tsubst_flags_
 	     A,' while an attempt to create the type type rvalue reference to
 	     cv T' creates the type T"
 	  */
-	  r = cp_build_reference_type
-	      (TREE_TYPE (type),
-	       TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
+	  r = cp_build_reference_type (TREE_TYPE (type),
+				       TYPE_REF_IS_RVALUE (t)
+				       && TYPE_REF_IS_RVALUE (type));
 	else
 	  r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
 	r = cp_build_qualified_type (r, cp_type_quals (t), complain);
@@ -16935,6 +16937,11 @@  tsubst (tree t, tree args, tsubst_flags_
 	  /* Will this ever be needed for TYPE_..._TO values?  */
 	  layout_type (r);
 
+	if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
+					     /*flags=*/0,
+					     args, complain, in_decl))
+	  return error_mark_node;
+
 	return r;
       }
     case OFFSET_TYPE:
@@ -17009,7 +17016,9 @@  tsubst (tree t, tree args, tsubst_flags_
 
 	/* As an optimization, we avoid regenerating the array type if
 	   it will obviously be the same as T.  */
-	if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
+	if (type == TREE_TYPE (t)
+	    && domain == TYPE_DOMAIN (t)
+	    && TYPE_ATTRIBUTES (t) == NULL_TREE)
 	  return t;
 
 	/* These checks should match the ones in create_array_type_for_decl.
@@ -17048,6 +17057,11 @@  tsubst (tree t, tree args, tsubst_flags_
 	    TYPE_USER_ALIGN (r) = 1;
 	  }
 
+	if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
+					     /*flags=*/0,
+					     args, complain, in_decl))
+	  return error_mark_node;
+
 	return r;
       }
 
--- gcc/testsuite/g++.dg/cpp0x/alignas22.C.jj	2025-02-10 17:33:16.242452750 +0100
+++ gcc/testsuite/g++.dg/cpp0x/alignas22.C	2025-02-10 17:36:28.739046629 +0100
@@ -0,0 +1,23 @@ 
+// PR c++/118787
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic" }
+
+template <typename T, int N>
+void foo (T & alignas (N));		// { dg-warning "'alignas' on a type other than class" }
+template <typename T, int N>
+void bar (T (&)[N] alignas (N));	// { dg-warning "'alignas' on a type other than class" }
+template <typename T, int N>
+using U = T * alignas (N);		// { dg-warning "'alignas' on a type other than class" }
+template <typename T, int N>
+using V = T[N] alignas (N);		// { dg-warning "'alignas' on a type other than class" }
+
+void
+baz ()
+{
+  int x alignas (4) = 0;
+  foo <int, 4> (x);
+  int y alignas (4) [4];
+  bar <int, 4> (y);
+  U <int, 4> u;
+  V <int, 4> v;
+}