drm: fix potential dangling else problems in for_each_ macros
authorJani Nikula <jani.nikula@intel.com>
Tue, 24 Nov 2015 19:21:55 +0000 (21:21 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 25 Nov 2015 08:29:21 +0000 (09:29 +0100)
commit373701b1fc7d7c0013ae4fffd8103615c150751e
tree8ac8879cb421dd4ae80cb9a7bc377e222e2d91df
parented293f7754934b26c6f3db0dbc39ec2ed990f286
drm: fix potential dangling else problems in for_each_ macros

We have serious dangling else bugs waiting to happen in our for_each_
style macros with ifs. Consider, for example,

 #define drm_for_each_plane_mask(plane, dev, plane_mask) \
         list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \
                 if ((plane_mask) & (1 << drm_plane_index(plane)))

If this is used in context:

if (condition)
drm_for_each_plane_mask(plane, dev, plane_mask);
else
foo();

foo() will be called for each plane *not* in plane_mask, if condition
holds, and not at all if condition doesn't hold.

Fix this by reversing the conditions in the macros, and adding an else
branch for the "for each" block, so that other if/else blocks can't
interfere. Provide a "for_each_if" helper macro to make it easier to get
this right.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1448392916-2281-1-git-send-email-jani.nikula@intel.com
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
include/drm/drmP.h
include/drm/drm_atomic.h
include/drm/drm_crtc.h