re PR c++/51047 ([C++0x] SFINAE does not handle errors of ambiguous base members)
/cp 2011-11-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51047 * search.c (lookup_member): Change to take also a tsubst_flags_t parameter. (lookup_field, lookup_fnfields): Adjust calls. * typeck.c (lookup_destructor, finish_class_member_access_expr, build_ptrmemfunc_access_expr): Likewise. * class.c (handle_using_decl, maybe_note_name_used_in_class): Likewise. * pt.c (resolve_typename_type): Likewise. * semantics.c (lambda_function): Likewise. * parser.c (cp_parser_perform_range_for_lookup, cp_parser_lookup_name): Likewise. * friend.c (make_friend_class): Likewise. * name-lookup.c (pushdecl_maybe_friend_1, get_class_binding, do_class_using_decl, lookup_qualified_name): Likewise. * cp-tree.h (lookup_member): Adjust declaration. /testsuite 2011-11-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51047 * g++.dg/cpp0x/sfinae29.C: New. From-SVN: r181213
This commit is contained in:
parent
60858d8a32
commit
db422ace3f
@ -1167,7 +1167,8 @@ handle_using_decl (tree using_decl, tree t)
|
||||
|
||||
gcc_assert (!processing_template_decl && decl);
|
||||
|
||||
old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false);
|
||||
old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
if (old_value)
|
||||
{
|
||||
if (is_overloaded_fn (old_value))
|
||||
@ -7290,7 +7291,7 @@ maybe_note_name_used_in_class (tree name, tree decl)
|
||||
/* If there's already a binding for this NAME, then we don't have
|
||||
anything to worry about. */
|
||||
if (lookup_member (current_class_type, name,
|
||||
/*protect=*/0, /*want_type=*/false))
|
||||
/*protect=*/0, /*want_type=*/false, tf_warning_or_error))
|
||||
return;
|
||||
|
||||
if (!current_class_stack[current_class_depth - 1].names_used)
|
||||
|
@ -5367,7 +5367,8 @@ extern tree lookup_fnfields_slot (tree, tree);
|
||||
extern tree lookup_fnfields_slot_nolazy (tree, tree);
|
||||
extern int class_method_index_for_fn (tree, tree);
|
||||
extern tree lookup_fnfields (tree, tree, int);
|
||||
extern tree lookup_member (tree, tree, int, bool);
|
||||
extern tree lookup_member (tree, tree, int, bool,
|
||||
tsubst_flags_t);
|
||||
extern int look_for_overrides (tree, tree);
|
||||
extern void get_pure_virtuals (tree);
|
||||
extern void maybe_suppress_debug_info (tree);
|
||||
|
@ -314,7 +314,7 @@ make_friend_class (tree type, tree friend_type, bool complain)
|
||||
}
|
||||
else
|
||||
{
|
||||
decl = lookup_member (ctype, name, 0, true);
|
||||
decl = lookup_member (ctype, name, 0, true, tf_warning_or_error);
|
||||
if (!decl)
|
||||
{
|
||||
error ("%qT is not a member of %qT", name, ctype);
|
||||
|
@ -1121,7 +1121,8 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
|
||||
member = lookup_member (current_class_type,
|
||||
name,
|
||||
/*protect=*/0,
|
||||
/*want_type=*/false);
|
||||
/*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
else
|
||||
member = NULL_TREE;
|
||||
|
||||
@ -2891,10 +2892,12 @@ get_class_binding (tree name, cp_binding_level *scope)
|
||||
|
||||
/* Get the type binding. */
|
||||
type_binding = lookup_member (class_type, name,
|
||||
/*protect=*/2, /*want_type=*/true);
|
||||
/*protect=*/2, /*want_type=*/true,
|
||||
tf_warning_or_error);
|
||||
/* Get the value binding. */
|
||||
value_binding = lookup_member (class_type, name,
|
||||
/*protect=*/2, /*want_type=*/false);
|
||||
/*protect=*/2, /*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
|
||||
if (value_binding
|
||||
&& (TREE_CODE (value_binding) == TYPE_DECL
|
||||
@ -3193,7 +3196,7 @@ do_class_using_decl (tree scope, tree name)
|
||||
}
|
||||
else if (!name_dependent_p)
|
||||
{
|
||||
decl = lookup_member (binfo, name, 0, false);
|
||||
decl = lookup_member (binfo, name, 0, false, tf_warning_or_error);
|
||||
if (!decl)
|
||||
{
|
||||
error ("no members matching %<%T::%D%> in %q#T", scope, name,
|
||||
@ -4258,7 +4261,7 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
|
||||
else if (cxx_dialect != cxx98 && TREE_CODE (scope) == ENUMERAL_TYPE)
|
||||
t = lookup_enumerator (scope, name);
|
||||
else if (is_class_type (scope, complain))
|
||||
t = lookup_member (scope, name, 2, is_type_p);
|
||||
t = lookup_member (scope, name, 2, is_type_p, tf_warning_or_error);
|
||||
|
||||
if (!t)
|
||||
return error_mark_node;
|
||||
|
@ -9495,9 +9495,11 @@ cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
|
||||
id_begin = get_identifier ("begin");
|
||||
id_end = get_identifier ("end");
|
||||
member_begin = lookup_member (TREE_TYPE (range), id_begin,
|
||||
/*protect=*/2, /*want_type=*/false);
|
||||
/*protect=*/2, /*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
member_end = lookup_member (TREE_TYPE (range), id_end,
|
||||
/*protect=*/2, /*want_type=*/false);
|
||||
/*protect=*/2, /*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
|
||||
if (member_begin != NULL_TREE || member_end != NULL_TREE)
|
||||
{
|
||||
@ -20398,7 +20400,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
|
||||
object_decl = lookup_member (object_type,
|
||||
name,
|
||||
/*protect=*/0,
|
||||
tag_type != none_type);
|
||||
tag_type != none_type,
|
||||
tf_warning_or_error);
|
||||
/* Look it up in the enclosing context, too. */
|
||||
decl = lookup_name_real (name, tag_type != none_type,
|
||||
/*nonclass=*/0,
|
||||
|
@ -19861,7 +19861,8 @@ resolve_typename_type (tree type, bool only_current_p)
|
||||
longer be considered a dependent type. */
|
||||
pushed_scope = push_scope (scope);
|
||||
/* Look up the declaration. */
|
||||
decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true);
|
||||
decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true,
|
||||
tf_warning_or_error);
|
||||
|
||||
result = NULL_TREE;
|
||||
|
||||
|
@ -1155,7 +1155,8 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
|
||||
If nothing can be found return NULL_TREE and do not issue an error. */
|
||||
|
||||
tree
|
||||
lookup_member (tree xbasetype, tree name, int protect, bool want_type)
|
||||
lookup_member (tree xbasetype, tree name, int protect, bool want_type,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree rval, rval_binfo = NULL_TREE;
|
||||
tree type = NULL_TREE, basetype_path = NULL_TREE;
|
||||
@ -1250,9 +1251,12 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
|
||||
|
||||
if (errstr && protect)
|
||||
{
|
||||
error (errstr, name, type);
|
||||
if (lfi.ambiguous)
|
||||
print_candidates (lfi.ambiguous);
|
||||
if (complain & tf_error)
|
||||
{
|
||||
error (errstr, name, type);
|
||||
if (lfi.ambiguous)
|
||||
print_candidates (lfi.ambiguous);
|
||||
}
|
||||
rval = error_mark_node;
|
||||
}
|
||||
|
||||
@ -1269,7 +1273,8 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
|
||||
tree
|
||||
lookup_field (tree xbasetype, tree name, int protect, bool want_type)
|
||||
{
|
||||
tree rval = lookup_member (xbasetype, name, protect, want_type);
|
||||
tree rval = lookup_member (xbasetype, name, protect, want_type,
|
||||
tf_warning_or_error);
|
||||
|
||||
/* Ignore functions, but propagate the ambiguity list. */
|
||||
if (!error_operand_p (rval)
|
||||
@ -1285,7 +1290,8 @@ lookup_field (tree xbasetype, tree name, int protect, bool want_type)
|
||||
tree
|
||||
lookup_fnfields (tree xbasetype, tree name, int protect)
|
||||
{
|
||||
tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false);
|
||||
tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
|
||||
/* Ignore non-functions, but propagate the ambiguity list. */
|
||||
if (!error_operand_p (rval)
|
||||
|
@ -8621,7 +8621,8 @@ lambda_function (tree lambda)
|
||||
&& !COMPLETE_OR_OPEN_TYPE_P (type))
|
||||
return NULL_TREE;
|
||||
lambda = lookup_member (type, ansi_opname (CALL_EXPR),
|
||||
/*protect=*/0, /*want_type=*/false);
|
||||
/*protect=*/0, /*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
if (lambda)
|
||||
lambda = BASELINK_FUNCTIONS (lambda);
|
||||
return lambda;
|
||||
|
@ -2397,7 +2397,8 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
|
||||
return error_mark_node;
|
||||
}
|
||||
expr = lookup_member (dtor_type, complete_dtor_identifier,
|
||||
/*protect=*/1, /*want_type=*/false);
|
||||
/*protect=*/1, /*want_type=*/false,
|
||||
tf_warning_or_error);
|
||||
expr = (adjust_result_of_qualified_name_lookup
|
||||
(expr, dtor_type, object_type));
|
||||
return expr;
|
||||
@ -2607,7 +2608,7 @@ finish_class_member_access_expr (tree object, tree name, bool template_p,
|
||||
{
|
||||
/* Look up the member. */
|
||||
member = lookup_member (access_path, name, /*protect=*/1,
|
||||
/*want_type=*/false);
|
||||
/*want_type=*/false, complain);
|
||||
if (member == NULL_TREE)
|
||||
{
|
||||
if (complain & tf_error)
|
||||
@ -2681,7 +2682,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
|
||||
ptrmem_type = TREE_TYPE (ptrmem);
|
||||
gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
|
||||
member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
|
||||
/*want_type=*/false);
|
||||
/*want_type=*/false, tf_warning_or_error);
|
||||
member_type = cp_build_qualified_type (TREE_TYPE (member),
|
||||
cp_type_quals (ptrmem_type));
|
||||
return fold_build3_loc (input_location,
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-11-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/51047
|
||||
* g++.dg/cpp0x/sfinae29.C: New.
|
||||
|
||||
2011-11-09 Janus Weil <janus@gcc.gnu.org>
|
||||
|
||||
PR fortran/50960
|
||||
|
17
gcc/testsuite/g++.dg/cpp0x/sfinae29.C
Normal file
17
gcc/testsuite/g++.dg/cpp0x/sfinae29.C
Normal file
@ -0,0 +1,17 @@
|
||||
// PR c++/51047
|
||||
// { dg-options -std=c++0x }
|
||||
|
||||
template<typename T> T &&declval();
|
||||
template<class T> decltype(declval<T>().x) f(T *);
|
||||
template<class T> char f(T);
|
||||
struct B1{ int x; };
|
||||
struct B2{ int x; };
|
||||
struct D : public B1, B2{};
|
||||
struct S { int x; };
|
||||
int main()
|
||||
{
|
||||
S *p = nullptr;
|
||||
static_assert(sizeof(f(p)) == sizeof(int), "");
|
||||
D *q = nullptr;
|
||||
static_assert(sizeof(f(q)) == 1u, "");
|
||||
}
|
Loading…
Reference in New Issue
Block a user