Open Rush10233 opened 2 months ago
https://timsong-cpp.github.io/cppwp/n4868/basic.lookup.classref#3
If the unqualified-id is
~
type-name, the type-name is looked up in the context of the entire postfix-expression. If the typeT
of the object expression is of a class typeC
, the type-name is also looked up in the scope of classC
. At least one of the lookups shall find a name that refers to cvT
.
Lookup for A
does not find the type B
, ~
type-name can only call the destructor on the same type as the postfix-expression, not a base type.
@llvm/issue-subscribers-clang-frontend
Author: None (Rush10233)
These lookup rules were heavily modified by P1787R6. It looks like this is valid in C++23 but was not valid before that.
It should be accepted as an extension (in non-SFINAE contexts, with a pedantic warning) in C++20.
@Endilll @sdkrystian
@MitalAshok FYI P1787R6 was accepted as a DR so we would apply the change unconditionally
I think this is invalid in post-P1787R6 wording as well according to [basic.lookup.qual.general]/4.6:
If a qualified name Q follows a ~: — <...> — The type-name that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under the interpretation established by at least one (successful) lookup performed.
In the example, Q
refers to A
, but lookup context is decltype(*b)
, which is B
.
This interpretation is also supported by a FIXME we have in the test for CWG399: https://github.com/llvm/llvm-project/blob/5c0eb1a6e4679cc741f75f5ddc53d4878dabc1f2/clang/test/CXX/drs/cwg3xx.cpp#L1731 (This line is in function template, hence the FIXME instead of the diagnostic we see in the original example in this issue.)
Consider:
The code will work only if the destructor
~A()
in the derived class pointerB *b
is called with qualified nameA::~A()
. I'm not sure whether this is necessary. class.dtor_#17 says that "In an explicit destructor call, the destructor is specified by a ~ followed by a type-name or decltype-specifier that denotes the destructor's class type. The invocation of a destructor is subject to the usual rules for member functions ([class.mfct]);", but usual member function does not have to be called with a qualified name in derived class instance.GCC is now accepting this code, but MSVC does not accept it either.
https://godbolt.org/z/sW6YEhc8j