forked from OSchip/llvm-project
[flang] enable call06.f90 test
Relax checking when irrelevant due to INTENT(IN) Add and pass call14.f90 test on VALUE Allow ASYNCHRONOUS/VOLATILE to apply to host/USE associated entities, add tests Pass call06 Check C827 & C828, fix tests Original-commit: flang-compiler/f18@df6cb83794 Reviewed-on: https://github.com/flang-compiler/f18/pull/801
This commit is contained in:
parent
e46a5a4c10
commit
926da903f2
|
@ -106,6 +106,9 @@ Extensions, deletions, and legacy features supported by default
|
|||
* When a scalar CHARACTER actual argument of the same kind is known to
|
||||
have a length shorter than the associated dummy argument, it is extended
|
||||
on the right with blanks, similar to assignment.
|
||||
* When a dummy argument is `POINTER` or `ALLOCATABLE` and is `INTENT(IN)`, we
|
||||
relax enforcement of some requirements on actual arguments that must otherwise
|
||||
hold true for definable arguments.
|
||||
|
||||
Extensions supported when enabled by options
|
||||
--------------------------------------------
|
||||
|
|
|
@ -41,7 +41,8 @@ static void CopyAttrs(const semantics::Symbol &src, A &dst,
|
|||
}
|
||||
|
||||
bool TypeAndShape::operator==(const TypeAndShape &that) const {
|
||||
return type_ == that.type_ && shape_ == that.shape_ && attrs_ == that.attrs_;
|
||||
return type_ == that.type_ && shape_ == that.shape_ &&
|
||||
attrs_ == that.attrs_ && corank_ == that.corank_;
|
||||
}
|
||||
|
||||
std::optional<TypeAndShape> TypeAndShape::Characterize(
|
||||
|
@ -142,6 +143,7 @@ bool TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages,
|
|||
|
||||
void TypeAndShape::AcquireShape(const semantics::ObjectEntityDetails &object) {
|
||||
CHECK(shape_.empty() && !attrs_.test(Attr::AssumedRank));
|
||||
corank_ = object.coshape().Rank();
|
||||
if (object.IsAssumedRank()) {
|
||||
attrs_.set(Attr::AssumedRank);
|
||||
return;
|
||||
|
|
|
@ -102,6 +102,7 @@ public:
|
|||
}
|
||||
const Shape &shape() const { return shape_; }
|
||||
const Attrs &attrs() const { return attrs_; }
|
||||
int corank() const { return corank_; }
|
||||
|
||||
int Rank() const { return GetRank(shape_); }
|
||||
bool IsCompatibleWith(parser::ContextualMessages &, const TypeAndShape &that,
|
||||
|
@ -119,6 +120,7 @@ protected:
|
|||
std::optional<Expr<SomeInteger>> LEN_;
|
||||
Shape shape_;
|
||||
Attrs attrs_;
|
||||
int corank_{0};
|
||||
};
|
||||
|
||||
// 15.3.2.2
|
||||
|
|
|
@ -330,34 +330,66 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
|
|||
}
|
||||
}
|
||||
|
||||
// 15.5.2.5 -- actual & dummy are both POINTER or both ALLOCATABLE
|
||||
bool actualIsAllocatable{
|
||||
actualLastSymbol && IsAllocatable(*actualLastSymbol)};
|
||||
// 15.5.2.6 -- dummy is ALLOCATABLE
|
||||
bool dummyIsAllocatable{
|
||||
dummy.attrs.test(characteristics::DummyDataObject::Attr::Allocatable)};
|
||||
bool actualIsAllocatable{
|
||||
actualLastSymbol && IsAllocatable(*actualLastSymbol)};
|
||||
if (dummyIsAllocatable) {
|
||||
if (!actualIsAllocatable) {
|
||||
messages.Say(
|
||||
"ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US,
|
||||
dummyName);
|
||||
}
|
||||
if (actualIsAllocatable && actualIsCoindexed &&
|
||||
dummy.intent != common::Intent::In) {
|
||||
messages.Say(
|
||||
"ALLOCATABLE %s must have INTENT(IN) to be associated with a coindexed actual argument"_err_en_US,
|
||||
dummyName);
|
||||
}
|
||||
if (!actualIsCoindexed && actualLastSymbol &&
|
||||
actualLastSymbol->Corank() != dummy.type.corank()) {
|
||||
messages.Say(
|
||||
"ALLOCATABLE %s has corank %d but actual argument has corank %d"_err_en_US,
|
||||
dummyName, dummy.type.corank(), actualLastSymbol->Corank());
|
||||
}
|
||||
}
|
||||
|
||||
// 15.5.2.5 -- actual & dummy are both POINTER or both ALLOCATABLE
|
||||
if ((actualIsPointer && dummyIsPointer) ||
|
||||
(actualIsAllocatable && dummyIsAllocatable)) {
|
||||
if (dummyIsPolymorphic != actualIsPolymorphic) {
|
||||
messages.Say(
|
||||
"If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both must be so"_err_en_US);
|
||||
}
|
||||
bool actualIsUnlimited{actualType.type().IsUnlimitedPolymorphic()};
|
||||
bool dummyIsUnlimited{dummy.type.type().IsUnlimitedPolymorphic()};
|
||||
if (!actualIsUnlimited) {
|
||||
if (dummyIsUnlimited) {
|
||||
if (actualIsUnlimited != dummyIsUnlimited) {
|
||||
if (typesCompatible) {
|
||||
messages.Say(
|
||||
"If a POINTER or ALLOCATABLE dummy or actual argument is unlimited polymorphic, both must be so"_err_en_US);
|
||||
} else if (typesCompatible) {
|
||||
if (!actualType.type().IsTypeCompatibleWith(dummy.type.type())) {
|
||||
}
|
||||
} else if (dummyIsPolymorphic != actualIsPolymorphic) {
|
||||
if (dummy.intent == common::Intent::In && typesCompatible) {
|
||||
// extension: allow with warning, rule is only relevant for definables
|
||||
messages.Say(
|
||||
"If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both should be so"_en_US);
|
||||
} else {
|
||||
messages.Say(
|
||||
"If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both must be so"_err_en_US);
|
||||
}
|
||||
} else if (!actualIsUnlimited && typesCompatible) {
|
||||
if (!actualType.type().IsTypeCompatibleWith(dummy.type.type())) {
|
||||
if (dummy.intent == common::Intent::In) {
|
||||
// extension: allow with warning, rule is only relevant for definables
|
||||
messages.Say(
|
||||
"POINTER or ALLOCATABLE dummy and actual arguments should have the same declared type"_en_US);
|
||||
} else {
|
||||
messages.Say(
|
||||
"POINTER or ALLOCATABLE dummy and actual arguments must have the same declared type"_err_en_US);
|
||||
}
|
||||
if (actualType.type().category() == TypeCategory::Derived &&
|
||||
!DefersSameTypeParameters(actualType.type().GetDerivedTypeSpec(),
|
||||
dummy.type.type().GetDerivedTypeSpec())) {
|
||||
messages.Say(
|
||||
"Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE"_err_en_US);
|
||||
}
|
||||
}
|
||||
if (actualType.type().category() == TypeCategory::Derived &&
|
||||
!DefersSameTypeParameters(actualType.type().GetDerivedTypeSpec(),
|
||||
dummy.type.type().GetDerivedTypeSpec())) {
|
||||
messages.Say(
|
||||
"Dummy and actual arguments must defer the same type parameters when POINTER or ALLOCATABLE"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,15 +31,15 @@ public:
|
|||
|
||||
void Check() { Check(context_.globalScope()); }
|
||||
void Check(const ParamValue &, bool canBeAssumed);
|
||||
void Check(Bound &bound) { CheckSpecExpr(bound.GetExplicit()); }
|
||||
void Check(ShapeSpec &spec) {
|
||||
void Check(const Bound &bound) { CheckSpecExpr(bound.GetExplicit()); }
|
||||
void Check(const ShapeSpec &spec) {
|
||||
Check(spec.lbound());
|
||||
Check(spec.ubound());
|
||||
}
|
||||
void Check(ArraySpec &);
|
||||
void Check(DeclTypeSpec &, bool canHaveAssumedTypeParameters);
|
||||
void Check(Symbol &);
|
||||
void Check(Scope &);
|
||||
void Check(const ArraySpec &);
|
||||
void Check(const DeclTypeSpec &, bool canHaveAssumedTypeParameters);
|
||||
void Check(const Symbol &);
|
||||
void Check(const Scope &);
|
||||
|
||||
private:
|
||||
template<typename A> void CheckSpecExpr(A &x) {
|
||||
|
@ -49,11 +49,16 @@ private:
|
|||
template<typename A> void CheckSpecExpr(const A &x) {
|
||||
evaluate::CheckSpecificationExpr(x, messages_, DEREF(scope_));
|
||||
}
|
||||
void CheckValue(const Symbol &, const DerivedTypeSpec *);
|
||||
void CheckVolatile(
|
||||
const Symbol &, bool isAssociated, const DerivedTypeSpec *);
|
||||
|
||||
SemanticsContext &context_;
|
||||
evaluate::FoldingContext &foldingContext_{context_.foldingContext()};
|
||||
parser::ContextualMessages &messages_{foldingContext_.messages()};
|
||||
const Scope *scope_{nullptr};
|
||||
bool inBindC_{false}; // scope is BIND(C)
|
||||
bool inPure_{false}; // scope is PURE
|
||||
};
|
||||
|
||||
void CheckHelper::Check(const ParamValue &value, bool canBeAssumed) {
|
||||
|
@ -67,13 +72,14 @@ void CheckHelper::Check(const ParamValue &value, bool canBeAssumed) {
|
|||
}
|
||||
}
|
||||
|
||||
void CheckHelper::Check(ArraySpec &shape) {
|
||||
for (auto &spec : shape) {
|
||||
void CheckHelper::Check(const ArraySpec &shape) {
|
||||
for (const auto &spec : shape) {
|
||||
Check(spec);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckHelper::Check(DeclTypeSpec &type, bool canHaveAssumedTypeParameters) {
|
||||
void CheckHelper::Check(
|
||||
const DeclTypeSpec &type, bool canHaveAssumedTypeParameters) {
|
||||
if (type.category() == DeclTypeSpec::Character) {
|
||||
Check(type.characterTypeSpec().length(), canHaveAssumedTypeParameters);
|
||||
} else if (const DerivedTypeSpec * spec{type.AsDerived()}) {
|
||||
|
@ -83,14 +89,25 @@ void CheckHelper::Check(DeclTypeSpec &type, bool canHaveAssumedTypeParameters) {
|
|||
}
|
||||
}
|
||||
|
||||
void CheckHelper::Check(Symbol &symbol) {
|
||||
if (context_.HasError(symbol) || symbol.has<UseDetails>() ||
|
||||
symbol.has<HostAssocDetails>()) {
|
||||
void CheckHelper::Check(const Symbol &symbol) {
|
||||
if (context_.HasError(symbol)) {
|
||||
return;
|
||||
}
|
||||
const DeclTypeSpec *type{symbol.GetUltimate().GetType()};
|
||||
const DerivedTypeSpec *derived{nullptr};
|
||||
if (type != nullptr) {
|
||||
derived = type->AsDerived();
|
||||
}
|
||||
auto save{messages_.SetLocation(symbol.name())};
|
||||
context_.set_location(symbol.name());
|
||||
if (DeclTypeSpec * type{symbol.GetType()}) {
|
||||
bool isAssociated{symbol.has<UseDetails>() || symbol.has<HostAssocDetails>()};
|
||||
if (symbol.attrs().test(Attr::VOLATILE)) {
|
||||
CheckVolatile(symbol, isAssociated, derived);
|
||||
}
|
||||
if (isAssociated) {
|
||||
return; // only care about checking VOLATILE on associated symbols
|
||||
}
|
||||
if (type != nullptr) {
|
||||
bool canHaveAssumedParameter{IsNamedConstant(symbol) ||
|
||||
IsAssumedLengthCharacterFunction(symbol) ||
|
||||
symbol.test(Symbol::Flag::ParentComp)};
|
||||
|
@ -130,6 +147,19 @@ void CheckHelper::Check(Symbol &symbol) {
|
|||
if (auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
|
||||
Check(object->shape());
|
||||
Check(object->coshape());
|
||||
if (!object->coshape().empty()) {
|
||||
if (IsAllocatable(symbol)) {
|
||||
if (!object->coshape().IsDeferredShape()) { // C827
|
||||
messages_.Say(
|
||||
"ALLOCATABLE coarray must have a deferred coshape"_err_en_US);
|
||||
}
|
||||
} else {
|
||||
if (!object->coshape().IsAssumedSize()) { // C828
|
||||
messages_.Say(
|
||||
"Non-ALLOCATABLE coarray must have an explicit coshape"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (object->isDummy() && symbol.attrs().test(Attr::INTENT_OUT)) {
|
||||
if (FindUltimateComponent(symbol, [](const Symbol &symbol) {
|
||||
return IsCoarray(symbol) && IsAllocatable(symbol);
|
||||
|
@ -143,14 +173,87 @@ void CheckHelper::Check(Symbol &symbol) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (symbol.attrs().test(Attr::VALUE)) {
|
||||
CheckValue(symbol, derived);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckHelper::Check(Scope &scope) {
|
||||
void CheckHelper::CheckValue(
|
||||
const Symbol &symbol, const DerivedTypeSpec *derived) { // C863 - C865
|
||||
if (!IsDummy(symbol)) {
|
||||
messages_.Say(
|
||||
"VALUE attribute may apply only to a dummy argument"_err_en_US);
|
||||
}
|
||||
if (IsProcedure(symbol)) {
|
||||
messages_.Say(
|
||||
"VALUE attribute may apply only to a dummy data object"_err_en_US);
|
||||
}
|
||||
if (IsAssumedSizeArray(symbol)) {
|
||||
messages_.Say(
|
||||
"VALUE attribute may not apply to an assumed-size array"_err_en_US);
|
||||
}
|
||||
if (IsCoarray(symbol)) {
|
||||
messages_.Say("VALUE attribute may not apply to a coarray"_err_en_US);
|
||||
}
|
||||
if (IsAllocatable(symbol)) {
|
||||
messages_.Say("VALUE attribute may not apply to an ALLOCATABLE"_err_en_US);
|
||||
} else if (IsPointer(symbol)) {
|
||||
messages_.Say("VALUE attribute may not apply to a POINTER"_err_en_US);
|
||||
}
|
||||
if (IsIntentInOut(symbol)) {
|
||||
messages_.Say(
|
||||
"VALUE attribute may not apply to an INTENT(IN OUT) argument"_err_en_US);
|
||||
} else if (IsIntentOut(symbol)) {
|
||||
messages_.Say(
|
||||
"VALUE attribute may not apply to an INTENT(OUT) argument"_err_en_US);
|
||||
}
|
||||
if (symbol.attrs().test(Attr::VOLATILE)) {
|
||||
messages_.Say("VALUE attribute may not apply to a VOLATILE"_err_en_US);
|
||||
}
|
||||
if (inBindC_ && IsOptional(symbol)) {
|
||||
messages_.Say(
|
||||
"VALUE attribute may not apply to an OPTIONAL in a BIND(C) procedure"_err_en_US);
|
||||
}
|
||||
if (derived != nullptr) {
|
||||
if (FindCoarrayUltimateComponent(*derived)) {
|
||||
messages_.Say(
|
||||
"VALUE attribute may not apply to a type with a coarray ultimate component"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckHelper::CheckVolatile(const Symbol &symbol, bool isAssociated,
|
||||
const DerivedTypeSpec *derived) { // C866 - C868
|
||||
if (IsIntentIn(symbol)) {
|
||||
messages_.Say(
|
||||
"VOLATILE attribute may not apply to an INTENT(IN) argument"_err_en_US);
|
||||
}
|
||||
if (IsProcedure(symbol)) {
|
||||
messages_.Say("VOLATILE attribute may apply only to a variable"_err_en_US);
|
||||
}
|
||||
if (isAssociated) {
|
||||
const Symbol &ultimate{symbol.GetUltimate()};
|
||||
if (IsCoarray(ultimate)) {
|
||||
messages_.Say(
|
||||
"VOLATILE attribute may not apply to a coarray accessed by USE or host association"_err_en_US);
|
||||
}
|
||||
if (derived != nullptr) {
|
||||
if (FindCoarrayUltimateComponent(*derived)) {
|
||||
messages_.Say(
|
||||
"VOLATILE attribute may not apply to a type with a coarray ultimate component accessed by USE or host association"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckHelper::Check(const Scope &scope) {
|
||||
scope_ = &scope;
|
||||
for (auto &pair : scope) {
|
||||
inBindC_ = IsBindCProcedure(scope);
|
||||
inPure_ = IsPureProcedure(scope);
|
||||
for (const auto &pair : scope) {
|
||||
Check(*pair.second);
|
||||
}
|
||||
for (Scope &child : scope.children()) {
|
||||
for (const Scope &child : scope.children()) {
|
||||
Check(child);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3137,8 +3137,10 @@ Symbol &DeclarationVisitor::HandleAttributeStmt(
|
|||
}
|
||||
auto *symbol{FindInScope(currScope(), name)};
|
||||
if (attr == Attr::ASYNCHRONOUS || attr == Attr::VOLATILE) {
|
||||
// these can be set on a symbol that is host-assoc into block or use-assoc
|
||||
if (!symbol && currScope().kind() == Scope::Kind::Block) {
|
||||
// these can be set on a symbol that is host-assoc or use-assoc
|
||||
if (!symbol &&
|
||||
(currScope().kind() == Scope::Kind::Subprogram ||
|
||||
currScope().kind() == Scope::Kind::Block)) {
|
||||
if (auto *hostSymbol{FindSymbol(name)}) {
|
||||
name.symbol = nullptr;
|
||||
symbol = &MakeSymbol(name, HostAssocDetails{*hostSymbol});
|
||||
|
|
|
@ -184,6 +184,24 @@ bool IsPureProcedure(const Scope &scope) {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsBindCProcedure(const Symbol &symbol) {
|
||||
if (const auto *procDetails{symbol.detailsIf<ProcEntityDetails>()}) {
|
||||
if (const Symbol * procInterface{procDetails->interface().symbol()}) {
|
||||
// procedure component with a BIND(C) interface
|
||||
return IsBindCProcedure(*procInterface);
|
||||
}
|
||||
}
|
||||
return symbol.attrs().test(Attr::BIND_C) && IsProcedure(symbol);
|
||||
}
|
||||
|
||||
bool IsBindCProcedure(const Scope &scope) {
|
||||
if (const Symbol * symbol{scope.GetSymbol()}) {
|
||||
return IsBindCProcedure(*symbol);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsProcedure(const Symbol &symbol) {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
|
|
|
@ -54,13 +54,15 @@ bool IsGenericDefinedOp(const Symbol &);
|
|||
bool IsCommonBlockContaining(const Symbol &block, const Symbol &object);
|
||||
bool DoesScopeContain(const Scope *maybeAncestor, const Scope &maybeDescendent);
|
||||
bool DoesScopeContain(const Scope *, const Symbol &);
|
||||
bool IsUseAssociated(const Symbol *, const Scope &);
|
||||
bool IsUseAssociated(const Symbol &, const Scope &);
|
||||
bool IsHostAssociated(const Symbol &, const Scope &);
|
||||
bool IsDummy(const Symbol &);
|
||||
bool IsPointerDummy(const Symbol &);
|
||||
bool IsFunction(const Symbol &);
|
||||
bool IsPureProcedure(const Symbol &);
|
||||
bool IsPureProcedure(const Scope &);
|
||||
bool IsBindCProcedure(const Symbol &);
|
||||
bool IsBindCProcedure(const Scope &);
|
||||
bool IsProcedure(const Symbol &);
|
||||
bool IsProcName(const Symbol &symbol); // proc-name
|
||||
bool IsVariableName(const Symbol &symbol); // variable-name
|
||||
|
@ -111,6 +113,12 @@ inline bool IsOptional(const Symbol &symbol) {
|
|||
inline bool IsIntentIn(const Symbol &symbol) {
|
||||
return symbol.attrs().test(Attr::INTENT_IN);
|
||||
}
|
||||
inline bool IsIntentInOut(const Symbol &symbol) {
|
||||
return symbol.attrs().test(Attr::INTENT_INOUT);
|
||||
}
|
||||
inline bool IsIntentOut(const Symbol &symbol) {
|
||||
return symbol.attrs().test(Attr::INTENT_OUT);
|
||||
}
|
||||
inline bool IsProtected(const Symbol &symbol) {
|
||||
return symbol.attrs().test(Attr::PROTECTED);
|
||||
}
|
||||
|
|
|
@ -177,7 +177,10 @@ set(ERROR_TESTS
|
|||
call03.f90
|
||||
call04.f90
|
||||
call05.f90
|
||||
call06.f90
|
||||
call13.f90
|
||||
call14.f90
|
||||
misc-declarations.f90
|
||||
)
|
||||
|
||||
# These test files have expected symbols in the source
|
||||
|
|
|
@ -50,7 +50,7 @@ subroutine s4_c1107
|
|||
end block
|
||||
end
|
||||
|
||||
subroutine s5_c1107
|
||||
subroutine s5_c1107(x,y)
|
||||
integer x, y
|
||||
value x
|
||||
block
|
||||
|
|
|
@ -33,7 +33,7 @@ module m01
|
|||
real, allocatable :: a(:)
|
||||
end type
|
||||
type :: ultimateCoarray
|
||||
real, allocatable :: a[*]
|
||||
real, allocatable :: a[:]
|
||||
end type
|
||||
|
||||
contains
|
||||
|
@ -85,7 +85,7 @@ module m01
|
|||
real, pointer :: x(:)
|
||||
end subroutine
|
||||
subroutine valueassumedsize(x)
|
||||
real, value :: x(*)
|
||||
real, intent(in) :: x(*)
|
||||
end subroutine
|
||||
subroutine volatileassumedsize(x)
|
||||
real, volatile :: x(*)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
module m
|
||||
|
||||
type :: hasCoarray
|
||||
real, allocatable :: a(:)[*]
|
||||
real, allocatable :: a(:)[:]
|
||||
end type
|
||||
type, extends(hasCoarray) :: extendsHasCoarray
|
||||
end type
|
||||
|
@ -36,6 +36,7 @@ module m
|
|||
end subroutine
|
||||
subroutine s01b ! C846 - can only be caught at a call via explicit interface
|
||||
!ERROR: ALLOCATABLE coarray 'coarray' may not be associated with INTENT(OUT) dummy argument 'x='
|
||||
!ERROR: ALLOCATABLE dummy argument 'x=' has corank 0 but actual argument has corank 1
|
||||
call s01a(coarray)
|
||||
end subroutine
|
||||
|
||||
|
|
|
@ -46,24 +46,24 @@ module m
|
|||
subroutine test(x)
|
||||
real :: scalar
|
||||
real, allocatable, intent(in) :: x
|
||||
!ERROR: ALLOCATABLE dummy argument must be associated with an ALLOCATABLE effective argument
|
||||
!ERROR: ALLOCATABLE dummy argument 'x=' must be associated with an ALLOCATABLE actual argument
|
||||
call s01(scalar)
|
||||
!ERROR: ALLOCATABLE dummy argument must be associated with an ALLOCATABLE effective argument
|
||||
!ERROR: ALLOCATABLE dummy argument 'x=' must be associated with an ALLOCATABLE actual argument
|
||||
call s01(1.)
|
||||
!ERROR: ALLOCATABLE dummy argument must be associated with an ALLOCATABLE effective argument
|
||||
!ERROR: ALLOCATABLE dummy argument 'x=' must be associated with an ALLOCATABLE actual argument
|
||||
call s01(allofunc()) ! subtle: ALLOCATABLE function result isn't
|
||||
call s02(cov) ! ok
|
||||
call s03(com) ! ok
|
||||
!ERROR: Dummy argument has corank 1, but effective argument has corank 2
|
||||
!ERROR: ALLOCATABLE dummy argument 'x=' has corank 1 but actual argument has corank 2
|
||||
call s02(com)
|
||||
!ERROR: Dummy argument has corank 2, but effective argument has corank 1
|
||||
!ERROR: ALLOCATABLE dummy argument 'x=' has corank 2 but actual argument has corank 1
|
||||
call s03(cov)
|
||||
call s04(cov[1]) ! ok
|
||||
!ERROR: Coindexed ALLOCATABLE effective argument must be associated with INTENT(IN) dummy argument
|
||||
!ERROR: ALLOCATABLE dummy argument 'x=' must have INTENT(IN) to be associated with a coindexed actual argument
|
||||
call s01(cov[1])
|
||||
!ERROR: Effective argument associated with INTENT(OUT) dummy is not definable
|
||||
!ERROR: Actual argument associated with INTENT(OUT) dummy argument 'x=' must be definable
|
||||
call s05(x)
|
||||
!ERROR: Effective argument associated with INTENT(IN OUT) dummy is not definable
|
||||
!ERROR: Actual argument associated with INTENT(IN OUT) dummy argument 'x=' must be definable
|
||||
call s06(x)
|
||||
end subroutine
|
||||
end module
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
! Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
!
|
||||
! Licensed under the Apache License, Version 2.0 (the "License");
|
||||
! you may not use this file except in compliance with the License.
|
||||
! You may obtain a copy of the License at
|
||||
!
|
||||
! http://www.apache.org/licenses/LICENSE-2.0
|
||||
!
|
||||
! Unless required by applicable law or agreed to in writing, software
|
||||
! distributed under the License is distributed on an "AS IS" BASIS,
|
||||
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
! See the License for the specific language governing permissions and
|
||||
! limitations under the License.
|
||||
|
||||
! Test 8.5.18 constraints on the VALUE attribute
|
||||
|
||||
module m
|
||||
type :: hasCoarray
|
||||
real :: coarray[*]
|
||||
end type
|
||||
contains
|
||||
!ERROR: VALUE attribute may apply only to a dummy data object
|
||||
subroutine C863(notData,assumedSize,coarray,coarrayComponent)
|
||||
external :: notData
|
||||
!ERROR: VALUE attribute may apply only to a dummy argument
|
||||
real, value :: notADummy
|
||||
value :: notData
|
||||
!ERROR: VALUE attribute may not apply to an assumed-size array
|
||||
real, value :: assumedSize(10,*)
|
||||
!ERROR: VALUE attribute may not apply to a coarray
|
||||
real, value :: coarray[*]
|
||||
!ERROR: VALUE attribute may not apply to a type with a coarray ultimate component
|
||||
type(hasCoarray), value :: coarrayComponent
|
||||
end subroutine
|
||||
subroutine C864(allocatable, inout, out, pointer, volatile)
|
||||
!ERROR: VALUE attribute may not apply to an ALLOCATABLE
|
||||
real, value, allocatable :: allocatable
|
||||
!ERROR: VALUE attribute may not apply to an INTENT(IN OUT) argument
|
||||
real, value, intent(in out) :: inout
|
||||
!ERROR: VALUE attribute may not apply to an INTENT(OUT) argument
|
||||
real, value, intent(out) :: out
|
||||
!ERROR: VALUE attribute may not apply to a POINTER
|
||||
real, value, pointer :: pointer
|
||||
!ERROR: VALUE attribute may not apply to a VOLATILE
|
||||
real, value, volatile :: volatile
|
||||
end subroutine
|
||||
subroutine C865(optional) bind(c)
|
||||
!ERROR: VALUE attribute may not apply to an OPTIONAL in a BIND(C) procedure
|
||||
real, value, optional :: optional
|
||||
end subroutine
|
||||
end module
|
|
@ -123,7 +123,7 @@ end subroutine s5
|
|||
subroutine s6()
|
||||
type :: type0
|
||||
integer, allocatable, dimension(:) :: type0_field
|
||||
integer, allocatable, dimension(:), codimension[*] :: coarray_type0_field
|
||||
integer, allocatable, dimension(:), codimension[:] :: coarray_type0_field
|
||||
end type
|
||||
|
||||
type :: type1
|
||||
|
@ -134,7 +134,7 @@ subroutine s6()
|
|||
type(type1) :: qvar;
|
||||
integer, allocatable, dimension(:) :: array1
|
||||
integer, allocatable, dimension(:) :: array2
|
||||
integer, allocatable, codimension[*] :: ca, cb
|
||||
integer, allocatable, codimension[:] :: ca, cb
|
||||
integer, allocatable :: aa, ab
|
||||
|
||||
! All of the following are allowable outside a DO CONCURRENT
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
subroutine test(j)
|
||||
integer, intent(in) :: j
|
||||
real, allocatable, target, save :: x1
|
||||
real, codimension[:], target, save :: x2
|
||||
real, codimension[*], target, save :: x2
|
||||
real, save :: x3
|
||||
real, target :: x4
|
||||
real, target, save :: x5(10)
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
! Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
!
|
||||
! Licensed under the Apache License, Version 2.0 (the "License");
|
||||
! you may not use this file except in compliance with the License.
|
||||
! You may obtain a copy of the License at
|
||||
!
|
||||
! http://www.apache.org/licenses/LICENSE-2.0
|
||||
!
|
||||
! Unless required by applicable law or agreed to in writing, software
|
||||
! distributed under the License is distributed on an "AS IS" BASIS,
|
||||
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
! See the License for the specific language governing permissions and
|
||||
! limitations under the License.
|
||||
|
||||
! Miscellaneous constraint and requirement checking on declarations:
|
||||
! - 8.5.6.2 & 8.5.6.3 constraints on coarrays
|
||||
! - 8.5.19 constraints on the VOLATILE attribute
|
||||
|
||||
module m
|
||||
!ERROR: ALLOCATABLE coarray must have a deferred coshape
|
||||
real, allocatable :: mustBeDeferred[*] ! C827
|
||||
!ERROR: Non-ALLOCATABLE coarray must have an explicit coshape
|
||||
real :: mustBeExplicit[:] ! C828
|
||||
type :: hasCoarray
|
||||
real :: coarray[*]
|
||||
end type
|
||||
real :: coarray[*]
|
||||
type(hasCoarray) :: coarrayComponent
|
||||
contains
|
||||
!ERROR: VOLATILE attribute may not apply to an INTENT(IN) argument
|
||||
subroutine C866(x)
|
||||
intent(in) :: x
|
||||
volatile :: x
|
||||
!ERROR: VOLATILE attribute may apply only to a variable
|
||||
volatile :: notData
|
||||
external :: notData
|
||||
end subroutine
|
||||
subroutine C867
|
||||
!ERROR: VOLATILE attribute may not apply to a coarray accessed by USE or host association
|
||||
volatile :: coarray
|
||||
!ERROR: VOLATILE attribute may not apply to a type with a coarray ultimate component accessed by USE or host association
|
||||
volatile :: coarrayComponent
|
||||
end subroutine
|
||||
subroutine C868(coarray,coarrayComponent)
|
||||
real, volatile :: coarray[*]
|
||||
type(hasCoarray) :: coarrayComponent
|
||||
block
|
||||
!ERROR: VOLATILE attribute may not apply to a coarray accessed by USE or host association
|
||||
volatile :: coarray
|
||||
!ERROR: VOLATILE attribute may not apply to a type with a coarray ultimate component accessed by USE or host association
|
||||
volatile :: coarrayComponent
|
||||
end block
|
||||
end subroutine
|
||||
end module
|
|
@ -49,8 +49,8 @@ end
|
|||
! coarray-spec in components and with non-constants bounds
|
||||
module m3
|
||||
type t
|
||||
real, allocatable :: c(:)[1:10,1:*]
|
||||
complex, allocatable, codimension[5,*] :: d
|
||||
real :: c[1:10,1:*]
|
||||
complex, codimension[5,*] :: d
|
||||
end type
|
||||
real, allocatable :: e[:,:,:]
|
||||
contains
|
||||
|
@ -63,8 +63,8 @@ end
|
|||
!Expect: m3.mod
|
||||
!module m3
|
||||
! type::t
|
||||
! real(4),allocatable::c(:)[1_8:10_8,1_8:*]
|
||||
! complex(4),allocatable::d[1_8:5_8,1_8:*]
|
||||
! real(4)::c[1_8:10_8,1_8:*]
|
||||
! complex(4)::d[1_8:5_8,1_8:*]
|
||||
! end type
|
||||
! real(4),allocatable::e[:,:,:]
|
||||
!contains
|
||||
|
|
Loading…
Reference in New Issue