]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/14122 (problem with non-type tmplt parm in member template)
authorMark Mitchell <mark@codesourcery.com>
Sat, 14 Feb 2004 00:49:15 +0000 (00:49 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 14 Feb 2004 00:49:15 +0000 (00:49 +0000)
PR c++/14122
* cp-tree.h (delete_sanity): Change prototype.
* decl2.c (delete_sanity): Make doing_vec a bool, not an int.
Remove dead code.  Adjust code to warn about deleting an array.
* typekc.c (decay_conversion): Use build_address and build_nop.

PR c++/14108
* search.c (accessible_p): Do not check access in thunks.

PR c++/14122
* g++.dg/template/array4.C: New test.

PR c++/14108
* g++.dg/inherit/thunk2.C: New test.

From-SVN: r77786

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/search.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/thunk2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/array4.C [new file with mode: 0644]

index 89d8edc8d8183424d538a6644e0217f8c9d2738c..572b774f7aa2345a0c50ab62c7481de2269233e7 100644 (file)
@@ -1,5 +1,14 @@
 2004-02-13  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/14122
+       * cp-tree.h (delete_sanity): Change prototype.
+       * decl2.c (delete_sanity): Make doing_vec a bool, not an int.
+       Remove dead code.  Adjust code to warn about deleting an array.
+       * typekc.c (decay_conversion): Use build_address and build_nop.
+
+       PR c++/14108
+       * search.c (accessible_p): Do not check access in thunks.
+
        PR c++/14083
        * call.c (build_conditional_expr): Call force_rvalue on the
        non-void operand in the case that one result is a throw-expression
index ce826afad903192c980553c312ccfdd95a05019c..0097c42f288770a015d063510965cbd0eb43c7c1 100644 (file)
@@ -3709,7 +3709,7 @@ extern void maybe_retrofit_in_chrg (tree);
 extern void maybe_make_one_only        (tree);
 extern void grokclassfn        (tree, tree, enum overload_flags, tree);
 extern tree grok_array_decl (tree, tree);
-extern tree delete_sanity (tree, tree, int, int);
+extern tree delete_sanity (tree, tree, bool, int);
 extern tree check_classfn (tree, tree, bool);
 extern void check_member_template (tree);
 extern tree grokfield (tree, tree, tree, tree, tree);
index 07acd139f327453b69ac574522e37566abafd6d6..d5ee526381c0bf2fc05c1e6c749a0b4e14e603c5 100644 (file)
@@ -432,18 +432,14 @@ grok_array_decl (tree array_expr, tree index_exp)
 /* Given the cast expression EXP, checking out its validity.   Either return
    an error_mark_node if there was an unavoidable error, return a cast to
    void for trying to delete a pointer w/ the value 0, or return the
-   call to delete.  If DOING_VEC is 1, we handle things differently
-   for doing an array delete.  If DOING_VEC is 2, they gave us the
-   array size as an argument to delete.
+   call to delete.  If DOING_VEC is true, we handle things differently
+   for doing an array delete.
    Implements ARM $5.3.4.  This is called from the parser.  */
 
 tree
-delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete)
+delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
 {
   tree t, type;
-  /* For a regular vector delete (aka, no size argument) we will pass
-     this down as a NULL_TREE into build_vec_delete.  */
-  tree maxindex = NULL_TREE;
 
   if (exp == error_mark_node)
     return exp;
@@ -457,6 +453,12 @@ delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete)
     }
 
   exp = convert_from_reference (exp);
+
+  /* An array can't have been allocated by new, so complain.  */
+  if (TREE_CODE (exp) == VAR_DECL
+      && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+    warning ("deleting array `%#D'", exp);
+
   t = build_expr_type_conversion (WANT_POINTER, exp, true);
 
   if (t == NULL_TREE || t == error_mark_node)
@@ -466,12 +468,6 @@ delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete)
       return error_mark_node;
     }
 
-  if (doing_vec == 2)
-    {
-      maxindex = cp_build_binary_op (MINUS_EXPR, size, integer_one_node);
-      pedwarn ("anachronistic use of array size in vector delete");
-    }
-
   type = TREE_TYPE (t);
 
   /* As of Valley Forge, you can delete a pointer to const.  */
