Hi Alex,

and this is how this could potentially be used
in _Countof.

Martin

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index ed6e56e7279..b46eb43bb5a 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -3771,6 +3771,26 @@ is_top_array_vla (tree type)
   return var;
 }
 
+
+tree
+c_array_parm_orig_type (tree expr)
+{
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (expr)));
+
+  if (TREE_CODE (expr) == PARM_DECL
+      && C_ARRAY_PARAMETER (expr))
+    {
+      if (tree attr = lookup_attribute ("arg spec", DECL_ATTRIBUTES (expr)))
+       {
+         tree arg = TREE_CHAIN (TREE_VALUE (attr));
+         if (arg)
+           return TREE_VALUE (arg);
+       }
+    }
+
+  return NULL_TREE;
+}
+
 /* Return the result of countof applied to EXPR.  */
 
 struct c_expr
@@ -3788,16 +3808,27 @@ c_expr_countof_expr (location_t loc, struct c_expr expr)
   else
     {
       bool expr_const_operands = true;
+      ret.original_code = COUNTOF_EXPR;
+      ret.original_type = NULL;
+      ret.m_decimal = 0;
 
       tree folded_expr = c_fully_fold (expr.value, require_constant_value,
                                       &expr_const_operands);
-      ret.value = c_countof_type (loc, TREE_TYPE (folded_expr));
+
+      tree type = TREE_TYPE (folded_expr);
+      if (POINTER_TYPE_P (type))
+       {
+         if (tree rv = c_array_parm_orig_type (folded_expr))
+           {
+             type = rv;
+           }
+       }
+
+      ret.value = c_countof_type (loc, type);
       c_last_sizeof_arg = expr.value;
       c_last_sizeof_loc = loc;
-      ret.original_code = COUNTOF_EXPR;
-      ret.original_type = NULL;
-      ret.m_decimal = 0;
-      if (is_top_array_vla (TREE_TYPE (folded_expr)))
+
+      if (is_top_array_vla (type))
        {
          /* countof is evaluated when given a vla.  */
          ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value),
@@ -3805,7 +3836,7 @@ c_expr_countof_expr (location_t loc, struct c_expr expr)
          C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !expr_const_operands;
          SET_EXPR_LOCATION (ret.value, loc);
        }
-      pop_maybe_used (is_top_array_vla (TREE_TYPE (folded_expr)));
+      pop_maybe_used (is_top_array_vla (type));
     }
   return ret;
 }
diff --git a/gcc/testsuite/gcc.dg/countof-compile.c 
b/gcc/testsuite/gcc.dg/countof-compile.c
index afd5659618b..aa6816c9db4 100644
--- a/gcc/testsuite/gcc.dg/countof-compile.c
+++ b/gcc/testsuite/gcc.dg/countof-compile.c
@@ -38,12 +38,16 @@ fam (void)
   _Countof (s.fam); /* { dg-error "incomplete" } */
 }
 
+void
+param_const (int p[4])
+{
+  _Countof (p);
+}
+
 void
 param (int n, int p[n])
 {
-  /* We want to support array parameters in the future,
-     which would make this work.  */
-  _Countof (p);  /* { dg-error "invalid" } */
+  _Countof (p);
 }
 
 void fix_fix (int i, char (*a)[3][5], int (*x)[_Countof (*a)],




Reply via email to