https://gcc.gnu.org/g:23251983e020d265e8d40c7a48ba9b383d15e585

commit 23251983e020d265e8d40c7a48ba9b383d15e585
Author: Julian Brown <[email protected]>
Date:   Fri Apr 3 23:20:36 2026 +0000

    Various OpenACC reduction enhancements - FE changes
    
    gcc/c/ChangeLog
            * c-parser.cc (c_parser_omp_variable_list): New c_omp_region_type
            argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
            OpenACC.
            (c_parser_omp_var_list_parens): Add region-type argument to call.
            (c_parser_oacc_data_clause): Likewise.
            (c_parser_oacc_data_clause_deviceptr): Likewise.
            (c_parser_omp_clause_reduction): Change is_omp boolean parameter to
            c_omp_region_type.  Update call to c_parser_omp_variable_list.
            (c_parser_omp_clause_map): Update call to
            c_parser_omp_variable_list.
            (c_parser_omp_clause_from_to): Likewise.
            (c_parser_omp_clause_init): Likewise.
            (c_parser_oacc_all_clauses): Update calls to
            c_parser_omp_clause_reduction.
            (c_parser_omp_all_clauses): Likewise.
            (c_parser_oacc_cache): Update call to c_parser_omp_variable_list.
            * c-typeck.cc (c_finish_omp_clauses): Emit an error on orphan 
OpenACC
            gang reductions.  Suppress user-defined reduction error for OpenACC.
    
    gcc/cp/ChangeLog
            * parser.cc (cp_parser_omp_var_list_no_open):  New c_omp_region_type
            argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
            OpenACC.
            (cp_parser_omp_var_list): Add c_omp_region_type argument. Update 
call
            to cp_parser_omp_var_list_no_open.
            (cp_parser_oacc_data_clause): Update call to
            cp_parser_omp_var_list_no_open.
            (cp_parser_omp_clause_reduction): Change is_omp boolean parameter to
            c_omp_region_type.  Update call to cp_parser_omp_var_list_no_open.
            (cp_parser_omp_clause_from_to): Update call to
            cp_parser_omp_clause_var_list_no_open.
            (cp_parser_omp_clause_map): Likewise.
            (cp_parser_omp_clause_init): Likewise.
            (cp_parser_oacc_all_clauses): Update call to
            cp_parser_omp_clause_reduction.
            (cp_parser_omp_all_clauses): Likewise.
            * semantics.cc (finish_omp_reduction_clause): Add c_omp_region_type
            argument.  Suppress user-defined reduction error for OpenACC.
            (finish_omp_clauses): Update call to finish_omp_reduction_clause.
    
    gcc/fortran/ChangeLog
            * trans-openmp.cc (gfc_omp_clause_copy_ctor): Permit reductions.
    
    Co-Authored-By: Cesar Philippidis <[email protected]>
    Co-Authored-By: Nathan Sidwell <[email protected]>
    Co-Authored-By: Kwok Cheung Yeung  <[email protected]>

Diff:
---
 gcc/c/c-parser.cc           | 46 +++++++++++++++++++++++++--------------------
 gcc/c/c-typeck.cc           |  7 +++++--
 gcc/cp/parser.cc            | 33 +++++++++++++++++---------------
 gcc/cp/semantics.cc         | 13 ++++++++-----
 gcc/fortran/trans-openmp.cc |  3 ++-
 5 files changed, 59 insertions(+), 43 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 08a1b1e005c3..d521978c8aa0 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -16714,7 +16714,7 @@ c_parser_oacc_wait_list (c_parser *parser, location_t 
clause_loc, tree list)
    in TREE_PURPOSE and the location in TREE_VALUE (accessible using
    EXPR_LOCATION); return the list created.
 
-   The optional ALLOW_DEREF argument is true if list items can use the deref
+   The optional MAP_LVALUE argument is true if list items can use the deref
    (->) operator.  */
 
 struct omp_dim