@@ -490,18 +486,13 @@ delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete)
       doing_vec = 0;
     }
 
-  /* An array can't have been allocated by new, so complain.  */
-  if (TREE_CODE (t) == ADDR_EXPR
-      && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
-      && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE)
-    warning ("deleting array `%#D'", TREE_OPERAND (t, 0));
-
   /* Deleting a pointer with the value zero is valid and has no effect.  */
   if (integer_zerop (t))
     return build1 (NOP_EXPR, void_type_node, t);
 
   if (doing_vec)
-    return build_vec_delete (t, maxindex, sfk_deleting_destructor,
+    return build_vec_delete (t, /*maxindex=*/NULL_TREE, 
+                            sfk_deleting_destructor,
                             use_global_delete);
   else
     return build_delete (type, t, sfk_deleting_destructor,
index 08836f0b82dea693c4736f7175ed25f27d8c5cce..1b8c8c8afe46e83450111db5394821d673d9c978 100644 (file)
@@ -905,6 +905,7 @@ accessible_p (tree type, tree decl)
 {
   tree binfo;
   tree t;
+  tree scope;
   access_kind access;
 
   /* Nonzero if it's OK to access DECL if it has protected
@@ -916,6 +917,11 @@ accessible_p (tree type, tree decl)
   if (!TYPE_P (context_for_name_lookup (decl)))
     return 1;
 
+  /* There is no need to perform access checks inside a thunk.  */
+  scope = current_scope ();
+  if (scope && DECL_THUNK_P (scope))
+    return 1;
+
   /* In a template declaration, we cannot be sure whether the
      particular specialization that is instantiated will be a friend
      or not.  Therefore, all access checks are deferred until
@@ -958,7 +964,7 @@ accessible_p (tree type, tree decl)
 
   /* Now, loop through the classes of which we are a friend.  */
   if (!protected_ok)
-    protected_ok = friend_accessible_p (current_scope (), decl, binfo);
+    protected_ok = friend_accessible_p (scope, decl, binfo);
 
   /* Standardize the binfo that access_in_type will use.  We don't
      need to know what path was chosen from this point onwards.  */
index 02858486b466013a0fcd6c637a47f9a6f7528eec..919d3d75c5b0e01149784292ef41b2cde788713b 100644 (file)
@@ -1371,14 +1371,9 @@ decay_conversion (tree exp)
 
       if (TREE_CODE (exp) == VAR_DECL)
        {
-         /* ??? This is not really quite correct
-            in that the type of the operand of ADDR_EXPR
-            is not the target type of the type of the ADDR_EXPR itself.
-            Question is, can this lossage be avoided?  */
-         adr = build1 (ADDR_EXPR, ptrtype, exp);
          if (!cxx_mark_addressable (exp))
            return error_mark_node;
-         TREE_CONSTANT (adr) = staticp (exp);
+         adr = build_nop (ptrtype, build_address (exp));
          TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
          return adr;
        }
index dd136645c6d507cb25a1691414da51d7b1af4880..0b1289d24122b5b0127454d418c9446019279b4b 100644 (file)
@@ -1,5 +1,11 @@
 2004-02-13  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/14122
+       * g++.dg/template/array4.C: New test.
+       
+       PR c++/14108
+       * g++.dg/inherit/thunk2.C: New test.
+
        PR c++/14083
        * g++.dg/eh/cond2.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/inherit/thunk2.C b/gcc/testsuite/g++.dg/inherit/thunk2.C
new file mode 100644 (file)
index 0000000..094891c
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/14108
+
+class ClassC {
+public:
+  ~ClassC();
+};
+
+class ClassA {
+  virtual ClassC f();
+};
+
+class ClassB : public virtual ClassA {
+  virtual ClassC f();
+};
+
+ClassC ClassB::f() {
+  return ClassC();
+}
+
diff --git a/gcc/testsuite/g++.dg/template/array4.C b/gcc/testsuite/g++.dg/template/array4.C
new file mode 100644 (file)
index 0000000..c72782b
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/14122
+
+extern const char str[];
+
+template <const char* P>
+struct A
+{
+  template <const char* R>  void foo();
+};
+
+template class A<str>;