forked from OSchip/llvm-project
[flang] Address most review comments
Original-commit: flang-compiler/f18@43720b5057 Reviewed-on: https://github.com/flang-compiler/f18/pull/782 Tree-same-pre-rewrite: false
This commit is contained in:
parent
ca9d6be0e4
commit
db4ae5cd98
|
@ -123,7 +123,7 @@ std::optional<TypeAndShape> TypeAndShape::Characterize(
|
|||
}
|
||||
|
||||
bool TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages,
|
||||
const TypeAndShape &that, const char *thisDesc, const char *thatDesc,
|
||||
const TypeAndShape &that, const char *thisIs, const char *thatIs,
|
||||
bool isElemental) const {
|
||||
const auto &len{that.LEN()};
|
||||
if (!type_.IsTypeCompatibleWith(that.type_)) {
|
||||
|
@ -131,13 +131,13 @@ bool TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages,
|
|||
if (len) {
|
||||
len->AsFortran(lenstr);
|
||||
}
|
||||
messages.Say("%s type '%s' is not compatible with %s type '%s'"_err_en_US,
|
||||
thatDesc, that.type_.AsFortran(lenstr.str()), thisDesc,
|
||||
type_.AsFortran());
|
||||
messages.Say(
|
||||
"%1$s type '%2$s' is not compatible with %3$s type '%4$s'"_err_en_US,
|
||||
thatIs, that.type_.AsFortran(lenstr.str()), thisIs, type_.AsFortran());
|
||||
return false;
|
||||
}
|
||||
return isElemental ||
|
||||
CheckConformance(messages, shape_, that.shape_, thisDesc, thatDesc);
|
||||
CheckConformance(messages, shape_, that.shape_, thisIs, thatIs);
|
||||
}
|
||||
|
||||
void TypeAndShape::AcquireShape(const semantics::ObjectEntityDetails &object) {
|
||||
|
|
|
@ -104,8 +104,8 @@ public:
|
|||
const Attrs &attrs() const { return attrs_; }
|
||||
|
||||
int Rank() const { return GetRank(shape_); }
|
||||
bool IsCompatibleWith(parser::ContextualMessages &, const TypeAndShape &,
|
||||
const char * = "POINTER", const char * = "TARGET",
|
||||
bool IsCompatibleWith(parser::ContextualMessages &, const TypeAndShape &that,
|
||||
const char *thisIs = "POINTER", const char *thatIs = "TARGET",
|
||||
bool isElemental = false) const;
|
||||
|
||||
std::ostream &Dump(std::ostream &) const;
|
||||
|
|
|
@ -550,23 +550,23 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
|
|||
}
|
||||
|
||||
bool CheckConformance(parser::ContextualMessages &messages, const Shape &left,
|
||||
const Shape &right, const char *leftDesc, const char *rightDesc) {
|
||||
const Shape &right, const char *leftIs, const char *rightIs) {
|
||||
if (!left.empty() && !right.empty()) {
|
||||
int n{GetRank(left)};
|
||||
int rn{GetRank(right)};
|
||||
if (n != rn) {
|
||||
messages.Say("Rank of %s is %d, but %s has rank %d"_err_en_US, leftDesc,
|
||||
n, rightDesc, rn);
|
||||
messages.Say("Rank of %1$s is %2$d, but %3$s has rank %4$d"_err_en_US,
|
||||
leftIs, n, rightIs, rn);
|
||||
return false;
|
||||
} else {
|
||||
for (int j{0}; j < n; ++j) {
|
||||
if (auto leftDim{ToInt64(left[j])}) {
|
||||
if (auto rightDim{ToInt64(right[j])}) {
|
||||
if (*leftDim != *rightDim) {
|
||||
messages.Say("Dimension %d of %s has extent %jd, "
|
||||
"but %s has extent %jd"_err_en_US,
|
||||
j + 1, leftDesc, static_cast<std::intmax_t>(*leftDim),
|
||||
rightDesc, static_cast<std::intmax_t>(*rightDim));
|
||||
messages.Say("Dimension %1$d of %2$s has extent %3$jd, "
|
||||
"but %4$s has extent %5$jd"_err_en_US,
|
||||
j + 1, leftIs, static_cast<std::intmax_t>(*leftDim), rightIs,
|
||||
static_cast<std::intmax_t>(*rightDim));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,9 +190,9 @@ std::optional<Shape> GetShape(FoldingContext &context, const A &x) {
|
|||
|
||||
// Compilation-time shape conformance checking, when corresponding extents
|
||||
// are known.
|
||||
bool CheckConformance(parser::ContextualMessages &, const Shape &,
|
||||
const Shape &, const char * = "left operand",
|
||||
const char * = "right operand");
|
||||
bool CheckConformance(parser::ContextualMessages &, const Shape &left,
|
||||
const Shape &right, const char *leftIs = "left operand",
|
||||
const char *rightIs = "right operand");
|
||||
|
||||
}
|
||||
#endif // FORTRAN_EVALUATE_SHAPE_H_
|
||||
|
|
|
@ -682,8 +682,9 @@ bool IsNullPointer(const Expr<SomeType> &expr) {
|
|||
return std::visit(
|
||||
common::visitors{
|
||||
[](const NullPointer &) { return true; },
|
||||
[](const ProcedureRef &call) { return IsNullPointer(call); },
|
||||
[](const auto &) { return false; },
|
||||
[](const BOZLiteralConstant &) { return false; },
|
||||
[](const ProcedureDesignator &) { return false; },
|
||||
[](const auto &x) { return IsNullPointer(x); },
|
||||
},
|
||||
expr.u);
|
||||
}
|
||||
|
|
|
@ -303,6 +303,7 @@ template<typename A> const Symbol *UnwrapWholeSymbolDataRef(const A &x) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// GetFirstSymbol(A%B%C[I]%D) -> A
|
||||
template<typename A> const Symbol *GetFirstSymbol(const A &x) {
|
||||
if (auto dataRef{ExtractDataRef(x)}) {
|
||||
return &dataRef->GetFirstSymbol();
|
||||
|
|
|
@ -164,18 +164,6 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
|
|||
bool dummyIsValue{
|
||||
dummy.attrs.test(characteristics::DummyDataObject::Attr::Value)};
|
||||
|
||||
bool actualIsAsynchronous{false};
|
||||
bool actualIsVolatile{false};
|
||||
const Symbol *actualFirstSymbol{evaluate::GetFirstSymbol(actual)};
|
||||
if (actualFirstSymbol != nullptr) {
|
||||
const Symbol &ultimate{actualFirstSymbol->GetUltimate()};
|
||||
actualIsAsynchronous =
|
||||
actualFirstSymbol->attrs().test(Attr::ASYNCHRONOUS) ||
|
||||
ultimate.attrs().test(Attr::ASYNCHRONOUS);
|
||||
actualIsVolatile = actualFirstSymbol->attrs().test(Attr::VOLATILE) ||
|
||||
ultimate.attrs().test(Attr::VOLATILE);
|
||||
}
|
||||
|
||||
if (actualIsPolymorphic && dummyIsPolymorphic &&
|
||||
actualIsCoindexed) { // 15.5.2.4(2)
|
||||
messages.Say(
|
||||
|
@ -190,6 +178,11 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
|
|||
}
|
||||
|
||||
// derived type actual argument checks
|
||||
const Symbol *actualFirstSymbol{evaluate::GetFirstSymbol(actual)};
|
||||
bool actualIsAsynchronous{
|
||||
actualFirstSymbol && actualFirstSymbol->attrs().test(Attr::ASYNCHRONOUS)};
|
||||
bool actualIsVolatile{
|
||||
actualFirstSymbol && actualFirstSymbol->attrs().test(Attr::VOLATILE)};
|
||||
if (!actualType.type().IsUnlimitedPolymorphic() &&
|
||||
actualType.type().category() == TypeCategory::Derived) {
|
||||
const auto &derived{actualType.type().GetDerivedTypeSpec()};
|
||||
|
@ -276,12 +269,12 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
|
|||
}
|
||||
if (actualIsPolymorphic) {
|
||||
messages.Say(
|
||||
"Element of polymorphic array may not be associated with a %s array"_err_en_US,
|
||||
"Polymorphic scalar may not be associated with a %s array"_err_en_US,
|
||||
dummyName);
|
||||
}
|
||||
if (actualLastSymbol && actualLastSymbol->attrs().test(Attr::POINTER)) {
|
||||
messages.Say(
|
||||
"Element of pointer array may not be associated with a %s array"_err_en_US,
|
||||
"Scalar POINTER target may not be associated with a %s array"_err_en_US,
|
||||
dummyName);
|
||||
}
|
||||
if (actualLastObject && actualLastObject->IsAssumedShape()) {
|
||||
|
|
|
@ -1568,7 +1568,7 @@ const Symbol *ExpressionAnalyzer::ResolveGeneric(const Symbol &symbol,
|
|||
characteristics::Procedure::Characterize(
|
||||
ProcedureDesignator{*specific}, context_.intrinsics())}) {
|
||||
ActualArguments localActuals{actuals};
|
||||
auto messages{CheckExplicitInterface(
|
||||
auto messages{semantics::CheckExplicitInterface(
|
||||
*procedure, localActuals, GetFoldingContext(), scope)};
|
||||
if (messages.empty() &&
|
||||
CheckCompatibleArguments(*procedure, localActuals)) {
|
||||
|
|
|
@ -166,11 +166,11 @@ module m01
|
|||
character(10) :: c(:)
|
||||
!ERROR: Whole scalar actual argument may not be associated with a dummy argument 'x=' array
|
||||
call assumedsize(x)
|
||||
!ERROR: Element of pointer array may not be associated with a dummy argument 'x=' array
|
||||
!ERROR: Scalar POINTER target may not be associated with a dummy argument 'x=' array
|
||||
call assumedsize(p(1))
|
||||
!ERROR: Element of assumed-shape array may not be associated with a dummy argument 'x=' array
|
||||
call assumedsize(ashape(1))
|
||||
!ERROR: Element of polymorphic array may not be associated with a dummy argument 'x=' array
|
||||
!ERROR: Polymorphic scalar may not be associated with a dummy argument 'x=' array
|
||||
call polyassumedsize(polyarray(1))
|
||||
call charray(c(1:1)) ! not an error if character
|
||||
call assumedsize(arr(1)) ! not an error if element in sequence
|
||||
|
|
Loading…
Reference in New Issue