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

ruby-changes:47334

From: nobu <ko1@a...>
Date: Sun, 30 Jul 2017 23:48:51 +0900 (JST)
Subject: [ruby-changes:47334] nobu:r59450 (trunk): UNALIGNED_MEMBER_ACCESS

nobu	2017-07-30 23:48:45 +0900 (Sun, 30 Jul 2017)

  New Revision: 59450

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

  Log:
    UNALIGNED_MEMBER_ACCESS
    
    * eval_intern.h (UNALIGNED_MEMBER_ACCESS): suppress
      address-of-packed-member warnings by clang 4.0.

  Modified files:
    trunk/configure.in
    trunk/eval_intern.h
    trunk/thread_sync.c
    trunk/vm_method.c
Index: configure.in
===================================================================
--- configure.in	(revision 59449)
+++ configure.in	(revision 59450)
@@ -1653,6 +1653,7 @@ AC_CACHE_CHECK(packed struct attribute, https://github.com/ruby/ruby/blob/trunk/configure.in#L1653
     done])
 AS_IF([test "$rb_cv_packed_struct" != no], [
     AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], [$rb_cv_packed_struct])
+    RUBY_TRY_CFLAGS(-Wno-address-of-packed-member, [AC_DEFINE(USE_UNALIGNED_MEMBER_ACCESS)])
 ], [
     AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], x)
 ])
Index: eval_intern.h
===================================================================
--- eval_intern.h	(revision 59449)
+++ eval_intern.h	(revision 59450)
@@ -157,6 +157,22 @@ LONG WINAPI rb_w32_stack_overflow_handle https://github.com/ruby/ruby/blob/trunk/eval_intern.h#L157
 # define VAR_NOCLOBBERED(var) var
 #endif
 
+#if defined(USE_UNALIGNED_MEMBER_ACCESS) && USE_UNALIGNED_MEMBER_ACCESS
+# define UNALIGNED_MEMBER_ACCESS(expr) __extension__({ \
+    _Pragma("GCC diagnostic push"); \
+    _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); \
+    typeof(expr) unaligned_member_access_result = (expr); \
+    _Pragma("GCC diagnostic pop"); \
+    unaligned_member_access_result; \
+})
+#else
+# define UNALIGNED_MEMBER_ACCESS(expr) expr
+#endif
+#define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
+
+#undef RB_OBJ_WRITE
+#define RB_OBJ_WRITE(a, slot, b) UNALIGNED_MEMBER_ACCESS(rb_obj_write((VALUE)(a), (VALUE *)(slot), (VALUE)(b), __FILE__, __LINE__))
+
 /* clear th->ec.tag->state, and return the value */
 static inline int
 rb_threadptr_tag_state(rb_thread_t *th)
Index: thread_sync.c
===================================================================
--- thread_sync.c	(revision 59449)
+++ thread_sync.c	(revision 59450)
@@ -521,12 +521,15 @@ void rb_mutex_allow_trap(VALUE self, int https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L521
 
 /* Queue */
 
+#define queue_waitq(q) UNALIGNED_MEMBER_PTR(q, waitq)
 PACKED_STRUCT_UNALIGNED(struct rb_queue {
     struct list_head waitq;
     const VALUE que;
     int num_waiting;
 });
 
+#define szqueue_waitq(sq) UNALIGNED_MEMBER_PTR(sq, q.waitq)
+#define szqueue_pushq(sq) UNALIGNED_MEMBER_PTR(sq, pushq)
 PACKED_STRUCT_UNALIGNED(struct rb_szqueue {
     struct rb_queue q;
     int num_waiting_push;
@@ -562,7 +565,7 @@ queue_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L565
     struct rb_queue *q;
 
     obj = TypedData_Make_Struct(klass, struct rb_queue, &queue_data_type, q);
-    list_head_init(&q->waitq);
+    list_head_init(queue_waitq(q));
     return obj;
 }
 
@@ -603,8 +606,8 @@ szqueue_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L606
     struct rb_szqueue *sq;
     VALUE obj = TypedData_Make_Struct(klass, struct rb_szqueue,
 					&szqueue_data_type, sq);
-    list_head_init(&sq->q.waitq);
-    list_head_init(&sq->pushq);
+    list_head_init(szqueue_waitq(sq));
+    list_head_init(szqueue_pushq(sq));
     return obj;
 }
 
@@ -702,7 +705,7 @@ rb_queue_initialize(VALUE self) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L705
 {
     struct rb_queue *q = queue_ptr(self);
     RB_OBJ_WRITE(self, &q->que, ary_buf_new());
-    list_head_init(&q->waitq);
+    list_head_init(queue_waitq(q));
     return self;
 }
 
@@ -713,7 +716,7 @@ queue_do_push(VALUE self, struct rb_queu https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L716
 	raise_closed_queue_error(self);
     }
     rb_ary_push(check_array(self, q->que), obj);
-    wakeup_one(&q->waitq);
+    wakeup_one(queue_waitq(q));
     return self;
 }
 
