diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c index 0c895854851..f52953f6b04 100644 --- a/src/amd/vulkan/radv_nir_to_llvm.c +++ b/src/amd/vulkan/radv_nir_to_llvm.c @@ -96,8 +96,7 @@ struct radv_shader_output_values { static inline struct radv_shader_context * radv_shader_context_from_abi(struct ac_shader_abi *abi) { - struct radv_shader_context *ctx = NULL; - return container_of(abi, ctx, abi); + return container_of(abi, struct radv_shader_context, abi); } static LLVMValueRef get_rel_patch_id(struct radv_shader_context *ctx) diff --git a/src/amd/vulkan/radv_shader_args.h b/src/amd/vulkan/radv_shader_args.h index cb79f8a9efd..c4c57f38d44 100644 --- a/src/amd/vulkan/radv_shader_args.h +++ b/src/amd/vulkan/radv_shader_args.h @@ -48,8 +48,7 @@ struct radv_shader_args { static inline struct radv_shader_args * radv_shader_args_from_ac(struct ac_shader_args *args) { - struct radv_shader_args *radv_args = NULL; - return (struct radv_shader_args *) container_of(args, radv_args, ac); + return container_of(args, struct radv_shader_args, ac); } void radv_declare_shader_args(struct radv_shader_args *args, diff --git a/src/broadcom/compiler/qpu_schedule.c b/src/broadcom/compiler/qpu_schedule.c index 9fe842c3e84..ee3d800fdad 100644 --- a/src/broadcom/compiler/qpu_schedule.c +++ b/src/broadcom/compiler/qpu_schedule.c @@ -1490,7 +1490,7 @@ qpu_set_branch_targets(struct v3d_compile *c) struct list_head *entry = block->instructions.prev; for (int i = 0; i < 3; i++) entry = entry->prev; - struct qinst *branch = container_of(entry, branch, link); + struct qinst *branch = container_of(entry, struct qinst, link); assert(branch->qpu.type == V3D_QPU_INSTR_TYPE_BRANCH); /* Make sure that the if-we-don't-jump diff --git a/src/gallium/auxiliary/driver_rbug/rbug_core.c b/src/gallium/auxiliary/driver_rbug/rbug_core.c index 9e0dfc0d7ca..6d6ca7ec04b 100644 --- a/src/gallium/auxiliary/driver_rbug/rbug_core.c +++ b/src/gallium/auxiliary/driver_rbug/rbug_core.c @@ -47,9 +47,6 @@ #define U642VOID(x) ((void *)(uintptr_t)(x)) #define VOID2U64(x) ((uint64_t)(uintptr_t)(x)) -#define container_of(ptr, type, field) \ - (type*)((char*)ptr - offsetof(type, field)) - struct rbug_rbug { struct rbug_screen *rb_screen; diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 5e0d4e226fc..532c1cc9257 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -393,7 +393,7 @@ static void fd_trace_record_ts(struct u_trace *ut, struct pipe_resource *timestamps, unsigned idx) { - struct fd_batch *batch = container_of(ut, batch, trace); + struct fd_batch *batch = container_of(ut, struct fd_batch, trace); struct fd_ringbuffer *ring = batch->nondraw ? batch->draw : batch->gmem; if (ring->cur == batch->last_timestamp_cmd) { @@ -411,7 +411,7 @@ static uint64_t fd_trace_read_ts(struct u_trace_context *utctx, struct pipe_resource *timestamps, unsigned idx) { - struct fd_context *ctx = container_of(utctx, ctx, trace_context); + struct fd_context *ctx = container_of(utctx, struct fd_context, trace_context); struct fd_bo *ts_bo = fd_resource(timestamps)->bo; /* Only need to stall on results for the first entry: */ diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c index e4aa1907a13..9fc6bb389ca 100644 --- a/src/gallium/drivers/iris/iris_context.c +++ b/src/gallium/drivers/iris/iris_context.c @@ -81,12 +81,12 @@ iris_lost_context_state(struct iris_batch *batch) struct iris_context *ice = NULL; if (batch->name == IRIS_BATCH_RENDER) { - ice = container_of(batch, ice, batches[IRIS_BATCH_RENDER]); + ice = container_of(batch, struct iris_context, batches[IRIS_BATCH_RENDER]); assert(&ice->batches[IRIS_BATCH_RENDER] == batch); batch->screen->vtbl.init_render_context(batch); } else if (batch->name == IRIS_BATCH_COMPUTE) { - ice = container_of(batch, ice, batches[IRIS_BATCH_COMPUTE]); + ice = container_of(batch, struct iris_context, batches[IRIS_BATCH_COMPUTE]); assert(&ice->batches[IRIS_BATCH_COMPUTE] == batch); batch->screen->vtbl.init_compute_context(batch); diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 3b92121254b..409928a70fe 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -812,8 +812,7 @@ iris_upload_slice_hashing_state(struct iris_batch *batch) if (subslices_delta == 0) return; - struct iris_context *ice = NULL; - ice = container_of(batch, ice, batches[IRIS_BATCH_RENDER]); + struct iris_context *ice = container_of(batch, struct iris_context, batches[IRIS_BATCH_RENDER]); assert(&ice->batches[IRIS_BATCH_RENDER] == batch); unsigned size = GENX(SLICE_HASH_TABLE_length) * 4; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c index 853db925b73..83c3c6fd82d 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_context.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c @@ -42,7 +42,7 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push) if (!push->user_priv) return; - nv30 = container_of(push->user_priv, nv30, bufctx); + nv30 = container_of(push->user_priv, struct nv30_context, bufctx); screen = &nv30->screen->base; nouveau_fence_next(screen); diff --git a/src/gallium/drivers/r600/compute_memory_pool.c b/src/gallium/drivers/r600/compute_memory_pool.c index 6b64b3da0b1..ecd1fd06433 100644 --- a/src/gallium/drivers/r600/compute_memory_pool.c +++ b/src/gallium/drivers/r600/compute_memory_pool.c @@ -436,7 +436,7 @@ static void compute_memory_move_item(struct compute_memory_pool *pool, if (pool->item_list != item->link.prev) { ASSERTED struct compute_memory_item *prev; - prev = container_of(item->link.prev, item, link); + prev = container_of(item->link.prev, struct compute_memory_item, link); assert(prev->start_in_dw + prev->size_in_dw <= new_start_in_dw); } diff --git a/src/gallium/drivers/radeonsi/si_query.c b/src/gallium/drivers/radeonsi/si_query.c index 36e02b6e86a..3437681eb9e 100644 --- a/src/gallium/drivers/radeonsi/si_query.c +++ b/src/gallium/drivers/radeonsi/si_query.c @@ -634,8 +634,7 @@ void si_query_hw_destroy(struct si_context *sctx, struct si_query *squery) static bool si_query_hw_prepare_buffer(struct si_context *sctx, struct si_query_buffer *qbuf) { - static const struct si_query_hw si_query_hw_s; - struct si_query_hw *query = container_of(qbuf, &si_query_hw_s, buffer); + struct si_query_hw *query = container_of(qbuf, struct si_query_hw, buffer); struct si_screen *screen = sctx->screen; /* The caller ensures that the buffer is currently unused by the GPU. */ diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 53bf95efa13..2da1cebb30e 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -164,8 +164,7 @@ struct si_shader_context { static inline struct si_shader_context *si_shader_context_from_abi(struct ac_shader_abi *abi) { - struct si_shader_context *ctx = NULL; - return container_of(abi, ctx, abi); + return container_of(abi, struct si_shader_context, abi); } /* si_shader.c */ diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c index b092ae270c6..1b1a8077e20 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c @@ -481,7 +481,7 @@ svga_buffer_upload_gb_command(struct svga_context *svga, if (!invalidate_cmd) return PIPE_ERROR_OUT_OF_MEMORY; - cicmd = container_of(invalidate_cmd, cicmd, body); + cicmd = container_of(invalidate_cmd, struct svga_3d_invalidate_gb_image, body); cicmd->header.size = sizeof(*invalidate_cmd); swc->surface_relocation(swc, &invalidate_cmd->image.sid, NULL, sbuf->handle, @@ -513,7 +513,7 @@ svga_buffer_upload_gb_command(struct svga_context *svga, /* The whole_update_command is a SVGA3dCmdHeader plus the * SVGA3dCmdUpdateGBImage command. */ - whole_update_cmd = container_of(update_cmd, whole_update_cmd, body); + whole_update_cmd = container_of(update_cmd, struct svga_3d_update_gb_image, body); } /* Init the first UPDATE_GB_IMAGE command */ diff --git a/src/gallium/frontends/omx/bellagio/vid_dec_av1.c b/src/gallium/frontends/omx/bellagio/vid_dec_av1.c index c020a0d7ee2..3ee93313652 100644 --- a/src/gallium/frontends/omx/bellagio/vid_dec_av1.c +++ b/src/gallium/frontends/omx/bellagio/vid_dec_av1.c @@ -2421,8 +2421,7 @@ void vid_dec_av1_FrameDecoded(OMX_COMPONENTTYPE *comp, if (task->is_sef_task) { if (task->buf_ref_count == 0) { - struct dec_av1_task *t; - t = container_of(task->buf_ref, t, buf); + struct dec_av1_task *t = container_of(task->buf_ref, struct dec_av1_task, buf); list_del(&task->list); t->buf_ref_count--; list_del(&t->list); diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index 90c598316f0..0ab39539182 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -625,8 +625,7 @@ bool amdgpu_bo_can_reclaim(struct pb_buffer *_buf) bool amdgpu_bo_can_reclaim_slab(void *priv, struct pb_slab_entry *entry) { - struct amdgpu_winsys_bo *bo = NULL; /* fix container_of */ - bo = container_of(entry, bo, u.slab.entry); + struct amdgpu_winsys_bo *bo = container_of(entry, struct amdgpu_winsys_bo, u.slab.entry); return amdgpu_bo_can_reclaim(&bo->base); } @@ -1032,10 +1031,9 @@ static void amdgpu_bo_sparse_destroy(struct pb_buffer *_buf) } while (!list_is_empty(&bo->u.sparse.backing)) { - struct amdgpu_sparse_backing *dummy = NULL; sparse_free_backing_buffer(bo, container_of(bo->u.sparse.backing.next, - dummy, list)); + struct amdgpu_sparse_backing, list)); } amdgpu_va_range_free(bo->u.sparse.va_handle); @@ -1332,8 +1330,7 @@ amdgpu_bo_create(struct amdgpu_winsys *ws, if (!entry) return NULL; - bo = NULL; - bo = container_of(entry, bo, u.slab.entry); + bo = container_of(entry, struct amdgpu_winsys_bo, u.slab.entry); pipe_reference_init(&bo->base.reference, 1); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index d7f892bc1a5..220008ec880 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -296,7 +296,7 @@ static void radeon_bomgr_free_va(const struct radeon_info *info, heap->start = va; /* Delete uppermost hole if it reaches the new top */ if (!list_is_empty(&heap->holes)) { - hole = container_of(heap->holes.next, hole, list); + hole = container_of(heap->holes.next, struct radeon_bo_va_hole, list); if ((hole->offset + hole->size) == va) { heap->start = hole->offset; list_del(&hole->list); @@ -306,7 +306,7 @@ static void radeon_bomgr_free_va(const struct radeon_info *info, } else { struct radeon_bo_va_hole *next; - hole = container_of(&heap->holes, hole, list); + hole = container_of(&heap->holes, struct radeon_bo_va_hole, list); LIST_FOR_EACH_ENTRY(next, &heap->holes, list) { if (next->offset < va) break; @@ -749,8 +749,7 @@ bool radeon_bo_can_reclaim(struct pb_buffer *_buf) bool radeon_bo_can_reclaim_slab(void *priv, struct pb_slab_entry *entry) { - struct radeon_bo *bo = NULL; /* fix container_of */ - bo = container_of(entry, bo, u.slab.entry); + struct radeon_bo *bo = container_of(entry, struct radeon_bo, u.slab.entry); return radeon_bo_can_reclaim(&bo->base); } @@ -1044,8 +1043,7 @@ radeon_winsys_bo_create(struct radeon_winsys *rws, if (!entry) return NULL; - bo = NULL; - bo = container_of(entry, bo, u.slab.entry); + bo = container_of(entry, struct radeon_bo, u.slab.entry); pipe_reference_init(&bo->base.reference, 1); diff --git a/src/mesa/vbo/vbo_private.h b/src/mesa/vbo/vbo_private.h index 560e087c5f4..19ce569c202 100644 --- a/src/mesa/vbo/vbo_private.h +++ b/src/mesa/vbo/vbo_private.h @@ -58,24 +58,21 @@ vbo_context_const(const struct gl_context *ctx) static inline struct gl_context * gl_context_from_vbo_exec(struct vbo_exec_context *exec) { - struct gl_context *ctx = NULL; - return container_of(exec, ctx, vbo_context.exec); + return container_of(exec, struct gl_context, vbo_context.exec); } static inline const struct gl_context * gl_context_from_vbo_exec_const(const struct vbo_exec_context *exec) { - struct gl_context *ctx = NULL; - return container_of(exec, ctx, vbo_context.exec); + return container_of(exec, struct gl_context, vbo_context.exec); } static inline struct gl_context * gl_context_from_vbo_save(struct vbo_save_context *save) { - struct gl_context *ctx = NULL; - return container_of(save, ctx, vbo_context.save); + return container_of(save, struct gl_context, vbo_context.save); } diff --git a/src/util/list.h b/src/util/list.h index d50eb1ea5dd..fdc6fafb1a1 100644 --- a/src/util/list.h +++ b/src/util/list.h @@ -166,11 +166,9 @@ static inline void list_validate(const struct list_head *list) * * 'sample' MUST be initialized, or else the result is undefined! */ -#ifndef container_of -#define container_of(ptr, sample, member) \ +#define list_container_of(ptr, sample, member) \ (void *)((char *)(ptr) \ - ((char *)&(sample)->member - (char *)(sample))) -#endif #define list_first_entry(ptr, type, member) \ LIST_ENTRY(type, (ptr)->next, member) @@ -180,31 +178,31 @@ static inline void list_validate(const struct list_head *list) #define LIST_FOR_EACH_ENTRY(pos, head, member) \ - for (pos = NULL, pos = container_of((head)->next, pos, member); \ + for (pos = NULL, pos = list_container_of((head)->next, pos, member); \ &pos->member != (head); \ - pos = container_of(pos->member.next, pos, member)) + pos = list_container_of(pos->member.next, pos, member)) #define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \ - for (pos = NULL, pos = container_of((head)->next, pos, member), \ - storage = container_of(pos->member.next, pos, member); \ + for (pos = NULL, pos = list_container_of((head)->next, pos, member), \ + storage = list_container_of(pos->member.next, pos, member); \ &pos->member != (head); \ - pos = storage, storage = container_of(storage->member.next, storage, member)) + pos = storage, storage = list_container_of(storage->member.next, storage, member)) #define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \ - for (pos = NULL, pos = container_of((head)->prev, pos, member), \ - storage = container_of(pos->member.prev, pos, member); \ + for (pos = NULL, pos = list_container_of((head)->prev, pos, member), \ + storage = list_container_of(pos->member.prev, pos, member); \ &pos->member != (head); \ - pos = storage, storage = container_of(storage->member.prev, storage, member)) + pos = storage, storage = list_container_of(storage->member.prev, storage, member)) #define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \ - for (pos = NULL, pos = container_of((start), pos, member); \ + for (pos = NULL, pos = list_container_of((start), pos, member); \ &pos->member != (head); \ - pos = container_of(pos->member.next, pos, member)) + pos = list_container_of(pos->member.next, pos, member)) #define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \ - for (pos = NULL, pos = container_of((start), pos, member); \ + for (pos = NULL, pos = list_container_of((start), pos, member); \ &pos->member != (head); \ - pos = container_of(pos->member.prev, pos, member)) + pos = list_container_of(pos->member.prev, pos, member)) #define list_for_each_entry(type, pos, head, member) \ for (type *pos = LIST_ENTRY(type, (head)->next, member), \ diff --git a/src/util/macros.h b/src/util/macros.h index 3483428bc5d..d7fe24e5e9b 100644 --- a/src/util/macros.h +++ b/src/util/macros.h @@ -87,6 +87,27 @@ # define STATIC_ASSERT(COND) do { } while (0) #endif +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + */ +#ifndef __GNUC__ + /* a grown-up compiler is required for the extra type checking: */ +# define container_of(ptr, type, member) \ + (type*)((uint8_t *)ptr - offsetof(type, member)) +#else +# define __same_type(a, b) \ + __builtin_types_compatible_p(__typeof__(a), __typeof__(b)) +# define container_of(ptr, type, member) ({ \ + uint8_t *__mptr = (uint8_t *)(ptr); \ + STATIC_ASSERT(__same_type(*(ptr), ((type *)0)->member) || \ + __same_type(*(ptr), void) || \ + !"pointer type mismatch in container_of()"); \ + ((type *)(__mptr - offsetof(type, member))); \ + }) +#endif /** * Unreachable macro. Useful for suppressing "control reaches end of non-void