[前][次][番号順一覧][スレッド一覧]

ruby-changes:46261

From: nobu <ko1@a...>
Date: Mon, 17 Apr 2017 11:41:05 +0900 (JST)
Subject: [ruby-changes:46261] nobu:r58381 (trunk): eval.c: copy before cause setup

nobu	2017-04-17 11:41:00 +0900 (Mon, 17 Apr 2017)

  New Revision: 58381

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58381

  Log:
    eval.c: copy before cause setup
    
    * eval.c (setup_exception): copy frozen exception before setting
      up a cause not only a backtrace.

  Modified files:
    trunk/eval.c
    trunk/test/ruby/test_exception.rb
Index: test/ruby/test_exception.rb
===================================================================
--- test/ruby/test_exception.rb	(revision 58380)
+++ test/ruby/test_exception.rb	(revision 58381)
@@ -799,6 +799,13 @@ end.join https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L799
     assert_nil(orig_error.cause, bug13043)
   end
 
+  def test_cause_with_frozen_exception
+    exc = ArgumentError.new("foo").freeze
+    assert_raise_with_message(ArgumentError, exc.message) {
+      raise exc, cause: RuntimeError.new("bar")
+    }
+  end
+
   def test_anonymous_message
     assert_in_out_err([], "raise Class.new(RuntimeError), 'foo'", [], /foo\n/)
   end
Index: eval.c
===================================================================
--- eval.c	(revision 58380)
+++ eval.c	(revision 58381)
@@ -481,18 +481,17 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L481
 	mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
 	nocause = 0;
     }
-    if (cause != Qundef) {
-	exc_setup_cause(mesg, cause);
-    }
-    else if (nocause) {
-	exc_setup_cause(mesg, Qnil);
-    }
-    else if (!rb_ivar_defined(mesg, id_cause)) {
-	exc_setup_cause(mesg, get_thread_errinfo(th));
+    if (cause == Qundef) {
+	if (nocause) {
+	    cause = Qnil;
+	}
+	else if (!rb_ivar_defined(mesg, id_cause)) {
+	    cause = get_thread_errinfo(th);
+	}
     }
 
     file = rb_source_loc(&line);
-    if (file && !NIL_P(mesg)) {
+    if ((file && !NIL_P(mesg)) || (cause != Qundef))  {
 	VALUE at;
 	int status;
 
@@ -501,11 +500,16 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L500
 	    VALUE bt;
 	    if (rb_threadptr_set_raised(th)) goto fatal;
 	    bt = rb_get_backtrace(mesg);
-	    if (NIL_P(bt)) {
-		at = rb_threadptr_backtrace_object(th);
+	    if (!NIL_P(bt) || cause == Qundef) {
 		if (OBJ_FROZEN(mesg)) {
 		    mesg = rb_obj_dup(mesg);
 		}
+	    }
+	    if (cause != Qundef) {
+		exc_setup_cause(mesg, cause);
+	    }
+	    if (NIL_P(bt)) {
+		at = rb_threadptr_backtrace_object(th);
 		rb_ivar_set(mesg, idBt_locations, at);
 		set_backtrace(mesg, at);
 	    }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]