diff mbox series

[pushed] c++: dependent attribute on parameter [PR97900]

Message ID 20210403055316.678041-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: dependent attribute on parameter [PR97900] | expand

Commit Message

Jason Merrill April 3, 2021, 5:53 a.m. UTC
We were copying attributes from the template to the instantiation without
considering that they might be dependent.  To make sure that the new parms
have the appropriate properties for the code pattern, let's just regenerate
them.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

	PR c++/97900
	* pt.c (regenerate_decl_from_template): tsubst_decl
	the parms.

gcc/testsuite/ChangeLog:

	PR c++/97900
	* g++.dg/ext/vector40.C: New test.
---
 gcc/cp/pt.c                         | 67 ++++-------------------------
 gcc/testsuite/g++.dg/ext/vector40.C | 10 +++++
 2 files changed, 19 insertions(+), 58 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/vector40.C


base-commit: 2a26351b598242c2fbce95d2a0baacce0084aec6
diff mbox series

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 524a16ab0c6..68ee71397d0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -25364,8 +25364,6 @@  regenerate_decl_from_template (tree decl, tree tmpl, tree args)
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
-      tree decl_parm;
-      tree pattern_parm;
       tree specs;
       int args_depth;
       int parms_depth;
@@ -25389,65 +25387,18 @@  regenerate_decl_from_template (tree decl, tree tmpl, tree args)
 	  }
 
       /* Merge parameter declarations.  */
-      decl_parm = skip_artificial_parms_for (decl,
-					     DECL_ARGUMENTS (decl));
-      pattern_parm
-	= skip_artificial_parms_for (code_pattern,
-				     DECL_ARGUMENTS (code_pattern));
-      while (decl_parm && !DECL_PACK_P (pattern_parm))
+      if (tree pattern_parm
+	  = skip_artificial_parms_for (code_pattern,
+				       DECL_ARGUMENTS (code_pattern)))
 	{
-	  tree parm_type;
-	  tree attributes;
-
-	  if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
-	    DECL_NAME (decl_parm) = DECL_NAME (pattern_parm);
-	  parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error,
-			      NULL_TREE);
-	  parm_type = type_decays_to (parm_type);
-	  if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
-	    TREE_TYPE (decl_parm) = parm_type;
-	  attributes = DECL_ATTRIBUTES (pattern_parm);
-	  if (DECL_ATTRIBUTES (decl_parm) != attributes)
-	    {
-	      DECL_ATTRIBUTES (decl_parm) = attributes;
-	      cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0);
-	    }
-	  decl_parm = DECL_CHAIN (decl_parm);
-	  pattern_parm = DECL_CHAIN (pattern_parm);
+	  tree *p = &DECL_ARGUMENTS (decl);
+	  for (int skip = num_artificial_parms_for (decl); skip; --skip)
+	    p = &DECL_CHAIN (*p);
+	  *p = tsubst_decl (pattern_parm, args, tf_error);
+	  for (tree t = *p; t; t = DECL_CHAIN (t))
+	    DECL_CONTEXT (t) = decl;
 	}
-      /* Merge any parameters that match with the function parameter
-         pack.  */
-      if (pattern_parm && DECL_PACK_P (pattern_parm))
-        {
-          int i, len;
-          tree expanded_types;
-          /* Expand the TYPE_PACK_EXPANSION that provides the types for
-             the parameters in this function parameter pack.  */
-          expanded_types = tsubst_pack_expansion (TREE_TYPE (pattern_parm), 
-                                                 args, tf_error, NULL_TREE);
-          len = TREE_VEC_LENGTH (expanded_types);
-          for (i = 0; i < len; i++)
-            {
-              tree parm_type;
-              tree attributes;
 
-              if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
-                /* Rename the parameter to include the index.  */
-                DECL_NAME (decl_parm) = 
-                  make_ith_pack_parameter_name (DECL_NAME (pattern_parm), i);
-              parm_type = TREE_VEC_ELT (expanded_types, i);
-              parm_type = type_decays_to (parm_type);
-              if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
-                TREE_TYPE (decl_parm) = parm_type;
-              attributes = DECL_ATTRIBUTES (pattern_parm);
-              if (DECL_ATTRIBUTES (decl_parm) != attributes)
-                {
-                  DECL_ATTRIBUTES (decl_parm) = attributes;
-                  cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0);
-                }
-              decl_parm = DECL_CHAIN (decl_parm);
-            }
-        }
       /* Merge additional specifiers from the CODE_PATTERN.  */
       if (DECL_DECLARED_INLINE_P (code_pattern)
 	  && !DECL_DECLARED_INLINE_P (decl))
diff --git a/gcc/testsuite/g++.dg/ext/vector40.C b/gcc/testsuite/g++.dg/ext/vector40.C
new file mode 100644
index 00000000000..885afb058a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector40.C
@@ -0,0 +1,10 @@ 
+// PR c++/97900
+
+template<typename T>
+T test(T __attribute__((vector_size(2 * sizeof(T)))) vec) {
+    return vec[0] + vec[1];
+}
+typedef int v2si __attribute__((vector_size(2 * sizeof(int))));
+int run(v2si vec) {
+    return test<int>(vec);
+}