LLVM-COV覆盖率失踪断言调用时

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

我有以下的头文件:

power.hpp:

#pragma once

#include <type_traits>

template <typename T, typename R = decltype(std::declval<T>() * std::declval<T>())>
constexpr inline R square(const T& x_) noexcept;

power.inl:

#pragma once

#include "power.hpp"

template <typename T, typename R>
constexpr inline R square(const T& x_) noexcept
{
    return (x_ * x_);
}

power_unit_test.cpp:

#include <power.inl>

int main()
{
    static_assert(square(2) == 4);
    assert(square(2) == 4);
    square(2);

    return (0);
}

与标志-fprofile-instr-generate-fcoverage-mapping使用铛++编译之后。并运行单元测试二进制文件,我得到的报告告诉我,每三行主要的是所谓的,但功能内容是只能使用一次。这是使用从独立呼叫square(2)的断言似乎无法正确生成覆盖报告。

如果删除了独立square(2)然后覆盖没有达到100%,作为断言产生小姐因某种原因覆盖。

覆盖报告全文:

power.inl:

   22|       |        template <typename T, typename R>
   23|       |        constexpr inline R square(const T& x_) noexcept
   24|      0|        {
   25|      0|            return (x_ * x_);
   26|      0|        }

power_unit_test.cpp

   29|       |int main()
   30|      1|{
   31|      1|    static_assert(arc::math::sq(2) == 4);
   32|      1|    assert(arc::math::sq(2) == 4);
   33|      1|    // arc::math::sq(2);
   34|      1|
   35|      1|    return (0);
   36|      1|}

请你能帮助我理解为什么覆盖面不被报道,我期望在这里?这是LLVM-CoV的一个bug,或我不理解的范围意图是什么?

使用自制的铛7.0.1在MacOS编译。使用cmake 3.13.2为构建系统。

c++ llvm code-coverage llvm-clang llvm-cov
1个回答
1
投票

你遇到的问题是,你的编译器内嵌两个的断言方法square()功能。由于代码内联,它永远不会让你的外部代码的调用。

您首先想到的可能是去除inline标识,但不会工作。这是因为你的编译器很可能是足够聪明的认识到,square()功能会内联和前进并做也无妨。最终的结果是外部的代码不会被调用。

所以,你需要一种方法来绕过square()功能的内联。你可以用一个函数指针做到这一点。请参阅下面的修改您的main功能:

int main()
{
    int (*f_ptr)(const int&);       // Ptr to func that takes 'const int&' and returns 'int' 
    f_ptr = &square;

    static_assert(square(2) == 4);  // Cant use 'f_ptr' here
    assert(f_ptr(2) == 4);
    f_ptr(2);

    return (0);
}

在上面的代码,我们在更换显式调用一个函数指针,square(const int&)f_ptr。其结果是,编译器不会自动内联函数的断言和代码将被成功调用两次。结果:

power.cpp:

    4|       |template <typename T, typename R>
    5|       |constexpr inline R square(const T& x_) noexcept
    6|      2|{
    7|      2|    return (x_ * x_);
    8|      2|}

power_unit_test.cpp:

    5|       |int main()
    6|      1|{
    7|      1|    int (*f_ptr)(const int&);
    8|      1|    f_ptr = &square;
    9|      1|
   10|      1|    static_assert(square(2) == 4);
   11|      1|    assert(f_ptr(2) == 4);
   12|      1|    f_ptr(2);
   13|      1|
   14|      1|    return (0);
   15|      1|}

快速笔记。由于static_assert本质上是一个编译时断言,我们不能代替电话与我们的函数指针square(),因为函数指针不constant expressions。不过不用担心,你的编译器是足够聪明,如果你尝试用函数指针square(2)我更换f_ptr(2)抱怨。

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