[flang] Addresses issue flang-compiler/f18#242 by making non-inline definitions for the two versions

of ExpressionBase::derived().  gcc-8.2 on macOS was choosing to create
non-inline instances of derived() during the explicit instantiations of
ExpressionBase in expression.cc and fold.cc.  During linking of any
executable, the linker failed when it found these duplicate definitions.

While this solution works, it removes the opportunity to inline the trivial
derived() functions.  Another solution would be to make all of the
templates related to ExpressionBase in expression.cc and fold.cc available
in a single .cc file, where the explicit instantiation
FOR_EACH_TYPE_AND_KIND(template class ExpressionBase) is done once. This
approach would allow inlining, but require something like template
implementation headers that could be included into the instantiation .cc
file.

Original-commit: flang-compiler/f18@074de39418
Reviewed-on: https://github.com/flang-compiler/f18/pull/248
Tree-same-pre-rewrite: false
This commit is contained in:
Paul Henning 2018-12-20 10:39:29 -07:00
parent eef439577c
commit b61b31dfcd
2 changed files with 12 additions and 2 deletions

View File

@ -189,6 +189,16 @@ template<typename T> DynamicType ArrayConstructor<T>::GetType() const {
return result.GetType();
}
template<typename A>
typename ExpressionBase<A>::Derived &ExpressionBase<A>::derived() {
return *static_cast<Derived *>(this);
}
template<typename A>
const typename ExpressionBase<A>::Derived &ExpressionBase<A>::derived() const {
return *static_cast<const Derived *>(this);
}
template<typename A>
std::optional<DynamicType> ExpressionBase<A>::GetType() const {
if constexpr (IsLengthlessIntrinsicType<Result>) {

View File

@ -68,8 +68,8 @@ public:
private:
using Derived = Expr<Result>;
Derived &derived() { return *static_cast<Derived *>(this); }
const Derived &derived() const { return *static_cast<const Derived *>(this); }
Derived &derived();
const Derived &derived() const;
public:
template<typename A> Derived &operator=(const A &x) {