From patchwork Mon Aug 27 20:55:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 180280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D7F3A2C00D4 for ; Tue, 28 Aug 2012 06:55:48 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1346705749; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Message-ID:Date:From:User-Agent:MIME-Version: To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=ai7ZdR+Xu6jD57TlsoIvqWvr91A=; b=FhPJDZIhP/ZdYewLMum3TuifUsKtdG3bYzVK80/Wlgm0mpBdv2O/BowY1OjOa+ civbTwFD2U7PYMA/U4bxI1dwnQLfMZ2BaGo4HN1GH45vqZ6dzSwb7OEhwenlcn/p Z/PzO+Cjnw2icXX5wI8NCr5WOoQZ8v1fYM9z3R84guNE8= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=xg0umyjDFE3Bk3s8+YgJ1e0/cSfG2CjcYRakpooVYYU21+DPkJER+UUDB1ojnr KsaPrKCUQJ93Zm7eH7Qy28hg+doUNnKSoIqV19Pdpq2mHxpFr6nPhIUIJ/YiZr7N xKQON7Thp7lZdqQp/6YcSAHVT+U/ziDOg0FGzI+aCoO38=; Received: (qmail 16625 invoked by alias); 27 Aug 2012 20:55:45 -0000 Received: (qmail 16615 invoked by uid 22791); 27 Aug 2012 20:55:42 -0000 X-SWARE-Spam-Status: No, hits=-7.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD, TW_CD, TW_VT X-Spam-Check-By: sourceware.org Received: from rcsinet15.oracle.com (HELO rcsinet15.oracle.com) (148.87.113.117) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 27 Aug 2012 20:55:22 +0000 Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by rcsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q7RKtLwI001055 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 27 Aug 2012 20:55:22 GMT Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by ucsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q7RKtK2C001358 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 27 Aug 2012 20:55:21 GMT Received: from abhmt104.oracle.com (abhmt104.oracle.com [141.146.116.56]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q7RKtK3W024808; Mon, 27 Aug 2012 15:55:20 -0500 Received: from [192.168.1.4] (/79.52.192.194) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 27 Aug 2012 13:55:19 -0700 Message-ID: <503BDEB5.1040102@oracle.com> Date: Mon, 27 Aug 2012 22:55:17 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20120713 Thunderbird/14.0 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: Re: [C++ Patch] PR 54191 References: <5022CEBF.1060602@oracle.com> <503BA02C.4000901@redhat.com> <503BB03A.9050004@oracle.com> <503BB6CB.6080004@redhat.com> In-Reply-To: <503BB6CB.6080004@redhat.com> X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On 08/27/2012 08:04 PM, Jason Merrill wrote: > On 08/27/2012 01:36 PM, Paolo Carlini wrote: >> Thanks for the feedback. Indeed, as I tried to explain in an older >> message, that was also my understanding. The practical difficulty with >> the mapping (which you can also guess from the current structure of >> get_delta_difference_1, the if (kind == bk_inaccessible || kind == >> bk_ambig) check) is that ba_quiet, as used by lookup_base, doesn't just >> control the error calls - like normally tf_error does - it *also* >> changes the return value, error_mark_node or NULL_TREE. I'm still not >> sure about the correct (and concise! see get_delta_difference_1, again) >> way to handle this... > > I think the right way is to adjust the callers to handle > error_mark_node return properly. Macros may need to become functions. Ah, ok. I guess the prospect of touching those macros was somehow psychologically "blocking" me., eh ;) But actually, all in all, the code doesn't become more complex, because only the cases where we are now passing tf_none require checking for error_mark_node too where we were simply checking != NULL_TREE as return value of lookup_base and most of the calls are otherwise already Ok, or even become simpler, where we were, on a case by case basis, tweaking to | ba_quiet basing on complain (note: I left DERIVED_FROM_P alone, because we weren't passing ba_quiet to it) The below passes testing on x86_64-linux. Thanks! Paolo. ////////////////////////// Index: testsuite/g++.dg/cpp0x/sfinae39.C =================================================================== --- testsuite/g++.dg/cpp0x/sfinae39.C (revision 0) +++ testsuite/g++.dg/cpp0x/sfinae39.C (revision 0) @@ -0,0 +1,98 @@ +// PR c++/54191 +// { dg-do compile { target c++11 } } + +struct B +{}; + +struct D + : private B +{}; + +template +T &&declval(); + + +template(declval()))> +constexpr bool test_static_cast(int) +{ return true; } + +template +constexpr bool test_static_cast(bool) +{ return false; } + +static_assert(!test_static_cast(0), ""); +static_assert(!test_static_cast(0), ""); + + +template(declval()))> +constexpr bool test_dynamic_cast(int) +{ return true; } + +template +constexpr bool test_dynamic_cast(bool) +{ return false; } + +static_assert(!test_dynamic_cast(0), ""); +static_assert(!test_dynamic_cast(0), ""); + + +int B::*pm = 0; + +template().*pm)> +constexpr bool test_member_ptr_dot(int) +{ return true; } + +template +constexpr bool test_member_ptr_dot(bool) +{ return false; } + +static_assert(!test_member_ptr_dot(0), ""); + + +template()->*pm)> +constexpr bool test_member_ptr_arrow(int) +{ return true; } + +template +constexpr bool test_member_ptr_arrow(bool) +{ return false; } + +static_assert(!test_member_ptr_arrow(0), ""); + + +template() < declval())> +constexpr bool test_rel_op(int) +{ return true; } + +template +constexpr bool test_rel_op(bool) +{ return false; } + +static_assert(!test_rel_op(0), ""); + + +template() == declval())> +constexpr bool test_eq(int) +{ return true; } + +template +constexpr bool test_eq(bool) +{ return false; } + +static_assert(!test_eq(0), ""); + + +template() : declval())> +constexpr bool test_cond_op(int) +{ return true; } + +template +constexpr bool test_cond_op(bool) +{ return false; } + +static_assert(!test_cond_op(0), ""); Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 190730) +++ cp/typeck.c (working copy) @@ -975,7 +975,7 @@ comp_except_types (tree a, tree b, bool exact) || TREE_CODE (b) != RECORD_TYPE) return false; - if (PUBLICLY_UNIQUELY_DERIVED_P (a, b)) + if (publicly_uniquely_derived_p (a, b)) return true; } return false; @@ -2247,7 +2247,7 @@ build_class_member_access_expr (tree object, tree base_kind kind; binfo = lookup_base (access_path ? access_path : object_type, - member_scope, ba_unique, &kind); + member_scope, ba_unique, &kind, complain); if (binfo == error_mark_node) return error_mark_node; @@ -2630,7 +2630,8 @@ finish_class_member_access_expr (tree object, tree } /* Find the base of OBJECT_TYPE corresponding to SCOPE. */ - access_path = lookup_base (object_type, scope, ba_check, NULL); + access_path = lookup_base (object_type, scope, ba_check, + NULL, complain); if (access_path == error_mark_node) return error_mark_node; if (!access_path) @@ -3151,7 +3152,7 @@ get_member_function_from_ptrfunc (tree *instance_p (basetype, TREE_TYPE (TREE_TYPE (instance_ptr)))) { basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)), - basetype, ba_check, NULL); + basetype, ba_check, NULL, complain); instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1, complain); if (instance_ptr == error_mark_node) @@ -5997,7 +5998,7 @@ build_static_cast_1 (tree type, tree expr, bool c_ not considered. */ base = lookup_base (TREE_TYPE (type), intype, c_cast_p ? ba_unique : ba_check, - NULL); + NULL, complain); /* Convert from "B*" to "D*". This function will check that "B" is not a virtual base of "D". */ @@ -6121,7 +6122,7 @@ build_static_cast_1 (tree type, tree expr, bool c_ return error_mark_node; base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), c_cast_p ? ba_unique : ba_check, - NULL); + NULL, complain); expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false, complain); return cp_fold_convert(type, expr); @@ -7181,16 +7182,11 @@ get_delta_difference_1 (tree from, tree to, bool c { tree binfo; base_kind kind; - base_access access = c_cast_p ? ba_unique : ba_check; - /* Note: ba_quiet does not distinguish between access control and - ambiguity. */ - if (!(complain & tf_error)) - access |= ba_quiet; + binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, + &kind, complain); - binfo = lookup_base (to, from, access, &kind); - - if (kind == bk_inaccessible || kind == bk_ambig) + if (binfo == error_mark_node) { if (!(complain & tf_error)) return error_mark_node; Index: cp/class.c =================================================================== --- cp/class.c (revision 190730) +++ cp/class.c (working copy) @@ -275,7 +275,7 @@ build_base_path (enum tree_code code, if (complain & tf_error) { tree base = lookup_base (probe, BINFO_TYPE (d_binfo), - ba_unique, NULL); + ba_unique, NULL, complain); gcc_assert (base == error_mark_node); } return error_mark_node; @@ -544,7 +544,6 @@ convert_to_base (tree object, tree type, bool chec { tree binfo; tree object_type; - base_access access; if (TYPE_PTR_P (TREE_TYPE (object))) { @@ -554,12 +553,8 @@ convert_to_base (tree object, tree type, bool chec else object_type = TREE_TYPE (object); - access = check_access ? ba_check : ba_unique; - if (!(complain & tf_error)) - access |= ba_quiet; - binfo = lookup_base (object_type, type, - access, - NULL); + binfo = lookup_base (object_type, type, check_access ? ba_check : ba_unique, + NULL, complain); if (!binfo || binfo == error_mark_node) return error_mark_node; @@ -652,8 +647,8 @@ build_vtbl_ref_1 (tree instance, tree idx) if (fixed_type && !cdtorp) { tree binfo = lookup_base (fixed_type, basetype, - ba_unique | ba_quiet, NULL); - if (binfo) + ba_unique, NULL, tf_none); + if (binfo && binfo != error_mark_node) vtbl = unshare_expr (BINFO_VTABLE (binfo)); } @@ -5483,7 +5478,7 @@ warn_about_ambiguous_bases (tree t) { basetype = BINFO_TYPE (base_binfo); - if (!lookup_base (t, basetype, ba_unique | ba_quiet, NULL)) + if (!uniquely_derived_from_p (basetype, t)) warning (0, "direct base %qT inaccessible in %qT due to ambiguity", basetype, t); } @@ -5495,9 +5490,9 @@ warn_about_ambiguous_bases (tree t) { basetype = BINFO_TYPE (binfo); - if (!lookup_base (t, basetype, ba_unique | ba_quiet, NULL)) - warning (OPT_Wextra, "virtual base %qT inaccessible in %qT due to ambiguity", - basetype, t); + if (!uniquely_derived_from_p (basetype, t)) + warning (OPT_Wextra, "virtual base %qT inaccessible in %qT due " + "to ambiguity", basetype, t); } } @@ -8933,4 +8928,24 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_dat CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init); } +/* TRUE iff TYPE is uniquely derived from PARENT. Ignores + accessibility. */ + +bool +uniquely_derived_from_p (tree parent, tree type) +{ + tree base = lookup_base (type, parent, ba_unique, NULL, tf_none); + return base && base != error_mark_node; +} + +/* TRUE iff TYPE is publicly & uniquely derived from PARENT. */ + +bool +publicly_uniquely_derived_p (tree parent, tree type) +{ + tree base = lookup_base (type, parent, ba_ignore_scope | ba_check, + NULL, tf_none); + return base && base != error_mark_node; +} + #include "gt-cp-class.h" Index: cp/decl.c =================================================================== --- cp/decl.c (revision 190730) +++ cp/decl.c (working copy) @@ -8512,7 +8512,7 @@ grokdeclarator (const cp_declarator *declarator, } else if (innermost_code != cdk_function && current_class_type - && !UNIQUELY_DERIVED_FROM_P (ctype, + && !uniquely_derived_from_p (ctype, current_class_type)) { error ("type %qT is not derived from type %qT", Index: cp/rtti.c =================================================================== --- cp/rtti.c (revision 190730) +++ cp/rtti.c (working copy) @@ -615,7 +615,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst tree binfo; binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type), - ba_check, NULL); + ba_check, NULL, complain); if (binfo) { Index: cp/except.c =================================================================== --- cp/except.c (revision 190730) +++ cp/except.c (working copy) @@ -1052,7 +1052,7 @@ can_convert_eh (tree to, tree from) } if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from) - && PUBLICLY_UNIQUELY_DERIVED_P (to, from)) + && publicly_uniquely_derived_p (to, from)) return 1; return 0; Index: cp/tree.c =================================================================== --- cp/tree.c (revision 190730) +++ cp/tree.c (working copy) @@ -2772,7 +2772,8 @@ maybe_dummy_object (tree type, tree* binfop) tree current = current_nonlambda_class_type (); if (current - && (binfo = lookup_base (current, type, ba_any, NULL))) + && (binfo = lookup_base (current, type, ba_any, NULL, + tf_warning_or_error))) context = current; else { Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 190730) +++ cp/typeck2.c (working copy) @@ -57,7 +57,8 @@ error_not_base_type (tree basetype, tree type) tree binfo_or_else (tree base, tree type) { - tree binfo = lookup_base (type, base, ba_unique, NULL); + tree binfo = lookup_base (type, base, ba_unique, + NULL, tf_warning_or_error); if (binfo == error_mark_node) return NULL_TREE; @@ -1447,7 +1448,8 @@ build_scoped_ref (tree datum, tree basetype, tree* if (*binfo_p) binfo = *binfo_p; else - binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, NULL); + binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, + NULL, tf_warning_or_error); if (!binfo || binfo == error_mark_node) { @@ -1600,7 +1602,7 @@ build_m_component_ref (tree datum, tree component, } else { - binfo = lookup_base (objtype, ctype, ba_check, NULL); + binfo = lookup_base (objtype, ctype, ba_check, NULL, complain); if (!binfo) { Index: cp/call.c =================================================================== --- cp/call.c (revision 190730) +++ cp/call.c (working copy) @@ -4758,6 +4758,9 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr return error_mark_node; } + if (arg2 == error_mark_node || arg3 == error_mark_node) + return error_mark_node; + valid_operands: result = build3 (COND_EXPR, result_type, arg1, arg2, arg3); if (!cp_unevaluated_operand) @@ -6608,7 +6611,8 @@ build_over_call (struct z_candidate *cand, int fla will be to the derived class, not the base declaring fn. We must convert from derived to base. */ base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)), - TREE_TYPE (parmtype), ba_unique, NULL); + TREE_TYPE (parmtype), ba_unique, + NULL, complain); converted_arg = build_base_path (PLUS_EXPR, converted_arg, base_binfo, 1, complain); @@ -6852,7 +6856,7 @@ build_over_call (struct z_candidate *cand, int fla tree t; tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (argarray[0])), DECL_CONTEXT (fn), - ba_any, NULL); + ba_any, NULL, complain); gcc_assert (binfo && binfo != error_mark_node); /* Warn about deprecated virtual functions now, since we're about Index: cp/cvt.c =================================================================== --- cp/cvt.c (revision 190730) +++ cp/cvt.c (working copy) @@ -149,11 +149,13 @@ cp_convert_to_pointer (tree type, tree expr, tsubs binfo = NULL_TREE; /* Try derived to base conversion. */ if (!same_p) - binfo = lookup_base (intype_class, type_class, ba_check, NULL); + binfo = lookup_base (intype_class, type_class, ba_check, + NULL, complain); if (!same_p && !binfo) { /* Try base to derived conversion. */ - binfo = lookup_base (type_class, intype_class, ba_check, NULL); + binfo = lookup_base (type_class, intype_class, ba_check, + NULL, complain); code = MINUS_EXPR; } if (binfo == error_mark_node) @@ -279,11 +281,11 @@ convert_to_pointer_force (tree type, tree expr, ts tree binfo; binfo = lookup_base (TREE_TYPE (intype), TREE_TYPE (type), - ba_unique, NULL); + ba_unique, NULL, complain); if (!binfo) { binfo = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), - ba_unique, NULL); + ba_unique, NULL, complain); code = MINUS_EXPR; } if (binfo == error_mark_node) @@ -352,7 +354,8 @@ build_up_reference (tree type, tree arg, int flags && MAYBE_CLASS_TYPE_P (target_type)) { /* We go through lookup_base for the access control. */ - tree binfo = lookup_base (argtype, target_type, ba_check, NULL); + tree binfo = lookup_base (argtype, target_type, ba_check, + NULL, complain); if (binfo == error_mark_node) return error_mark_node; if (binfo == NULL_TREE) Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 190730) +++ cp/cp-tree.h (working copy) @@ -1278,15 +1278,8 @@ enum languages { lang_c, lang_cplusplus, lang_java /* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and ambiguity issues. */ #define DERIVED_FROM_P(PARENT, TYPE) \ - (lookup_base ((TYPE), (PARENT), ba_any, NULL) != NULL_TREE) -/* Nonzero iff TYPE is uniquely derived from PARENT. Ignores - accessibility. */ -#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) \ - (lookup_base ((TYPE), (PARENT), ba_unique | ba_quiet, NULL) != NULL_TREE) -/* Nonzero iff TYPE is publicly & uniquely derived from PARENT. */ -#define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \ - (lookup_base ((TYPE), (PARENT), ba_ignore_scope | ba_check | ba_quiet, \ - NULL) != NULL_TREE) + (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_warning_or_error)\ + != NULL_TREE) /* Gives the visibility specification for a class type. */ #define CLASSTYPE_VISIBILITY(TYPE) \ @@ -4187,8 +4180,7 @@ enum base_access_flags { ba_unique = 1 << 0, /* Must be a unique base. */ ba_check_bit = 1 << 1, /* Check access. */ ba_check = ba_unique | ba_check_bit, - ba_ignore_scope = 1 << 2, /* Ignore access allowed by local scope. */ - ba_quiet = 1 << 3 /* Do not issue error messages. */ + ba_ignore_scope = 1 << 2 /* Ignore access allowed by local scope. */ }; /* This type is used for parameters and variables which hold @@ -5007,6 +4999,8 @@ extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); extern void deduce_noexcept_on_destructor (tree); extern void insert_late_enum_def_into_classtype_sorted_fields (tree, tree); +extern bool uniquely_derived_from_p (tree, tree); +extern bool publicly_uniquely_derived_p (tree, tree); /* in cvt.c */ extern tree convert_to_reference (tree, tree, int, int, tree, @@ -5439,8 +5433,8 @@ extern bool emit_tinfo_decl (tree); /* in search.c */ extern bool accessible_base_p (tree, tree, bool); -extern tree lookup_base (tree, tree, base_access, - base_kind *); +extern tree lookup_base (tree, tree, base_access, + base_kind *, tsubst_flags_t); extern tree dcast_base_hint (tree, tree); extern int accessible_p (tree, tree, bool); extern tree lookup_field_1 (tree, tree, bool); Index: cp/search.c =================================================================== --- cp/search.c (revision 190730) +++ cp/search.c (working copy) @@ -179,13 +179,13 @@ accessible_base_p (tree t, tree base, bool conside non-NULL, fill with information about what kind of base we discovered. - If the base is inaccessible, or ambiguous, and the ba_quiet bit is - not set in ACCESS, then an error is issued and error_mark_node is - returned. If the ba_quiet bit is set, then no error is issued and - NULL_TREE is returned. */ + If the base is inaccessible, or ambiguous, then error_mark_node is + returned. If the tf_error bit of COMPLAIN is not set, no error + is issued. */ tree -lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr) +lookup_base (tree t, tree base, base_access access, + base_kind *kind_ptr, tsubst_flags_t complain) { tree binfo; tree t_binfo; @@ -251,11 +251,9 @@ tree break; case bk_ambig: - if (!(access & ba_quiet)) - { - error ("%qT is an ambiguous base of %qT", base, t); - binfo = error_mark_node; - } + if (complain & tf_error) + error ("%qT is an ambiguous base of %qT", base, t); + binfo = error_mark_node; break; default: @@ -269,13 +267,9 @@ tree && COMPLETE_TYPE_P (base) && !accessible_base_p (t, base, !(access & ba_ignore_scope))) { - if (!(access & ba_quiet)) - { - error ("%qT is an inaccessible base of %qT", base, t); - binfo = error_mark_node; - } - else - binfo = NULL_TREE; + if (complain & tf_error) + error ("%qT is an inaccessible base of %qT", base, t); + binfo = error_mark_node; bk = bk_inaccessible; } break; @@ -1537,14 +1531,13 @@ adjust_result_of_qualified_name_lookup (tree decl, or ambiguity -- in either case, the choice of a static member function might make the usage valid. */ base = lookup_base (context_class, qualifying_scope, - ba_unique | ba_quiet, NULL); - if (base) + ba_unique, NULL, tf_none); + if (base && base != error_mark_node) { BASELINK_ACCESS_BINFO (decl) = base; BASELINK_BINFO (decl) = lookup_base (base, BINFO_TYPE (BASELINK_BINFO (decl)), - ba_unique | ba_quiet, - NULL); + ba_unique, NULL, tf_none); } } @@ -1875,12 +1868,13 @@ check_final_overrider (tree overrider, tree basefn /* Strictly speaking, the standard requires the return type to be complete even if it only differs in cv-quals, but that seems like a bug in the wording. */ - if (!same_type_ignoring_top_level_qualifiers_p (base_return, over_return)) + if (!same_type_ignoring_top_level_qualifiers_p (base_return, + over_return)) { tree binfo = lookup_base (over_return, base_return, - ba_check | ba_quiet, NULL); + ba_check, NULL, tf_none); - if (!binfo) + if (!binfo || binfo == error_mark_node) fail = 1; } } Index: cp/name-lookup.c =================================================================== --- cp/name-lookup.c (revision 190730) +++ cp/name-lookup.c (working copy) @@ -3265,7 +3265,8 @@ do_class_using_decl (tree scope, tree name) if (!scope_dependent_p) { base_kind b_kind; - binfo = lookup_base (current_class_type, scope, ba_any, &b_kind); + binfo = lookup_base (current_class_type, scope, ba_any, &b_kind, + tf_warning_or_error); if (b_kind < bk_proper_base) { if (!bases_dependent_p)