Patchwork C++ PATCH for better access violation diagnostic locations

login
register
mail settings
Submitter Jason Merrill
Date July 16, 2012, 9:24 p.m.
Message ID <50048689.7090104@redhat.com>
Download mbox | patch
Permalink /patch/171260/
State New
Headers show

Comments

Jason Merrill - July 16, 2012, 9:24 p.m.
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.

Patch

commit f84991f247261f8e9d8c57115398f2fcd6ce9b62
Author: Jason Merrill <jason@redhat.com>
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<foo::memfun>
-struct fm_obj { }; // { dg-error "context" } 
+template<foo::memfun> // { dg-error "context" }
+struct fm_obj { };
 
 template <typename T = foo::memfun> // { 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<typename T> struct enable_if<false, T> { };
 template<typename F, typename T1, typename T2>
   typename enable_if<sizeof(create_a<F>()(create_a<T1>(), create_a<T2>()), 1),
 		     yes_type>::type
-  check_is_callable2(type<F>, type<T1>, type<T2>);
+  check_is_callable2(type<F>, type<T1>, type<T2>); // { dg-error "within this context" }
 
 no_type check_is_callable2(...);
 
 template<typename F, typename T1, typename T2 = T1>
 struct is_callable2
 {
-  static const bool value = // { dg-error "within this context" }
+  static const bool value =
     (sizeof(check_is_callable2(type<F>(), type<T1>(), type<T2>()))
      == sizeof(yes_type));
 };