@@ -16730,6 +16730,7 @@ static tree
 c_parser_omp_variable_list (c_parser *parser,
                            location_t clause_loc,
                            enum omp_clause_code kind, tree list,
+                           enum c_omp_region_type ort = C_ORT_OMP,
                            bool map_lvalue = false)
 {
   auto_vec<omp_dim> dims;
@@ -17002,7 +17003,8 @@ c_parser_omp_variable_list (c_parser *parser,
            case OMP_CLAUSE_HAS_DEVICE_ADDR:
              array_section_p = false;
              dims.truncate (0);
-             while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
+             while ((ort != C_ORT_ACC || kind != OMP_CLAUSE_REDUCTION)
+                    && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
                {
                  location_t loc = UNKNOWN_LOCATION;
                  tree low_bound = NULL_TREE, length = NULL_TREE;
@@ -17136,12 +17138,14 @@ c_parser_omp_variable_list (c_parser *parser,
 }
 
 /* Similarly, but expect leading and trailing parenthesis.  This is a very
-   common case for OpenACC and OpenMP clauses.  The optional ALLOW_DEREF
+   common case for OpenACC and OpenMP clauses.  The optional MAP_LVALUE
    argument is true if list items can use the deref (->) operator.  */
 
 static tree
 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
-                             tree list, bool map_lvalue = false)
+                             tree list,
+                             enum c_omp_region_type ort = C_ORT_OMP,
+                             bool map_lvalue = false)
 {
   /* The clauses location.  */
   location_t loc = c_parser_peek_token (parser)->location;
@@ -17162,7 +17166,8 @@ c_parser_omp_var_list_parens (c_parser *parser, enum 
omp_clause_code kind,
   matching_parens parens;
   if (parens.require_open (parser))
     {
-      list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue);
+      list = c_parser_omp_variable_list (parser, loc, kind, list, ort,
+                                        map_lvalue);
       parens.skip_until_found_close (parser);
     }
   return list;
@@ -17257,7 +17262,7 @@ c_parser_oacc_data_clause (c_parser *parser, 
pragma_omp_clause c_kind,
            }
        }
       nl = c_parser_omp_variable_list (parser, open_loc, OMP_CLAUSE_MAP, list,
-                                      false);
+                                      C_ORT_ACC, false);
       parens.skip_until_found_close (parser);
     }
 
@@ -17282,7 +17287,8 @@ c_parser_oacc_data_clause_deviceptr (c_parser *parser, 
tree list)
   /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
      c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
      variable-list must only allow for pointer variables.  */
-  vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
+  vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL,
+                                      C_ORT_ACC);
   for (t = vars; t && t; t = TREE_CHAIN (t))
     {
       tree v = TREE_PURPOSE (t);
@@ -18841,7 +18847,7 @@ c_parser_omp_clause_private (c_parser *parser, tree 
list)
 
 static tree
 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
-                              bool is_omp, tree list)
+                              enum c_omp_region_type ort, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   matching_parens parens;
@@ -18852,7 +18858,7 @@ c_parser_omp_clause_reduction (c_parser *parser, enum 
omp_clause_code kind,
       enum tree_code code = ERROR_MARK;
       tree reduc_id = NULL_TREE;
 
-      if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+      if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_OMP)
        {
          if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
              && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
@@ -18886,7 +18892,7 @@ c_parser_omp_clause_reduction (c_parser *parser, enum 
omp_clause_code kind,
          code = MULT_EXPR;
          break;
        case CPP_MINUS:
-         if (is_omp)
+         if (ort == C_ORT_OMP)
            {
              location_t loc = c_parser_peek_token (parser)->location;
              gcc_rich_location richloc (loc);
@@ -18942,7 +18948,8 @@ c_parser_omp_clause_reduction (c_parser *parser, enum 
omp_clause_code kind,
        {
          tree nl, c;
 
-         nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
+         nl = c_parser_omp_variable_list (parser, clause_loc, kind, list, ort);
+
          for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
            {
              tree d = OMP_CLAUSE_DECL (c), type;
@@ -20945,7 +20952,7 @@ c_parser_omp_clause_map (c_parser *parser, tree list, 
bool declare_mapper_p)
     }
 
   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
-                                  true);
+                                  C_ORT_OMP, true);
 
   tree last_new = NULL_TREE;
 
@@ -21375,7 +21382,7 @@ c_parser_omp_clause_from_to (c_parser *parser, enum 
omp_clause_code kind,
   if (colon_pos)
     c_parser_require (parser, CPP_COLON, "expected %<:%>");
 
-  tree nl = c_parser_omp_variable_list (parser, loc, kind, list);
+  tree nl = c_parser_omp_variable_list (parser, loc, kind, list, C_ORT_OMP);
   parens.skip_until_found_close (parser);
 
   if (present)
@@ -21960,8 +21967,7 @@ c_parser_omp_clause_init (c_parser *parser, tree list)
     error_at (loc,
              "missing required %<target%> and/or %<targetsync%> modifier");
 
-  tree nl = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_INIT, list,
-                                       false);
+  tree nl = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_INIT, list);
   parens.skip_until_found_close (parser);
 
   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
@@ -22153,7 +22159,7 @@ c_parser_oacc_all_clauses (c_parser *parser, 
omp_clause_mask mask,
        case PRAGMA_OACC_CLAUSE_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                            false, clauses);
+                                            C_ORT_ACC, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SELF:
@@ -22319,7 +22325,7 @@ c_parser_omp_all_clauses (c_parser *parser, 
omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
-                                            true, clauses);
+                                            C_ORT_OMP, clauses);
          c_name = "in_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_INDIRECT:
@@ -22365,7 +22371,7 @@ c_parser_omp_all_clauses (c_parser *parser, 
omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                            true, clauses);
+                                            C_ORT_OMP, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -22379,7 +22385,7 @@ c_parser_omp_all_clauses (c_parser *parser, 
omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
-                                            true, clauses);
+                                            C_ORT_OMP, clauses);
          c_name = "task_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_UNTIED:
