Linter 检查自动类型中的引用删除

问题描述 投票:0回答:1

我想知道是否有针对这种情况的编译器选项或 clang-tidy 检查:

#include<iostream>
#include <ostream>

int glob = 12;

int& test(int d){
    std::cout << &glob << std::endl;
    return glob;
}


int main() {

    auto a = test(10);
    std::cout << &a << std::endl;
    return 0;
}

如果我突然忘记将

&
放在
auto
之后,我会在输出中看到不同的地址,这是预期的,但是是否有任何编译器标志clang-tidy标志警告我是吗?

c++ g++ clang-tidy
1个回答
0
投票

我不知道现有的警告或检查可以做到这一点,但有一个 可以使用

clang-query
检查使用类型
auto
声明变量的模式 (与
auto&
不同)并通过调用来初始化它 返回引用的函数。

以下 shell 脚本使用这样的方式调用

clang-query
匹配表达式:

#!/bin/sh

PATH=$HOME/opt/clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/bin:$PATH

# In the following, the comments are seen and ignored by clang-query
# (not the shell).  But beware that clang-query has odd rules for where
# comments can go, and poor error reporting if the rules are violated.
query='m

  varDecl(                         # Report any variable declaration
    hasType(                       # whose declared type
      autoType()                   # is `auto`,
    ),
    hasInitializer(                # and that has an initializer
      implicitCastExpr(            # that is an implicit conversion
        hasSourceExpression(       # from
          callExpr(                # a function call expression
            callee(                # where the callee
              functionDecl(        # is a directly named function
                returns(           # whose return type
                  referenceType()  # is a reference.
                )
              )
            )
          )
        )
      )
    )
  ).bind("decl")

'

if [ "x$1" = "x" ]; then
  echo "usage: $0 filename.cc -- <compile options like -I, etc.>"
  exit 2
fi

# Run the query.  Setting 'bind-root' to false means clang-query will
# not also print a redundant "root" binding.
clang-query \
  -c="set bind-root false" \
  -c="$query" \
  "$@"

# EOF

输入以下内容:

// test.cc
// Cases for `auto` declaring non-ref initialized from ref.

int &getref();

int getnonref();

void g(int &refparam)
{
  // ref -> ref
  auto &r2r = getref();       // not reported: no conversion

  // ref -> nonref
  auto r2nr = getref();       // reported

  // nonref -> nonref
  auto nr2nr = getnonref();   // not reported: no conversion

  // nonref -> ref: Syntax error.
  //auto &nr2r = getnonref();

  auto rp2nr = refparam;      // not reported: not a call
}

// EOF

它产生输出:

$ ./cmd.sh test.cc --

Match #1:

$PWD/test.cc:14:3: note: "decl" binds here
  auto r2nr = getref();       // reported
  ^~~~~~~~~~~~~~~~~~~~
1 match.

在匹配表达式中,我将报告限制为初始化程序 函数调用。 但是,根据您的需求,您可能想要 删除整个

hasSourceExpression
匹配器(所以
implicitCastExpr
后面跟着
()
),从而报告任何
auto
使用隐式转换初始化的声明,因为可以说任何 这种情况是“令人惊讶的”,也许是无意的。

我还没有对这个匹配器进行任何大规模的测试或调整,所以它 可能需要进一步调整才能用于生产。

clang-query
集成到构建或测试中的过程 工作流程与
clang-tidy
的工作流程基本相同,假设 后者是通过直接调用完成的。

© www.soinside.com 2019 - 2024. All rights reserved.