]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/25895 (wrong code with ?: and derived class pointers)
authorMark Mitchell <mark@codesourcery.com>
Sun, 22 Jan 2006 00:42:40 +0000 (00:42 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 22 Jan 2006 00:42:40 +0000 (00:42 +0000)
PR c++/25895
* class.c (build_base_path): Generate a NOP_EXPR instead of a
COMPONENT_REF if the base and derived classes are at the same
address.
PR c++/25856
* decl.c (begin_destructor_body): Robustify.
PR c++/25858
* parser.c (cp_parser_direct_declarator): Robustify.

PR c++/25895
* g++.dg/inherit/conv2.C: New test.
PR c++/25856
* g++.dg/parse/dtor7.C: New test.
PR c++/25858
* g++.dg/template/crash44.C: New test.

From-SVN: r110084

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/conv2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/dtor7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/crash44.C [new file with mode: 0644]

index 42c69e8d7b925c7453d56fae986d01d1864de733..ea7355bcccecaba00376ab001a34b6aeef3a9724 100644 (file)
@@ -1,3 +1,16 @@
+2006-01-21  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/25895
+       * class.c (build_base_path): Generate a NOP_EXPR instead of a
+       COMPONENT_REF if the base and derived classes are at the same
+       address.
+
+       PR c++/25856
+       * decl.c (begin_destructor_body): Robustify.
+
+       PR c++/25858 
+       * parser.c (cp_parser_direct_declarator): Robustify.
+       
 2006-01-20  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        * parser.c (cp_lexer_next_token_is_keyword): Simplify.
index bd89b558abda430f7c24b7dc2f5cebdc3d59d906..6b075cbd0b72a42904428730fb8d1689cf41569e 100644 (file)
@@ -289,13 +289,23 @@ build_base_path (enum tree_code code,
 
   offset = BINFO_OFFSET (binfo);
   fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
+  target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
 
   /* Do we need to look in the vtable for the real offset?  */
   virtual_access = (v_binfo && fixed_type_p <= 0);
 
   /* Do we need to check for a null pointer?  */
-  if (want_pointer && !nonnull && (virtual_access || !integer_zerop (offset)))
-    null_test = error_mark_node;
+  if (want_pointer && !nonnull)
+    {
+      /* If we know the conversion will not actually change the value
+        of EXPR, then we can avoid testing the expression for NULL.
+        We have to avoid generating a COMPONENT_REF for a base class
+        field, because other parts of the compiler know that such
+        expressions are always non-NULL.  */
+      if (!virtual_access && integer_zerop (offset))
+       return build_nop (build_pointer_type (target_type), expr);
+      null_test = error_mark_node;
+    }
 
   /* Protect against multiple evaluation if necessary.  */
   if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
@@ -376,8 +386,6 @@ build_base_path (enum tree_code code,
        offset = v_offset;
     }
 
-  target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
-
   target_type = cp_build_qualified_type
     (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
   ptr_target_type = build_pointer_type (target_type);
index ae0b7e85c4410c670515c0ba4bfde3bed1ddd389..3c98d4918f23cdfca8b9f6ea1bce0ef91ba03501 100644 (file)
@@ -10628,18 +10628,23 @@ begin_destructor_body (void)
 {
   tree compound_stmt;
 
-  compound_stmt = begin_compound_stmt (0);
-
-  /* Make all virtual function table pointers in non-virtual base
-     classes point to CURRENT_CLASS_TYPE's virtual function
-     tables.  */
-  initialize_vtbl_ptrs (current_class_ptr);
-
-  finish_compound_stmt (compound_stmt);
-
-  /* And insert cleanups for our bases and members so that they
-     will be properly destroyed if we throw.  */
-  push_base_cleanups ();
+  /* If the CURRENT_CLASS_TYPE is incomplete, we will have already
+     issued an error message.  We still want to try to process the
+     body of the function, but initialize_vtbl_ptrs will crash if
+     TYPE_BINFO is NULL.  */
+  if (COMPLETE_TYPE_P (current_class_type))
+    {
+      compound_stmt = begin_compound_stmt (0);
+      /* Make all virtual function table pointers in non-virtual base
+        classes point to CURRENT_CLASS_TYPE's virtual function
+        tables.  */
+      initialize_vtbl_ptrs (current_class_ptr);
+      finish_compound_stmt (compound_stmt);
+      
+      /* And insert cleanups for our bases and members so that they
+        will be properly destroyed if we throw.  */
+      push_base_cleanups ();
+    }
 }
 
 /* At the end of every destructor we generate code to delete the object if
index 148eb1d14b3a941a311c96ba25b36d6e65d8f822..4c09b2fde9bf6e1a71f30595ae1b4823964279e2 100644 (file)
@@ -11479,22 +11479,24 @@ cp_parser_direct_declarator (cp_parser* parser,
 
              if (TREE_CODE (unqualified_name) == TYPE_DECL)
                {
-                 if (qualifying_scope 
-                     && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
+                 tree name_type = TREE_TYPE (unqualified_name);
+                 if (class_type && same_type_p (name_type, class_type))
                    {
-                     error ("invalid use of constructor as a template");
-                     inform ("use %<%T::%D%> instead of %<%T::%T%> to name "
-                             "the constructor in a qualified name",
-                             class_type,
-                             DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
-                             class_type, class_type);
-                     declarator = cp_error_declarator;
-                     break;
+                     if (qualifying_scope
+                         && CLASSTYPE_USE_TEMPLATE (name_type))
+                       {
+                         error ("invalid use of constructor as a template");
+                         inform ("use %<%T::%D%> instead of %<%T::%D%> to "
+                                 "name the constructor in a qualified name",
+                                 class_type,
+                                 DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
+                                 class_type, name_type);
+                         declarator = cp_error_declarator;
+                         break;
+                       }
+                     else
+                       unqualified_name = constructor_name (class_type);
                    }
-                 else if (class_type
-                          && same_type_p (TREE_TYPE (unqualified_name),
-                                          class_type))
-                   unqualified_name = constructor_name (class_type);
                  else
                    {
                      /* We do not attempt to print the declarator
index 7c28e0ee25b0f817985676dc1feacdf75ac8e77b..07aa699ca0c60f9ca2163df6e383518603a24610 100644 (file)
@@ -1,3 +1,14 @@
+2006-01-21  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/25895
+       * g++.dg/inherit/conv2.C: New test.
+
+       PR c++/25856
+       * g++.dg/parse/dtor7.C: New test.
+
+       PR c++/25858
+       * g++.dg/template/crash44.C: New test.
+
 2005-01-21  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/25124
diff --git a/gcc/testsuite/g++.dg/inherit/conv2.C b/gcc/testsuite/g++.dg/inherit/conv2.C
new file mode 100644 (file)
index 0000000..fd00838
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/25895
+// { dg-do run }
+
+class base {
+public:
+  base() {}
+private:
+  int val_;
+};
+
+class derived : public base {
+public:
+  derived() {}
+};
+
+static bool x = true ? (derived*)0 : (base*)0;
+
+int main ()
+{
+  if (x)
+    return 1;
+}
diff --git a/gcc/testsuite/g++.dg/parse/dtor7.C b/gcc/testsuite/g++.dg/parse/dtor7.C
new file mode 100644 (file)
index 0000000..3525624
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/25856
+
+struct A; // { dg-error "forward" } 
+A::~A() {} // { dg-error "undefined" }
diff --git a/gcc/testsuite/g++.dg/template/crash44.C b/gcc/testsuite/g++.dg/template/crash44.C
new file mode 100644 (file)
index 0000000..d5596c1
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/25858
+
+namespace N {
+  template<int> struct A {};
+}
+
+struct B N::A<0> {}; // { dg-error "invalid" }