@@ -22685,7 +22691,7 @@ c_parser_oacc_cache (location_t loc, c_parser *parser)
          readonly = true;
        }
       clauses = c_parser_omp_variable_list (parser, open_loc,
-                                           OMP_CLAUSE__CACHE_, NULL_TREE);
+                                           OMP_CLAUSE__CACHE_, NULL_TREE, 
C_ORT_ACC);
       parens.skip_until_found_close (parser);
     }
 
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index f246c6c524f3..15703cf166a5 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -16950,8 +16950,11 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
            }
          else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node)
            {
-             error_at (OMP_CLAUSE_LOCATION (c),
-                       "user defined reduction not found for %qE", t);
+             /* There are no user-defined reductions in OpenACC (as of
+                2.6).  */
+             if (ort & C_ORT_OMP)
+               error_at (OMP_CLAUSE_LOCATION (c),
+                         "user defined reduction not found for %qE", t);
              remove = true;
              break;
            }
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 9f305723acee..1cd827d47f66 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -41511,6 +41511,7 @@ struct omp_dim
 static tree
 cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
                                tree list, bool *colon,
+                               enum c_omp_region_type ort = C_ORT_OMP,
                                bool map_lvalue = false)
 {
   auto_vec<omp_dim> dims;
@@ -41727,7 +41728,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum 
omp_clause_code kind,
            case OMP_CLAUSE_HAS_DEVICE_ADDR:
              array_section_p = false;
              dims.truncate (0);
-             while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+             while ((ort != C_ORT_ACC || kind != OMP_CLAUSE_REDUCTION)
+                    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
                {
                  location_t loc = UNKNOWN_LOCATION;
                  tree low_bound = NULL_TREE, length = NULL_TREE;
@@ -41875,6 +41877,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum 
omp_clause_code kind,
 
 static tree
 cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree 
list,
+                       enum c_omp_region_type ort = C_ORT_OMP,
                        bool map_lvalue = false)
 {
   if (parser->lexer->in_omp_decl_attribute)
@@ -41893,7 +41896,7 @@ cp_parser_omp_var_list (cp_parser *parser, enum 
omp_clause_code kind, tree list,
     }
 
   if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
-    return cp_parser_omp_var_list_no_open (parser, kind, list, NULL,
+    return cp_parser_omp_var_list_no_open (parser, kind, list, NULL, ort,
                                           map_lvalue);
   return list;
 }
@@ -41985,7 +41988,7 @@ cp_parser_oacc_data_clause (cp_parser *parser, 
pragma_omp_clause c_kind,
            }
        }
       nl = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list, NULL,
-                                          false);
+                                          C_ORT_ACC, false);
     }
 
   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
@@ -43349,7 +43352,7 @@ cp_parser_omp_clause_ordered (cp_parser *parser,
 
 static tree
 cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
-                               bool is_omp, tree list)
+                               enum c_omp_region_type ort, tree list)
 {
   enum tree_code code = ERROR_MARK;
   tree nlist, c, id = NULL_TREE;
@@ -43359,7 +43362,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum 
omp_clause_code kind,
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
-  if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+  if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_OMP)
     {
       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT)
          && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
