The method `template <int KIND> Result operator()(const TypeParamInquiry<KIND> &)` is defined in `evaluate::GetShapeHelper` as well as in its ancestor `evaluate::Traverse`. Normally, only the overloads of class that first defines method name would be considered, but the declaration `using Base::operator()` imports the base class methods with the same signature. Msvc interprets this as an ambiguity. [[ https://en.cppreference.com/w/cpp/language/using_declaration | According to cppreference.com ]], derived class members hide members imported with the using directive. Hence this is probably a bug in msvc not implementing this rule for templated methods.
The base class method `evaluate::Traverse::operator()(const TypeParamInquiry<KIND> &)` forwards the call to the visitor of its unpacked argument.is pattern occurs in the following classes:
GCC and Clang call the derived class method in one test case (Semantics/assign04.f90),* `evaluate::IsConstantExprHelper`
in which case the base class overload computed the same values as the derived class overload (`Scalar()`).* `evaluate::IsInitialDataTargetHelper`
I do not know whether this generally the case* `evaluate::CheckSpecificationExprHelper`
Fix by moving the generic TypeParamInquiry operator() overload into the derived classes that do not define this overload themselves.
This patch is part of the series to [[ http://lists.llvm.org/pipermail/flang-dev/2020-July/000448.html | make flang compilable with MS Visual Studio ]].