@@ -756,7 +759,7 @@ rb_queue_close(VALUE self) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L759
     if (!queue_closed_p(self)) {
 	FL_SET(self, QUEUE_CLOSED);
 
-	wakeup_all(&q->waitq);
+	wakeup_all(queue_waitq(q));
     }
 
     return self;
@@ -975,8 +978,8 @@ rb_szqueue_initialize(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L978
     }
 
     RB_OBJ_WRITE(self, &sq->q.que, ary_buf_new());
-    list_head_init(&sq->q.waitq);
-    list_head_init(&sq->pushq);
+    list_head_init(szqueue_waitq(sq));
+    list_head_init(szqueue_pushq(sq));
     sq->max = max;
 
     return self;
@@ -1001,8 +1004,8 @@ rb_szqueue_close(VALUE self) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L1004
 	struct rb_szqueue *sq = szqueue_ptr(self);
 
 	FL_SET(self, QUEUE_CLOSED);
-	wakeup_all(&sq->q.waitq);
-	wakeup_all(&sq->pushq);
+	wakeup_all(szqueue_waitq(sq));
+	wakeup_all(szqueue_pushq(sq));
     }
     return self;
 }
@@ -1040,7 +1043,7 @@ rb_szqueue_max_set(VALUE self, VALUE vma https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L1043
 	diff = max - sq->max;
     }
     sq->max = max;
-    while (diff-- > 0 && wakeup_one(&sq->pushq)) {
+    while (diff-- > 0 && wakeup_one(szqueue_pushq(sq))) {
 	/* keep waking more up */
     }
     return vmax;
@@ -1086,10 +1089,11 @@ rb_szqueue_push(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L1089
 	}
 	else {
 	    struct queue_waiter qw;
+	    struct list_head *pushq = szqueue_pushq(sq);
 
 	    qw.w.th = GET_THREAD();
 	    qw.as.sq = sq;
-	    list_add_tail(&sq->pushq, &qw.w.node);
+	    list_add_tail(pushq, &qw.w.node);
 	    sq->num_waiting_push++;
 
 	    rb_ensure(queue_sleep, Qfalse, szqueue_sleep_done, (VALUE)&qw);
@@ -1111,7 +1115,7 @@ szqueue_do_pop(VALUE self, int should_bl https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L1115
     VALUE retval = queue_do_pop(self, &sq->q, should_block);
 
     if (queue_length(self, &sq->q) < sq->max) {
-	wakeup_one(&sq->pushq);
+	wakeup_one(szqueue_pushq(sq));
     }
 
     return retval;
@@ -1150,7 +1154,7 @@ rb_szqueue_clear(VALUE self) https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L1154
     struct rb_szqueue *sq = szqueue_ptr(self);
 
     rb_ary_clear(check_array(self, sq->q.que));
-    wakeup_all(&sq->pushq);
+    wakeup_all(szqueue_pushq(sq));
     return self;
 }
 
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 59449)
+++ vm_method.c	(revision 59450)
@@ -252,7 +252,7 @@ method_definition_set(const rb_method_en https://github.com/ruby/ruby/blob/trunk/vm_method.c#L252
 	  case VM_METHOD_TYPE_CFUNC:
 	    {
 		rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
-		setup_method_cfunc_struct(&def->body.cfunc, cfunc->func, cfunc->argc);
+		setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), cfunc->func, cfunc->argc);
 		return;
 	    }
 	  case VM_METHOD_TYPE_ATTRSET:
@@ -279,7 +279,7 @@ method_definition_set(const rb_method_en https://github.com/ruby/ruby/blob/trunk/vm_method.c#L279
 	    RB_OBJ_WRITE(me, &def->body.proc, (VALUE)opts);
 	    return;
 	  case VM_METHOD_TYPE_NOTIMPLEMENTED:
-	    setup_method_cfunc_struct(&def->body.cfunc, rb_f_notimplement, -1);
+	    setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), rb_f_notimplement, -1);
 	    return;
 	  case VM_METHOD_TYPE_OPTIMIZED:
 	    def->body.optimize_type = (enum method_optimized_type)opts;

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

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