[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:
peter klausler 2019-10-17 10:57:01 -07:00
parent ca9d6be0e4
commit db4ae5cd98
9 changed files with 31 additions and 36 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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();

View File

@ -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()) {

View File

@ -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)) {

View File

@ -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