llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.87k stars 11.93k forks source link

[clang-tidy] MSVC's Pragma packed not expanded correctly in structs #64112

Open EduMenges opened 1 year ago

EduMenges commented 1 year ago

When applying pragma packed in a struct definition, clang-tidy gives the following error: Declaration of anonymous struct must be a definition - clang(anon_type_definition) Declaration does not declare anything - clang(-Wmissing-declarations)

You can easily reproduce the error with the following code:

#include <cstdint>

#ifdef __GNUC__
#if __cplusplus >= 201103L
#define __begin_packed [[gnu::packed]]
#else
#define __begin_packed __attribute__((packed))
#endif
#define __end_packed
#else // MSVC
#define __begin_packed __pragma(pack(push, 1))
#define __end_packed   __pragma(pack(pop))
#endif

struct Normal {
    uint8_t a;
    uint32_t b;
};

struct __begin_packed Packed {
    uint8_t a;
    uint32_t b;
} __end_packed;

struct After {
    uint8_t a;
    uint32_t b;
};

int main() {
    static_assert(sizeof(struct Normal) == 8);
    static_assert(sizeof(struct Packed) == 5);
    static_assert(sizeof(struct After) == 8);
}

This only happens for MSVC, despite the code compiling and behaving correctly. In Visual Studio, with their static analysis, it does not even display an error. The error does not occur with the following code:

__pragma(pack(push, 1))
struct Packed {
    uint8_t a;
    uint32_t b;
} __end_packed;

And the behavior is as expected. It only occurs if pragma is placed right after struct. The way I'm using it may be obtuse, but that is a way to guarantee the same behavior accross GCC-based compilers and MSVC.

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-frontend

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-tidy