Is it possible to apply attributes to destructors? Example:
#if defined (__GNUC__) && !defined(__clang__)
# define TEST_PRE_ATTR [[deprecated]] __attribute__((deprecated))
# define TEST_POST_ATTR __attribute__((error("test")))
#elif defined(_MSC_VER) && !defined(__clang__)
# define TEST_PRE_ATTR [[deprecated]] __declspec(deprecated)
# define TEST_POST_ATTR
#elif defined (__clang__)
# define TEST_PRE_ATTR [[deprecated]] __attribute__((deprecated))
# define TEST_POST_ATTR __attribute__((diagnose_if(true, "test", "error")))
#endif
struct Foo {
//TEST_PRE_ATTR
void bar()
//TEST_POST_ATTR
{}
TEST_PRE_ATTR
~Foo()
TEST_POST_ATTR
= default;
};
int main() {
Foo* f = new Foo();
f->bar();
delete f;
return 0;
}
GCC, Clang, and MSVC ignore all of these attributes on Foo::~Foo
. If you apply the same attributes to Foo::bar
, they create warnings as expected. According to the standard and cppreference, the grammar for destructors should allow leading and trailing attributes. (And I suppose the fact that this does not produce any syntax errors confirms that.)
In my specific case, I have an UndefinedBehaviorSanitizer build (-fsanitize=undefined
) and I am trying to use __attribute__((no_sanitize("undefined")))
on a destructor to suppress an error from an upstream library (out of my control). However, I can't suppress the error because all compilers seem to be ignoring this attribute.
I have a feeling that the answer will be something extremely unsatisfying like "compilers are allowed to ignore any attribute for any reason." If that is the case, can someone suggest a workaround? I would rather not do something as heavy-handed as disabling UBSan for the entire target.