OSDN Git Service

PR c++/17867
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Oct 2004 05:02:54 +0000 (05:02 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Oct 2004 05:02:54 +0000 (05:02 +0000)
* error.c (dump_expr): Correct handling of AGGR_INIT_EXPRs using a
constructor.

PR c++/17670
* init.c (build_new): Correct comments.
* parser.c (cp_parser_new_expression): Use NULL_TREE for nelts in
the non-array case.

PR c++/17821
* parser.c (cp_parser_postfix_dot_deref_expression): If the
pseduo-destructor-name production does not work, fall back to the
ordinary production.

PR c++/17826
* tree.c (cp_tree_equal): Handle a BASELINK.

PR c++/17687
* g++.dg/parse/error19.C: New test.

PR c++/17670
* g++.dg/init/new11.C: New test.

PR c++/17821
* g++.dg/parse/error20.C: New test.

PR c++/17826
* g++.dg/template/crash24.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88836 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/new11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/error19.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/error20.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/crash24.C [new file with mode: 0644]

index 5c4c7c8..6084f51 100644 (file)
@@ -1,5 +1,22 @@
 2004-10-09  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/17867
+       * error.c (dump_expr): Correct handling of AGGR_INIT_EXPRs using a
+       constructor.
+
+       PR c++/17670
+       * init.c (build_new): Correct comments.
+       * parser.c (cp_parser_new_expression): Use NULL_TREE for nelts in
+       the non-array case.
+
+       PR c++/17821
+       * parser.c (cp_parser_postfix_dot_deref_expression): If the
+       pseduo-destructor-name production does not work, fall back to the
+       ordinary production.
+
+       PR c++/17826
+       * tree.c (cp_tree_equal): Handle a BASELINK.
+
        PR c++/17524
        * cp-tree.h (check_var_type): New function.
        * decl.c (check_var_type): New function, split out from ...
index 8ac6e2b..af973d6 100644 (file)
@@ -1343,7 +1343,7 @@ dump_expr (tree t, int flags)
        if (fn && TREE_CODE (fn) == FUNCTION_DECL)
          {
            if (DECL_CONSTRUCTOR_P (fn))
-             pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (TREE_TYPE (t)));
+             dump_type (DECL_CONTEXT (fn), flags);
            else
              dump_decl (fn, 0);
          }
index ceb6d69..2d04334 100644 (file)
@@ -1606,31 +1606,14 @@ build_builtin_delete_call (tree addr)
   return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
 }
 \f
-/* Generate a C++ "new" expression. DECL is either a TREE_LIST
-   (which needs to go through some sort of groktypename) or it
-   is the name of the class we are newing. INIT is an initialization value.
-   It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces.
-   If INIT is void_type_node, it means do *not* call a constructor
-   for this instance.
-
-   For types with constructors, the data returned is initialized
-   by the appropriate constructor.
-
-   Whether the type has a constructor or not, if it has a pointer
-   to a virtual function table, then that pointer is set up
-   here.
-
-   Unless I am mistaken, a call to new () will return initialized
-   data regardless of whether the constructor itself is private or
-   not.  NOPE; new fails if the constructor is private (jcm).
-
-   Note that build_new does nothing to assure that any special
-   alignment requirements of the type are met.  Rather, it leaves
-   it up to malloc to do the right thing.  Otherwise, folding to
-   the right alignment cal cause problems if the user tries to later
-   free the memory returned by `new'.
-
-   PLACEMENT is the `placement' list for user-defined operator new ().  */
+/* Generate a representation for a C++ "new" expression.  PLACEMENT is
+   a TREE_LIST of placement-new arguments (or NULL_TREE if none).  If
+   NELTS is NULL, TYPE is the type of the storage to be allocated.  If
+   NELTS is not NULL, then this is an array-new allocation; TYPE is
+   the type of the elements in the array and NELTS is the number of
+   elements in the array.  INIT, if non-NULL, is the initializer for
+   the new object.  If USE_GLOBAL_NEW is true, then the user
+   explicitly wrote "::new" rather than just "new".  */
 
 tree
 build_new (tree placement, tree type, tree nelts, tree init, 
index 9bd3f18..7fb9d96 100644 (file)
@@ -4274,6 +4274,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
   tree name;
   bool dependent_p;
   bool template_p;
+  bool pseudo_destructor_p;
   tree scope = NULL_TREE;
 
   /* If this is a `->' operator, dereference the pointer.  */
@@ -4315,11 +4316,34 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
        postfix_expression = error_mark_node;
     }
 
