* parser.c (cp_parser_direct_declarator): In a template, wrap
non-constant expression in NOP_EXPR with TREE_SIDE_EFFECTS set.
* pt.c (tsubst): Preserve it in a partial instantiation.
(dependent_type_p_r): Don't check value_dependent_expression_p.
* decl.c (compute_array_index_type): Don't check
value_dependent_expression_p if TREE_SIDE_EFFECTS.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@144988
138bc75d-0d04-0410-961f-
82ee72b054a4
2009-03-20 Jason Merrill <jason@redhat.com>
+ PR c++/28879
+ * parser.c (cp_parser_direct_declarator): In a template, wrap
+ non-constant expression in NOP_EXPR with TREE_SIDE_EFFECTS set.
+ * pt.c (tsubst): Preserve it in a partial instantiation.
+ (dependent_type_p_r): Don't check value_dependent_expression_p.
+ * decl.c (compute_array_index_type): Don't check
+ value_dependent_expression_p if TREE_SIDE_EFFECTS.
+
C++ core issue 703
* typeck2.c (check_narrowing): Don't complain about loss of
precision when converting a floating-point constant.
type = TREE_TYPE (size);
}
- if (value_dependent_expression_p (size))
- {
- /* We cannot do any checking for a value-dependent SIZE. Just
- build the index type and mark that it requires structural
- equality checks. */
+ /* We can only call value_dependent_expression_p on integral constant
+ expressions; the parser adds a dummy NOP_EXPR with TREE_SIDE_EFFECTS
+ set if this isn't one. */
+ if (processing_template_decl
+ && (TREE_SIDE_EFFECTS (size) || value_dependent_expression_p (size)))
+ {
+ /* We cannot do any checking for a SIZE that isn't known to be
+ constant. Just build the index type and mark that it requires
+ structural equality checks. */
itype = build_index_type (build_min (MINUS_EXPR, sizetype,
size, integer_one_node));
+ if (!TREE_SIDE_EFFECTS (size))
+ {
+ TYPE_DEPENDENT_P (itype) = 1;
+ TYPE_DEPENDENT_P_VALID (itype) = 1;
+ }
SET_TYPE_STRUCTURAL_EQUALITY (itype);
return itype;
}
&non_constant_p);
if (!non_constant_p)
bounds = fold_non_dependent_expr (bounds);
+ else if (processing_template_decl)
+ {
+ /* Remember this wasn't a constant-expression. */
+ bounds = build_nop (TREE_TYPE (bounds), bounds);
+ TREE_SIDE_EFFECTS (bounds) = 1;
+ }
+
/* Normally, the array bound must be an integral constant
expression. However, as an extension, we allow VLAs
in function scopes. */
/*integral_constant_expression_p=*/false);
max = fold_decl_constant_value (max);
+ /* If we're in a partial instantiation, preserve the magic NOP_EXPR
+ with TREE_SIDE_EFFECTS that indicates this is not an integral
+ constant expression. */
+ if (processing_template_decl
+ && TREE_SIDE_EFFECTS (omax) && TREE_CODE (omax) == NOP_EXPR)
+ {
+ gcc_assert (TREE_CODE (max) == NOP_EXPR);
+ TREE_SIDE_EFFECTS (max) = 1;
+ }
+
if (TREE_CODE (max) != INTEGER_CST
&& !at_function_scope_p ()
+ && !TREE_SIDE_EFFECTS (max)
&& !value_dependent_expression_p (max))
{
if (complain & tf_error)
&& !TREE_CONSTANT (TYPE_MAX_VALUE (type)))
{
/* If this is the TYPE_DOMAIN of an array type, consider it
- dependent. */
- return (value_dependent_expression_p (TYPE_MAX_VALUE (type))
- || type_dependent_expression_p (TYPE_MAX_VALUE (type)));
+ dependent. We already checked for value-dependence in
+ compute_array_index_type. */
+ return type_dependent_expression_p (TYPE_MAX_VALUE (type));
}
/* -- a template-id in which either the template name is a template
+2009-03-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/28879
+ * g++.dg/ext/vla6.C: New test.
+
2009-03-20 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/initlist5.C: Add additional test.
--- /dev/null
+// PR c++/28879
+// { dg-options "" }
+
+struct A
+{
+ int i;
+ A(): i(1) {}
+};
+
+template<int> void foo()
+{
+ int x[A().i];
+}
+
+void f()
+{
+ foo<1>();
+}