From patchwork Mon Jul 16 21:24:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for better access violation diagnostic locations Date: Mon, 16 Jul 2012 11:24:25 -0000 From: Jason Merrill X-Patchwork-Id: 171260 Message-Id: <50048689.7090104@redhat.com> To: gcc-patches List Cc: Dodji Seketeli , Paolo Carlini While looking at Paolo's access sfinae patch, I noticed that we were giving poor locations for deferred access control errors. This patch fixes that by storing the location of the check to use again later. Tested x86_64-pc-linux-gnu, applying to trunk. commit f84991f247261f8e9d8c57115398f2fcd6ce9b62 Author: Jason Merrill Date: Mon Jul 16 17:08:11 2012 -0400 * cp-tree.h (struct deferred_access_check): Add location. * semantics.c (perform_access_checks): Use it. (perform_or_defer_access_check): Store it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 10efa2a..59104e7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5484,6 +5484,8 @@ typedef struct GTY(()) deferred_access_check { tree decl; /* The declaration that should be used in the error message. */ tree diag_decl; + /* The location of this access. */ + location_t loc; } deferred_access_check; DEF_VEC_O(deferred_access_check); DEF_VEC_ALLOC_O(deferred_access_check,gc); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a32e48a..8110295 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -259,12 +259,18 @@ perform_access_checks (VEC (deferred_access_check,gc)* checks) { int i; deferred_access_check *chk; + location_t loc = input_location; if (!checks) return; FOR_EACH_VEC_ELT (deferred_access_check, checks, i, chk) - enforce_access (chk->binfo, chk->decl, chk->diag_decl); + { + input_location = chk->loc; + enforce_access (chk->binfo, chk->decl, chk->diag_decl); + } + + input_location = loc; } /* Perform the deferred access checks. @@ -334,6 +340,7 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl) new_access->binfo = binfo; new_access->decl = decl; new_access->diag_decl = diag_decl; + new_access->loc = input_location; } /* Used by build_over_call in LOOKUP_SPECULATIVE mode: return whether DECL diff --git a/gcc/testsuite/g++.dg/parse/access8.C b/gcc/testsuite/g++.dg/parse/access8.C index 45f4be7..205b7f2 100644 --- a/gcc/testsuite/g++.dg/parse/access8.C +++ b/gcc/testsuite/g++.dg/parse/access8.C @@ -5,8 +5,8 @@ class foo typedef int memfun; // { dg-error "private" } }; -template -struct fm_obj { }; // { dg-error "context" } +template // { dg-error "context" } +struct fm_obj { }; template // { dg-error "context" } struct S {}; diff --git a/gcc/testsuite/g++.dg/template/sfinae6_neg.C b/gcc/testsuite/g++.dg/template/sfinae6_neg.C index c238222..28adf73 100644 --- a/gcc/testsuite/g++.dg/template/sfinae6_neg.C +++ b/gcc/testsuite/g++.dg/template/sfinae6_neg.C @@ -14,14 +14,14 @@ template struct enable_if { }; template typename enable_if()(create_a(), create_a()), 1), yes_type>::type - check_is_callable2(type, type, type); + check_is_callable2(type, type, type); // { dg-error "within this context" } no_type check_is_callable2(...); template struct is_callable2 { - static const bool value = // { dg-error "within this context" } + static const bool value = (sizeof(check_is_callable2(type(), type(), type())) == sizeof(yes_type)); };