* except.c (build_throw): Check throw expression validity.
authorNathan Sidwell <nathan@acm.org>
Fri, 4 Jun 1999 01:31:42 +0000 (01:31 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Fri, 4 Jun 1999 01:31:42 +0000 (01:31 +0000)
From-SVN: r27344

gcc/cp/ChangeLog
gcc/cp/except.c
gcc/testsuite/g++.old-deja/g++.robertl/eh990323-1.C
gcc/testsuite/g++.old-deja/g++.robertl/ice990323-1.C
gcc/testsuite/g++.old-deja/g++.robertl/ice990323-2.C
gcc/testsuite/g++.old-deja/g++.robertl/ice990323-3.C
gcc/testsuite/g++.old-deja/g++.robertl/ice990323-4.C
gcc/testsuite/g++.old-deja/g++.robertl/ice990323-5.C

index b7f428906ab400bb12788cf66f80b4964a3ca1a8..d59db6bf0fa2b8f0171b203e7e4202ae9732968e 100644 (file)
@@ -1,3 +1,7 @@
+1999-06-04  Nathan Sidwell  <nathan@acm.org>
+
+       * except.c (build_throw): Check throw expression validity.
+
 1999-06-03  Mark Mitchell  <mark@codesourcery.com>
 
        * decl.c (grokdeclarator): Don't treat arbitrary types as unsigned
index 9e2d6af592aabece0bbd6ed794a9f9df60a77dec..5bdbd8c979bee07801a8c8aa55eb47e71f9b33a4 100644 (file)
@@ -1152,6 +1152,30 @@ build_throw (e)
 
   if (e == null_node)
     cp_warning ("throwing NULL, which has integral, not pointer type");
+  
+  if (e != NULL_TREE)
+    {
+      tree core;
+      int is_ptr;
+      
+      /* Cannot throw an incomplete type. */
+      e = require_complete_type (e);
+      if (e == error_mark_node)
+        return e;
+      
+      /* Or a pointer or ref to one, other than cv void *.  */
+      core = TREE_TYPE (e);
+      is_ptr = TREE_CODE (core) == POINTER_TYPE;
+      if (is_ptr || TREE_CODE (core) == REFERENCE_TYPE)
+        {
+          core = TREE_TYPE (core);
+      
+          if (is_ptr && same_type_p (TYPE_MAIN_VARIANT (core), void_type_node))
+            /* OK */;
+          else if (!complete_type_or_else (core, NULL_TREE))
+            return error_mark_node;
+        }
+    }
 
   e = build1 (THROW_EXPR, void_type_node, e);
   TREE_SIDE_EFFECTS (e) = 1;
index 9bf8a098c0fbb29bc78c92bc3ee12defcbcc8554..ef6d2dc77e1e6730dae39ae4d11cb32f35d311dc 100644 (file)
@@ -17,7 +17,7 @@ template <class T> void ff(T)
 {
 }
 
-void g(void)
+void g(int)
 {
 }
 
index c03154bdf8a8e6662cf7705567fda9c273def698..06112d257c5625b216ee9cb5bf87fb50ae73a13e 100644 (file)
@@ -1,7 +1,9 @@
+// Build don't link:
+
 //test 2
 struct A {};
 void f()
 {
-        struct A;
-        throw *(new A);
+        struct A; // ERROR - forward ref
+        throw *(new A); // ERROR - invalid use of undefined type
 }
index 3fa5bd566d16efa6c7a76fc3a9afacd30746b41d..0686ee5748d9e15068aa3f08153f57949cf4c87e 100644 (file)
@@ -25,7 +25,7 @@ void f4()
        throw A<double, 47, A<int, 36, short> > ("hi michey");
 }
 
-main()
+int main()
 {
        int flag;
 
index 55cb16c705eddcf8452540214c2e142a15d184ee..842e6478f5bb1ac1093c179b1b7eadfa6b90311b 100644 (file)
@@ -1,3 +1,4 @@
+// Build don't link:
 // try throwing overloaded function
 
 void f(int)
@@ -10,5 +11,5 @@ void f(long)
 
 void g()
 {
-       throw &f;
+       throw &f; // ERROR - insufficient contextual information
 }
index 85bbb457d34d9d64ce5c0e882dc1d400fbc87761..7f3f20ef92d8f6e7a27942e4c7b00b594db693c4 100644 (file)
@@ -1,3 +1,4 @@
+// Build don't link:
 // try throwing template function name
 
 template <class T> void f(T);
@@ -8,5 +9,5 @@ template <class T> void f(T)
 
 void g()
 {
-       throw &f;
+       throw &f; // ERROR - insufficient contextual information
 }
index c49b66e9fa58bb50d95cc18e34e76859daaf2cea..45225e3f0ceda1ee8675c351dcbd9bb745e10ac8 100644 (file)
@@ -1,3 +1,4 @@
+// Build don't link:
 // check attempting to throw an overloaded function
 
 struct A {
@@ -7,5 +8,5 @@ struct A {
 
 void g()
 {
-       throw &A::f;
+       throw &A::f; // ERROR - insufficient context
 }