forked from OSchip/llvm-project
[flang] Work around a gcc-7.2 specific build bug by recoding with a better approach
Original-commit: flang-compiler/f18@bc2b4015b0 Reviewed-on: https://github.com/flang-compiler/f18/pull/785
This commit is contained in:
parent
4f761d601e
commit
f3ae44f645
|
@ -28,9 +28,9 @@ namespace Fortran::evaluate {
|
|||
// able to fold it (yet) into a known constant value; specifically,
|
||||
// the expression may reference derived type kind parameters whose values
|
||||
// are not yet known.
|
||||
class IsConstantExprHelper : public AllTraverse<IsConstantExprHelper> {
|
||||
class IsConstantExprHelper : public AllTraverse<IsConstantExprHelper, true> {
|
||||
public:
|
||||
using Base = AllTraverse<IsConstantExprHelper>;
|
||||
using Base = AllTraverse<IsConstantExprHelper, true>;
|
||||
IsConstantExprHelper() : Base{*this} {}
|
||||
using Base::operator();
|
||||
|
||||
|
@ -76,8 +76,8 @@ template bool IsConstantExpr(const Expr<SomeInteger> &);
|
|||
// This code determines whether an expression is allowable as the static
|
||||
// data address used to initialize a pointer with "=> x". See C765.
|
||||
struct IsInitialDataTargetHelper
|
||||
: public AllTraverse<IsInitialDataTargetHelper> {
|
||||
using Base = AllTraverse<IsInitialDataTargetHelper>;
|
||||
: public AllTraverse<IsInitialDataTargetHelper, true> {
|
||||
using Base = AllTraverse<IsInitialDataTargetHelper, true>;
|
||||
using Base::operator();
|
||||
explicit IsInitialDataTargetHelper(parser::ContextualMessages &m)
|
||||
: Base{*this}, messages_{m} {}
|
||||
|
|
|
@ -660,33 +660,20 @@ bool IsProcedurePointer(const Expr<SomeType> &expr) {
|
|||
}
|
||||
|
||||
// IsNullPointer()
|
||||
static bool IsNullPointer(const ProcedureRef &call) {
|
||||
auto *intrinsic{call.proc().GetSpecificIntrinsic()};
|
||||
return intrinsic &&
|
||||
intrinsic->characteristics.value().attrs.test(
|
||||
characteristics::Procedure::Attr::NullPointer);
|
||||
}
|
||||
template<TypeCategory CAT, int KIND>
|
||||
bool IsNullPointer(const Expr<Type<CAT, KIND>> &expr) {
|
||||
const auto *call{std::get_if<FunctionRef<Type<CAT, KIND>>>(&expr.u)};
|
||||
return call && IsNullPointer(*call);
|
||||
}
|
||||
template<TypeCategory CAT> bool IsNullPointer(const Expr<SomeKind<CAT>> &expr) {
|
||||
return std::visit([](const auto &x) { return IsNullPointer(x); }, expr.u);
|
||||
}
|
||||
bool IsNullPointer(const Expr<SomeDerived> &expr) {
|
||||
const auto *call{std::get_if<FunctionRef<SomeDerived>>(&expr.u)};
|
||||
return call && IsNullPointer(*call);
|
||||
}
|
||||
struct IsNullPointerHelper : public AllTraverse<IsNullPointerHelper, false> {
|
||||
using Base = AllTraverse<IsNullPointerHelper, false>;
|
||||
IsNullPointerHelper() : Base(*this) {}
|
||||
using Base::operator();
|
||||
bool operator()(const ProcedureRef &call) const {
|
||||
auto *intrinsic{call.proc().GetSpecificIntrinsic()};
|
||||
return intrinsic &&
|
||||
intrinsic->characteristics.value().attrs.test(
|
||||
characteristics::Procedure::Attr::NullPointer);
|
||||
}
|
||||
bool operator()(const NullPointer &) const { return true; }
|
||||
};
|
||||
bool IsNullPointer(const Expr<SomeType> &expr) {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
[](const NullPointer &) { return true; },
|
||||
[](const BOZLiteralConstant &) { return false; },
|
||||
[](const ProcedureDesignator &) { return false; },
|
||||
[](const auto &x) { return IsNullPointer(x); },
|
||||
},
|
||||
expr.u);
|
||||
return IsNullPointerHelper{}(expr);
|
||||
}
|
||||
|
||||
// GetLastTarget()
|
||||
|
|
|
@ -247,11 +247,12 @@ private:
|
|||
|
||||
// For validity checks across an expression: if any operator() result is
|
||||
// false, so is the overall result.
|
||||
template<typename Visitor, typename Base = Traverse<Visitor, bool>>
|
||||
template<typename Visitor, bool DefaultValue,
|
||||
typename Base = Traverse<Visitor, bool>>
|
||||
struct AllTraverse : public Base {
|
||||
AllTraverse(Visitor &v) : Base{v} {}
|
||||
using Base::operator();
|
||||
static bool Default() { return true; }
|
||||
static bool Default() { return DefaultValue; }
|
||||
static bool Combine(bool x, bool y) { return x && y; }
|
||||
};
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ add_executable(integer-test
|
|||
target_link_libraries(integer-test
|
||||
FortranEvaluateTesting
|
||||
FortranEvaluate
|
||||
FortranSemantics
|
||||
)
|
||||
|
||||
add_executable(intrinsics-test
|
||||
|
@ -85,6 +86,8 @@ add_executable(logical-test
|
|||
|
||||
target_link_libraries(logical-test
|
||||
FortranEvaluateTesting
|
||||
FortranEvaluate
|
||||
FortranSemantics
|
||||
)
|
||||
|
||||
# GCC -fno-exceptions breaks the fenv.h interfaces needed to capture
|
||||
|
|
Loading…
Reference in New Issue