@@ -43389,7 +43392,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum 
omp_clause_code kind,
     case CPP_PLUS: code = PLUS_EXPR; break;
     case CPP_MULT: code = MULT_EXPR; break;
     case CPP_MINUS:
-      if (is_omp)
+      if (ort == C_ORT_OMP)
        {
          location_t loc = cp_lexer_peek_token (parser->lexer)->location;
          gcc_rich_location richloc (loc);
@@ -43467,8 +43470,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum 
omp_clause_code kind,
   if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
     goto resync_fail;
 
-  nlist = cp_parser_omp_var_list_no_open (parser, kind, list,
-                                         NULL);
+  nlist = cp_parser_omp_var_list_no_open (parser, kind, list, NULL, ort);
   for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
     {
       OMP_CLAUSE_REDUCTION_CODE (c) = code;
@@ -45301,7 +45303,8 @@ cp_parser_omp_clause_from_to (cp_parser *parser, enum 
omp_clause_code kind,
   if (colon_pos)
     cp_parser_require (parser, CPP_COLON, RT_COLON);
 
-  tree nl = cp_parser_omp_var_list_no_open (parser, kind, list, NULL, true);
+  tree nl = cp_parser_omp_var_list_no_open (parser, kind, list, NULL, 
C_ORT_OMP,
+                                           true);
   if (present)
     for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
       OMP_CLAUSE_MOTION_PRESENT (c) = 1;
@@ -45715,7 +45718,7 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, 
bool declare_mapper_p)
      legally.  */
   begin_scope (sk_omp, NULL);
   nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list,
-                                         NULL, true);
+                                         NULL, C_ORT_OMP, true);
   finish_scope ();
 
   tree last_new = NULL_TREE;
@@ -46422,7 +46425,7 @@ cp_parser_omp_clause_init (cp_parser *parser, tree list)
              "missing required %<target%> and/or %<targetsync%> modifier");
 
   tree nl = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_INIT, list,
-                                           NULL, false);
+                                           NULL);
   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
     {
       TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1;
@@ -46665,7 +46668,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
        case PRAGMA_OACC_CLAUSE_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                             false, clauses);
+                                             C_ORT_ACC, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SELF:
@@ -46863,7 +46866,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
-                                             true, clauses);
+                                             C_ORT_OMP, clauses);
          c_name = "in_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_INDIRECT:
@@ -46918,7 +46921,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                             true, clauses);
+                                             C_ORT_OMP, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -46935,7 +46938,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
          clauses
            = cp_parser_omp_clause_reduction (parser,
                                              OMP_CLAUSE_TASK_REDUCTION,
-                                             true, clauses);
+                                             C_ORT_OMP, clauses);
          c_name = "task_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_UNTIED:
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index bafb558b2594..b0bfc5a2a9d3 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -7223,7 +7223,8 @@ find_omp_placeholder_r (tree *tp, int *, void *data)
    Return true if there is some error and the clause should be removed.  */
 
 static bool
-finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
+finish_omp_reduction_clause (tree c, enum c_omp_region_type ort,
+                            bool *need_default_ctor, bool *need_dtor)
 {
   tree t = OMP_CLAUSE_DECL (c);
   bool predefined = false;
@@ -7469,9 +7470,11 @@ finish_omp_reduction_clause (tree c, bool 
*need_default_ctor, bool *need_dtor)
     *need_dtor = true;
   else
     {
-      error_at (OMP_CLAUSE_LOCATION (c),
-               "user defined reduction not found for %qE",
-               omp_clause_printable_decl (t));
+      /* There are no user-defined reductions for OpenACC (as of 2.6).  */
+      if (ort & C_ORT_OMP)
+       error_at (OMP_CLAUSE_LOCATION (c),
+                 "user defined reduction not found for %qE",
+                 omp_clause_printable_decl (t));
       return true;
     }
   if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
@@ -10536,7 +10539,7 @@ finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
          if (processing_template_decl
              && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
            break;
-         if (finish_omp_reduction_clause (c, &need_default_ctor,
+         if (finish_omp_reduction_clause (c, ort, &need_default_ctor,
                                           &need_dtor))
            remove = true;
          else
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index ab6f751a79e6..782ab7a15d4b 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -954,7 +954,8 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
   stmtblock_t block, cond_block;
 
   gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE
-             || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);
+             || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR
+             || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION);
 
   if (DECL_ARTIFICIAL (orig_decl)
       && DECL_LANG_SPECIFIC (orig_decl)

Reply via email to