+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34051
+ PR c++/34055
+ PR c++/34102
+ PR c++/34103
+ * typeck.c (check_return_expr): If there are bare parameter packs
+ in the return value, set it to error_mark_node.
+ * tree.c (cp_walk_subtrees): Walk USING_DECL nodes.
+ * pt.c (find_parameter_packs_r): Look at the type of
+ IDENTIFIER_NODEs (e.g., for user-defined conversions).
+ (check_for_bare_parameter_packs): Flip the result: now returns
+ TRUE when there were bare parameter packs, FALSE otherwise.
+ (push_template_decl_real): Deal with flipped result of
+ check_for_bare_parameter_packs.
+ * semantics.c (finish_cond): If there are bare parameter packs in
+ the conditional, set it to error_mark_node.
+ (finish_expr_stmt): If there are bare parameter packs in the
+ expression, set it to error_mark_node.
+ (finish_for_expr): Ditto.
+ (finish_switch_cond): If there are bare parameter packs in
+ the conditional, set it to error_mark_node.
+ (finish_mem_initializers): If there are bare parameter packs in
+ the member initializer, set it to error_mark_node.
+ (finish_member_declaration): Check the attributes of the
+ declaration for bare parameter packs, and remove the attributes if
+ any have bare parameter packs.
+ * parser.c (cp_parser_using_declaration): Check the using
+ declaration for bare parameter packs.
+ (cp_parser_base_clause): If there are bare parameter packs in a
+ base specifier, don't add it to the chain.
+
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34314
{
/* Create the USING_DECL. */
decl = do_class_using_decl (parser->scope, identifier);
- /* Add it to the list of members in this class. */
- finish_member_declaration (decl);
+
+ if (check_for_bare_parameter_packs (&decl))
+ return false;
+ else
+ /* Add it to the list of members in this class. */
+ finish_member_declaration (decl);
}
else
{
decl = cp_parser_lookup_name_simple (parser, identifier);
if (decl == error_mark_node)
cp_parser_name_lookup_error (parser, identifier, decl, NULL);
+ else if (check_for_bare_parameter_packs (&decl))
+ return false;
else if (!at_namespace_scope_p ())
do_local_using_decl (decl, qscope, identifier);
else
if (pack_expansion_p)
/* Make this a pack expansion type. */
TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
- else
- check_for_bare_parameter_packs (&TREE_VALUE (base));
+
- TREE_CHAIN (base) = bases;
- bases = base;
+ if (!check_for_bare_parameter_packs (&TREE_VALUE (base)))
+ {
+ TREE_CHAIN (base) = bases;
+ bases = base;
+ }
}
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
*walk_subtrees = 0;
return NULL_TREE;
+ case IDENTIFIER_NODE:
+ cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, NULL);
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
default:
return NULL_TREE;
}
g(h(args)), or f(g(h(args))), because we would produce erroneous
error messages.
- Returns TRUE if there were no bare parameter packs, returns FALSE
- (and emits an error) if there were bare parameter packs.*/
+ Returns TRUE and emits an error if there were bare parameter packs,
+ returns FALSE otherwise. */
bool
check_for_bare_parameter_packs (tree* t)
{
struct find_parameter_pack_data ppd;
if (!processing_template_decl || !t || !*t || *t == error_mark_node)
- return true;
+ return false;
if (TREE_CODE (*t) == TYPE_DECL)
t = &TREE_TYPE (*t);
cp_walk_tree (t, &find_parameter_packs_r, &ppd, NULL);
pointer_set_destroy (ppd.visited);
- return false;
+ return true;
}
- return true;
+ return false;
}
/* Expand any parameter packs that occur in the template arguments in
while (arg && argtype)
{
if (!FUNCTION_PARAMETER_PACK_P (arg)
- && !check_for_bare_parameter_packs (&TREE_TYPE (arg)))
+ && check_for_bare_parameter_packs (&TREE_TYPE (arg)))
{
/* This is a PARM_DECL that contains unexpanded parameter
packs. We have already complained about this in the
/* Check for bare parameter packs in the return type and the
exception specifiers. */
- if (!check_for_bare_parameter_packs (&TREE_TYPE (type)))
+ if (check_for_bare_parameter_packs (&TREE_TYPE (type)))
/* Errors were already issued, set return type to int
as the frontend doesn't expect error_mark_node as
the return type. */
TREE_TYPE (type) = integer_type_node;
check_for_bare_parameter_packs (&TYPE_RAISES_EXCEPTIONS (type));
}
- else if (!check_for_bare_parameter_packs (&TREE_TYPE (decl)))
+ else if (check_for_bare_parameter_packs (&TREE_TYPE (decl)))
return error_mark_node;
if (is_partial)
if (TREE_CODE (cond) == DECL_EXPR)
expr = cond;
- check_for_bare_parameter_packs (&expr);
+ if (check_for_bare_parameter_packs (&expr))
+ *cond_p = error_mark_node;
}
*cond_p = expr;
}
else if (!type_dependent_expression_p (expr))
convert_to_void (build_non_dependent_expr (expr), "statement");
- check_for_bare_parameter_packs (&expr);
+ if (check_for_bare_parameter_packs (&expr))
+ expr = error_mark_node;
/* Simplification of inner statement expressions, compound exprs,
etc can result in us already having an EXPR_STMT. */
else if (!type_dependent_expression_p (expr))
convert_to_void (build_non_dependent_expr (expr), "3rd expression in for");
expr = maybe_cleanup_point_expr_void (expr);
- check_for_bare_parameter_packs (&expr);
+ if (check_for_bare_parameter_packs (&expr))
+ expr = error_mark_node;
FOR_EXPR (for_stmt) = expr;
}
cond = index;
}
}
- check_for_bare_parameter_packs (&cond);
+ if (check_for_bare_parameter_packs (&cond))
+ cond = error_mark_node;
finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
SWITCH_STMT_TYPE (switch_stmt) = orig_type;
add_stmt (switch_stmt);
any parameter packs in the TREE_VALUE have already been
bound as part of the TREE_PURPOSE. See
make_pack_expansion for more information. */
- if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION)
- check_for_bare_parameter_packs (&TREE_VALUE (mem));
+ if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION
+ && check_for_bare_parameter_packs (&TREE_VALUE (mem)))
+ TREE_VALUE (mem) = error_mark_node;
}
add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits));
/* Check for bare parameter packs in the member variable declaration. */
if (TREE_CODE (decl) == FIELD_DECL)
- check_for_bare_parameter_packs (&TREE_TYPE (decl));
+ {
+ if (check_for_bare_parameter_packs (&TREE_TYPE (decl)))
+ TREE_TYPE (decl) = error_mark_node;
+ if (check_for_bare_parameter_packs (&DECL_ATTRIBUTES (decl)))
+ DECL_ATTRIBUTES (decl) = NULL_TREE;
+ }
/* [dcl.link]
*walk_subtrees_p = 0;
break;
+ case USING_DECL:
+ WALK_SUBTREE (DECL_NAME (*tp));
+ WALK_SUBTREE (USING_DECL_SCOPE (*tp));
+ WALK_SUBTREE (USING_DECL_DECLS (*tp));
+ *walk_subtrees_p = 0;
+ break;
+
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (*tp))
WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (*tp));
if (processing_template_decl)
{
current_function_returns_value = 1;
- check_for_bare_parameter_packs (&retval);
+ if (check_for_bare_parameter_packs (&retval))
+ retval = error_mark_node;
return retval;
}
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34051
+ PR c++/34055
+ PR c++/34102
+ PR c++/34103
+ * g++.dg/cpp0x/vt-34051-2.C: New.
+ * g++.dg/cpp0x/vt-34102.C: New.
+ * g++.dg/cpp0x/vt-34051.C: New.
+ * g++.dg/cpp0x/vt-34055.C: New.
+ * g++.dg/cpp0x/vt-34103.C: New.
+
+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34314
+ * g++.dg/cpp0x/vt-34314.C: New.
+ * g++.dg/cpp0x/variadic79.C: Fix the error message to reflect
+ reality (the error message was wrong previously).
+
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33964
--- /dev/null
+// { dg-options "-std=c++0x" }
+template<typename... T> struct A
+{
+ int i __attribute__((aligned(__alignof(T)))); // { dg-error "parameter packs|T" }
+};
+
+A<int> a;
--- /dev/null
+// { dg-options "-std=c++0x" }
+struct A
+{
+ operator int();
+};
+
+template <typename... T> struct B : A
+{
+ using A::operator T; // { dg-error "parameter packs|T" }
+};
+
+B<int> b;
--- /dev/null
+// { dg-options "-std=c++0x" }
+// PR c++/34055
+template<typename...> struct A; // { dg-error "declaration" }
+
+template<typename...T> struct A<T*> // { dg-error "parameter packs|T" }
+{
+ void foo();
+};
+
+template<typename...T> void A<T*>::foo() {} // { dg-error "invalid use" }
--- /dev/null
+// { dg-options "-std=c++0x" }
+// PR c++/34102
+struct A {};
+
+template<typename> struct B : virtual A {};
+
+template<typename...T> struct C : B<T> {}; // { dg-error "parameter packs|T" }
--- /dev/null
+// { dg-options "-std=c++0x" }
+// PR c++/34103
+template<typename> struct A {};
+
+template<typename...T> void foo(A<T>, A<T>); // { dg-error "parameter packs|T" }
+
+template<typename...T> void foo(A<T>, A<T>) {} // { dg-error "parameter packs|T" }