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)],