this statement may fall through [-Werror=implicit-fallthrough=] 编译报错的解决方法

报错log:

drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c: In function 'rwnx_txq_vif_for_each_sta':
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c:642:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
  642 |   rwnx_vif = rwnx_vif->ap_vlan.master;
      |   ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_txq.c:643:2: note: here
  643 |  case NL80211_IFTYPE_AP:
      |  ^~~~

源码报错位置:

    switch (RWNX_VIF_TYPE(rwnx_vif)) {
    case NL80211_IFTYPE_STATION:
    case NL80211_IFTYPE_P2P_CLIENT:
    {
        if (rwnx_vif->tdls_status == TDLS_LINK_ACTIVE)
            f(rwnx_vif->sta.tdls_sta, reason, rwnx_hw);
        if (!WARN_ON(rwnx_vif->sta.ap == NULL))
            f(rwnx_vif->sta.ap, reason, rwnx_hw);
        break;
    }
    case NL80211_IFTYPE_AP_VLAN:
        rwnx_vif = rwnx_vif->ap_vlan.master;

    case NL80211_IFTYPE_AP:
    case NL80211_IFTYPE_MESH_POINT:
    case NL80211_IFTYPE_P2P_GO:
    {
        struct rwnx_sta *sta;
        list_for_each_entry(sta, &rwnx_vif->ap.sta_list, list) {
            f(sta, reason, rwnx_hw);
        }
        break;
    }
    default:
        BUG();
        break;
    }

可以看到是code中的 case NL80211_IFTYPE_AP 没有break而发生警告

警告不会导致编译报错,但是编译参数中定义了 -Werror 从而导致编译报错

解决方法:

一、找到makefile中的-Werror,删除它

二、加入break(这可能不满足代码预期)

三、使用:GCC pragma #pragma GCC diagnostic ignored "-Wimplicit-fallthrough",来禁用代码警告

如下示例(亲测有效):

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"

switch (RWNX_VIF_TYPE(rwnx_vif)) {
    case NL80211_IFTYPE_STATION:
    case NL80211_IFTYPE_P2P_CLIENT:
    {
        if (rwnx_vif->tdls_status == TDLS_LINK_ACTIVE)
            f(rwnx_vif->sta.tdls_sta, reason, rwnx_hw);
        if (!WARN_ON(rwnx_vif->sta.ap == NULL))
            f(rwnx_vif->sta.ap, reason, rwnx_hw);
        break;
    }
    case NL80211_IFTYPE_AP_VLAN:
        rwnx_vif = rwnx_vif->ap_vlan.master;
    case NL80211_IFTYPE_AP:
    case NL80211_IFTYPE_MESH_POINT:
    case NL80211_IFTYPE_P2P_GO:
    {
        struct rwnx_sta *sta;
        list_for_each_entry(sta, &rwnx_vif->ap.sta_list, list) {
            f(sta, reason, rwnx_hw);
        }
        break;
    }
    default:
        BUG();
        break;
    }
#pragma GCC diagnostic pop

注意:编译时,会在push和pop之间,禁用警告(此方法会导致此部分code调试困难,因为看不到警告)

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"

//内容

#pragma GCC diagnostic pop

四、使用__attribute__((__fallthrough__))(亲测有效,且kernel中很多地方在用);

在switch中不期望break的地方,加入__attribute__((__fallthrough__));

如下示例:

int main()
{
    enum nl80211_iftype ss = NL80211_IFTYPE_UNSPECIFIED;
   switch(ss){
       case NL80211_IFTYPE_UNSPECIFIED:
           printf("Hello, World! 11\n");
           __attribute__((__fallthrough__));
       case NL80211_IFTYPE_ADHOC:
           printf("Hello, World! 222\n");
       case NL80211_IFTYPE_STATION:
           printf("Hello, World! 33\n");
           break;
       default:
           printf("Hello, World! 55\n");
   }
   return 0;
}

 kernel-5.10中,对此属性做了重定义,如下

kernel-5.10/include/linux/compiler_attributes.h

/*
 * Add the pseudo keyword 'fallthrough' so case statement blocks
 * must end with any of these keywords:
 *   break;
 *   fallthrough;
 *   goto <label>;
 *   return [expression];
 *
 *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
 */
#if __has_attribute(__fallthrough__)
# define fallthrough                    __attribute__((__fallthrough__))
#else
# define fallthrough                    do {} while (0)  /* fallthrough */
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值