-  /* If the SCOPE is not a scalar type, we are looking at an
-     ordinary class member access expression, rather than a
-     pseudo-destructor-name.  */
-  if (!scope || !SCALAR_TYPE_P (scope))
+  /* Assume this expression is not a pseudo-destructor access.  */
+  pseudo_destructor_p = false;
+
+  /* If the SCOPE is a scalar type, then, if this is a valid program,
+     we must be looking at a pseudo-destructor-name.  */
+  if (scope && SCALAR_TYPE_P (scope))
     {
+      tree s;
+      tree type;
+
+      cp_parser_parse_tentatively (parser);
+      /* Parse the pseudo-destructor-name.  */
+      s = NULL_TREE;
+      cp_parser_pseudo_destructor_name (parser, &s, &type);
+      if (cp_parser_parse_definitely (parser))
+       {
+         pseudo_destructor_p = true;
+         postfix_expression
+           = finish_pseudo_destructor_expr (postfix_expression,
+                                            s, TREE_TYPE (type));
+       }
+    }
+
+  if (!pseudo_destructor_p)
+    {
+      /* If the SCOPE is not a scalar type, we are looking at an
+        ordinary class member access expression, rather than a
+        pseudo-destructor-name.  */
       template_p = cp_parser_optional_template_keyword (parser);
       /* Parse the id-expression.  */
       name = cp_parser_id_expression (parser, template_p,
@@ -4354,19 +4378,6 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
       postfix_expression
        = finish_class_member_access_expr (postfix_expression, name);
     }
-  /* Otherwise, try the pseudo-destructor-name production.  */
-  else
-    {
-      tree s = NULL_TREE;
-      tree type;
-
-      /* Parse the pseudo-destructor-name.  */
-      cp_parser_pseudo_destructor_name (parser, &s, &type);
-      /* Form the call.  */
-      postfix_expression
-       = finish_pseudo_destructor_expr (postfix_expression,
-                                        s, TREE_TYPE (type));
-    }
 
   /* We no longer need to look up names in the scope of the object on
      the left-hand side of the `.' or `->' operator.  */
@@ -4862,7 +4873,7 @@ cp_parser_new_expression (cp_parser* parser)
          inform ("try removing the parentheses around the type-id");
          cp_parser_direct_new_declarator (parser);
        }
-      nelts = integer_one_node;
+      nelts = NULL_TREE;
     }
   /* Otherwise, there must be a new-type-id.  */
   else
index a8cea23..a4b7cf9 100644 (file)
@@ -1500,6 +1500,12 @@ cp_tree_equal (tree t1, tree t2)
     case IDENTIFIER_NODE:
       return false;
 
+    case BASELINK:
+      return (BASELINK_BINFO (t1) == BASELINK_BINFO (t2)
+             && BASELINK_ACCESS_BINFO (t1) == BASELINK_ACCESS_BINFO (t2)
+             && cp_tree_equal (BASELINK_FUNCTIONS (t1),
+                               BASELINK_FUNCTIONS (t2)));
+
     case TEMPLATE_PARM_INDEX:
       return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
              && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
index b983c01..2c47616 100644 (file)
@@ -1,3 +1,17 @@
+2004-10-09  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/17687
+       * g++.dg/parse/error19.C: New test.
+
+       PR c++/17670
+       * g++.dg/init/new11.C: New test.
+
+       PR c++/17821
+       * g++.dg/parse/error20.C: New test.
+
+       PR c++/17826
+       * g++.dg/template/crash24.C: New test.
+       
 2004-10-10  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        PR c/17301
diff --git a/gcc/testsuite/g++.dg/init/new11.C b/gcc/testsuite/g++.dg/init/new11.C
new file mode 100644 (file)
index 0000000..bf06aa4
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/17670
+// { dg-do run }
+
+#include <cstdlib>
+#include <new>
+
+bool abort_new;
+void *operator new[](size_t bytes) throw (std::bad_alloc) { 
+  if (abort_new)
+    abort(); 
+  return operator new (bytes);
+}
+
+
+struct X {};  
+int main () {
+  // Do not abort until main is running in case startup code uses
+  // operator new[].
+  abort_new = true;
+  new (X);
+}
diff --git a/gcc/testsuite/g++.dg/parse/error19.C b/gcc/testsuite/g++.dg/parse/error19.C
new file mode 100644 (file)
index 0000000..24a66af
--- /dev/null
@@ -0,0 +1,13 @@
+// PR C++/17867
+
+struct A
+{  // { dg-error "candidate" }
+  A(int);
+};
+
+const A& foo();
+
+void bar()
+{
+  foo()=A(0); // { dg-error "A" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/error20.C b/gcc/testsuite/g++.dg/parse/error20.C
new file mode 100644 (file)
index 0000000..ee7390a
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/17821
+
+struct A {
+  A(int i) {}
+};
+struct B {
+  int i;
+};
+struct C {
+  B* p;
+};
+int main() {
+  C c;
+  A(c.p.i); // { dg-error "member.*non-class" }
+  return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/template/crash24.C b/gcc/testsuite/g++.dg/template/crash24.C
new file mode 100644 (file)
index 0000000..49b8c7e
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/17826
+
+struct A
+{
+  template<typename> static int foo();
+};
+
+template<int> struct B {};
+
+template<typename T> void bar()
+{
+  B<sizeof A::foo<T>()> b1;
+  B<sizeof A::foo<T>()> b2;
+}