re PR c++/53549 (g++ and armadillo 3.2.0, operator() is inaccessible)
PR c++/53549 * parser.c (cp_parser_class_head): Call xref_basetypes here. (cp_parser_class_specifier_1): Not here. * pt.c (tsubst_decl) [USING_DECL]: Check uses_template_parms as well as DECL_DEPENDENT_P. From-SVN: r189582
This commit is contained in:
parent
65876d249e
commit
ec44e46396
|
@ -1,3 +1,11 @@
|
||||||
|
2012-07-17 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/53549
|
||||||
|
* parser.c (cp_parser_class_head): Call xref_basetypes here.
|
||||||
|
(cp_parser_class_specifier_1): Not here.
|
||||||
|
* pt.c (tsubst_decl) [USING_DECL]: Check uses_template_parms
|
||||||
|
as well as DECL_DEPENDENT_P.
|
||||||
|
|
||||||
2012-07-16 Jason Merrill <jason@redhat.com>
|
2012-07-16 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
* cp-tree.h (struct deferred_access_check): Add location.
|
* cp-tree.h (struct deferred_access_check): Add location.
|
||||||
|
|
|
@ -2008,7 +2008,7 @@ static tree cp_parser_class_name
|
||||||
static tree cp_parser_class_specifier
|
static tree cp_parser_class_specifier
|
||||||
(cp_parser *);
|
(cp_parser *);
|
||||||
static tree cp_parser_class_head
|
static tree cp_parser_class_head
|
||||||
(cp_parser *, bool *, tree *);
|
(cp_parser *, bool *);
|
||||||
static enum tag_types cp_parser_class_key
|
static enum tag_types cp_parser_class_key
|
||||||
(cp_parser *);
|
(cp_parser *);
|
||||||
static void cp_parser_member_specification_opt
|
static void cp_parser_member_specification_opt
|
||||||
|
@ -17961,15 +17961,13 @@ cp_parser_class_specifier_1 (cp_parser* parser)
|
||||||
bool saved_in_unbraced_linkage_specification_p;
|
bool saved_in_unbraced_linkage_specification_p;
|
||||||
tree old_scope = NULL_TREE;
|
tree old_scope = NULL_TREE;
|
||||||
tree scope = NULL_TREE;
|
tree scope = NULL_TREE;
|
||||||
tree bases;
|
|
||||||
cp_token *closing_brace;
|
cp_token *closing_brace;
|
||||||
|
|
||||||
push_deferring_access_checks (dk_no_deferred);
|
push_deferring_access_checks (dk_no_deferred);
|
||||||
|
|
||||||
/* Parse the class-head. */
|
/* Parse the class-head. */
|
||||||
type = cp_parser_class_head (parser,
|
type = cp_parser_class_head (parser,
|
||||||
&nested_name_specifier_p,
|
&nested_name_specifier_p);
|
||||||
&bases);
|
|
||||||
/* If the class-head was a semantic disaster, skip the entire body
|
/* If the class-head was a semantic disaster, skip the entire body
|
||||||
of the class. */
|
of the class. */
|
||||||
if (!type)
|
if (!type)
|
||||||
|
@ -17986,18 +17984,6 @@ cp_parser_class_specifier_1 (cp_parser* parser)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the base classes. If they're invalid, skip the
|
|
||||||
entire class body. */
|
|
||||||
if (!xref_basetypes (type, bases))
|
|
||||||
{
|
|
||||||
/* Consuming the closing brace yields better error messages
|
|
||||||
later on. */
|
|
||||||
if (cp_parser_skip_to_closing_brace (parser))
|
|
||||||
cp_lexer_consume_token (parser->lexer);
|
|
||||||
pop_deferring_access_checks ();
|
|
||||||
return error_mark_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Issue an error message if type-definitions are forbidden here. */
|
/* Issue an error message if type-definitions are forbidden here. */
|
||||||
cp_parser_check_type_definition (parser);
|
cp_parser_check_type_definition (parser);
|
||||||
/* Remember that we are defining one more class. */
|
/* Remember that we are defining one more class. */
|
||||||
|
@ -18283,14 +18269,14 @@ cp_parser_class_specifier (cp_parser* parser)
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
cp_parser_class_head (cp_parser* parser,
|
cp_parser_class_head (cp_parser* parser,
|
||||||
bool* nested_name_specifier_p,
|
bool* nested_name_specifier_p)
|
||||||
tree *bases)
|
|
||||||
{
|
{
|
||||||
tree nested_name_specifier;
|
tree nested_name_specifier;
|
||||||
enum tag_types class_key;
|
enum tag_types class_key;
|
||||||
tree id = NULL_TREE;
|
tree id = NULL_TREE;
|
||||||
tree type = NULL_TREE;
|
tree type = NULL_TREE;
|
||||||
tree attributes;
|
tree attributes;
|
||||||
|
tree bases;
|
||||||
cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
|
cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
|
||||||
bool template_id_p = false;
|
bool template_id_p = false;
|
||||||
bool qualified_p = false;
|
bool qualified_p = false;
|
||||||
|
@ -18307,8 +18293,6 @@ cp_parser_class_head (cp_parser* parser,
|
||||||
num_templates = 0;
|
num_templates = 0;
|
||||||
parser->colon_corrects_to_scope_p = false;
|
parser->colon_corrects_to_scope_p = false;
|
||||||
|
|
||||||
*bases = NULL_TREE;
|
|
||||||
|
|
||||||
/* Look for the class-key. */
|
/* Look for the class-key. */
|
||||||
class_key = cp_parser_class_key (parser);
|
class_key = cp_parser_class_key (parser);
|
||||||
if (class_key == none_type)
|
if (class_key == none_type)
|
||||||
|
@ -18671,7 +18655,15 @@ cp_parser_class_head (cp_parser* parser,
|
||||||
|
|
||||||
/* Get the list of base-classes, if there is one. */
|
/* Get the list of base-classes, if there is one. */
|
||||||
if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
|
if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
|
||||||
*bases = cp_parser_base_clause (parser);
|
bases = cp_parser_base_clause (parser);
|
||||||
|
else
|
||||||
|
bases = NULL_TREE;
|
||||||
|
|
||||||
|
/* If we're really defining a class, process the base classes.
|
||||||
|
If they're invalid, fail. */
|
||||||
|
if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
|
||||||
|
&& !xref_basetypes (type, bases))
|
||||||
|
type = NULL_TREE;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* Leave the scope given by the nested-name-specifier. We will
|
/* Leave the scope given by the nested-name-specifier. We will
|
||||||
|
|
|
@ -10235,8 +10235,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USING_DECL:
|
case USING_DECL:
|
||||||
/* We reach here only for member using decls. */
|
/* We reach here only for member using decls. We also need to check
|
||||||
if (DECL_DEPENDENT_P (t))
|
uses_template_parms because DECL_DEPENDENT_P is not set for a
|
||||||
|
using-declaration that designates a member of the current
|
||||||
|
instantiation (c++/53549). */
|
||||||
|
if (DECL_DEPENDENT_P (t)
|
||||||
|
|| uses_template_parms (USING_DECL_SCOPE (t)))
|
||||||
{
|
{
|
||||||
r = do_class_using_decl
|
r = do_class_using_decl
|
||||||
(tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl),
|
(tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl),
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2012-07-17 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/53549
|
||||||
|
* g++.dg/template/current-inst1.C: New.
|
||||||
|
* g++.dg/parse/crash35.C: Adjust.
|
||||||
|
|
||||||
2012-07-17 Tobias Burnus <burnus@net-b.de>
|
2012-07-17 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
PR fortran/52101
|
PR fortran/52101
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
|
|
||||||
struct a {};
|
struct a {};
|
||||||
|
|
||||||
class foo : public a, a
|
class foo : public a, a // { dg-error "duplicate base" }
|
||||||
{ /* { dg-error "duplicate base type|at end of input" } */
|
{ /* { dg-error "at end of input" } */
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
// PR c++/53549
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct C2
|
||||||
|
{
|
||||||
|
int operator()();
|
||||||
|
|
||||||
|
template<int> struct F2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<int I>
|
||||||
|
struct C2<T>::F2 : C2<T>
|
||||||
|
{
|
||||||
|
using C2<T>::operator();
|
||||||
|
};
|
||||||
|
|
||||||
|
C2<int>::F2<42> f;
|
Loading…
Reference in New Issue