re PR c++/51184 (Abstract class in function return type)
/cp 2012-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51184 * decl.c (grokdeclarator): Diagnose functions returning abstract class types as TYPENAME. * cp-tree.h (ABSTRACT_CLASS_TYPE_P): Add. * except.c (is_admissible_throw_operand_or_catch_parameter): Use it. * pt.c (tsubst): Likewise. * semantics.c (trait_expr_value): Likewise. /testsuite 2012-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51184 * g++.dg/other/abstract4.C: New- /cp 2012-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/40821 * parser.c (cp_parser_attributes_opt): Enforce error checking of unbalanced parentheses in the presence of tentative parsing. /testsuite 2012-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/40821 * g++.dg/ext/attrib46.C: New. From-SVN: r187720
This commit is contained in:
parent
cb0c9fc305
commit
94ccc95d41
|
@ -1,3 +1,19 @@
|
|||
2012-05-21 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/51184
|
||||
* decl.c (grokdeclarator): Diagnose functions returning abstract
|
||||
class types as TYPENAME.
|
||||
* cp-tree.h (ABSTRACT_CLASS_TYPE_P): Add.
|
||||
* except.c (is_admissible_throw_operand_or_catch_parameter): Use it.
|
||||
* pt.c (tsubst): Likewise.
|
||||
* semantics.c (trait_expr_value): Likewise.
|
||||
|
||||
2012-05-21 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/40821
|
||||
* parser.c (cp_parser_attributes_opt): Enforce error checking of
|
||||
unbalanced parentheses in the presence of tentative parsing.
|
||||
|
||||
2012-05-17 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/39681
|
||||
|
|
|
@ -1658,6 +1658,10 @@ struct GTY((variable_size)) lang_type {
|
|||
#define CLASSTYPE_PURE_VIRTUALS(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals)
|
||||
|
||||
/* Nonzero means that this type is an abstract class type. */
|
||||
#define ABSTRACT_CLASS_TYPE_P(NODE) \
|
||||
(CLASS_TYPE_P (NODE) && CLASSTYPE_PURE_VIRTUALS(NODE))
|
||||
|
||||
/* Nonzero means that this type has an X() constructor. */
|
||||
#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)
|
||||
|
|
|
@ -9194,6 +9194,11 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
error ("%qs declared as function returning an array", name);
|
||||
return error_mark_node;
|
||||
}
|
||||
/* When decl_context == NORMAL we emit a better error message
|
||||
later in abstract_virtuals_error. */
|
||||
if (decl_context == TYPENAME && ABSTRACT_CLASS_TYPE_P (type))
|
||||
error ("%qs declared as function returning an abstract "
|
||||
"class type", name);
|
||||
|
||||
/* Pick up type qualifiers which should be applied to `this'. */
|
||||
memfn_quals = declarator->u.function.qualifiers;
|
||||
|
|
|
@ -974,7 +974,7 @@ is_admissible_throw_operand_or_catch_parameter (tree t, bool is_throw)
|
|||
/* 10.4/3 An abstract class shall not be used as a parameter type,
|
||||
as a function return type or as type of an explicit
|
||||
conversion. */
|
||||
else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
|
||||
else if (ABSTRACT_CLASS_TYPE_P (type))
|
||||
{
|
||||
if (is_throw)
|
||||
error ("expression %qE of abstract class type %qT cannot "
|
||||
|
|
|
@ -20052,6 +20052,7 @@ cp_parser_attributes_opt (cp_parser* parser)
|
|||
{
|
||||
cp_token *token;
|
||||
tree attribute_list;
|
||||
bool ok = true;
|
||||
|
||||
/* Peek at the next token. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
|
@ -20076,8 +20077,12 @@ cp_parser_attributes_opt (cp_parser* parser)
|
|||
attribute_list = NULL;
|
||||
|
||||
/* Look for the two `)' tokens. */
|
||||
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
|
||||
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
|
||||
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
|
||||
ok = false;
|
||||
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
|
||||
ok = false;
|
||||
if (!ok)
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
|
||||
/* Add these new attributes to the list. */
|
||||
attributes = chainon (attributes, attribute_list);
|
||||
|
|
|
@ -11646,7 +11646,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
|||
error ("creating array of %qT", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
|
||||
if (ABSTRACT_CLASS_TYPE_P (type))
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("creating array of %qT, which is an abstract class type",
|
||||
|
|
|
@ -5441,7 +5441,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
|
|||
return type_has_virtual_destructor (type1);
|
||||
|
||||
case CPTK_IS_ABSTRACT:
|
||||
return (CLASS_TYPE_P (type1) && CLASSTYPE_PURE_VIRTUALS (type1));
|
||||
return (ABSTRACT_CLASS_TYPE_P (type1));
|
||||
|
||||
case CPTK_IS_BASE_OF:
|
||||
return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2012-05-21 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/51184
|
||||
* g++.dg/other/abstract4.C: New-
|
||||
|
||||
2012-05-21 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/40821
|
||||
* g++.dg/ext/attrib46.C: New.
|
||||
|
||||
2012-05-21 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/53148
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
// PR c++/40821
|
||||
|
||||
struct __attribute__((aligned(8)) S1 { int i; }; // { dg-error "expected" }
|
||||
struct __attribute__( aligned(8) S2 { int i; }; // { dg-error "expected" }
|
|
@ -0,0 +1,18 @@
|
|||
// PR c++/51184
|
||||
|
||||
template<typename T>
|
||||
struct S { };
|
||||
|
||||
template<typename T>
|
||||
void foo();
|
||||
|
||||
struct Abs
|
||||
{
|
||||
virtual void bar() = 0;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
S<Abs(int)> s; // { dg-error "abstract" }
|
||||
foo<Abs(int)>(); // { dg-error "abstract" }
|
||||
}
|
Loading…
Reference in New Issue