@@ -683,20 +683,10 @@ void CheckHelper::CheckObjectEntity(
683683 const DeclTypeSpec *type{details.type ()};
684684 const DerivedTypeSpec *derived{type ? type->AsDerived () : nullptr };
685685 bool isComponent{symbol.owner ().IsDerivedType ()};
686- if (details.coshape ().empty ()) { // not a coarray
687- if (!isComponent && !IsPointer (symbol) && derived) {
688- if (IsEventTypeOrLockType (derived)) {
689- messages_.Say (
690- " Variable '%s' with EVENT_TYPE or LOCK_TYPE must be a coarray" _err_en_US,
691- symbol.name ());
692- } else if (auto component{FindEventOrLockPotentialComponent (
693- *derived, /* ignoreCoarrays=*/ true )}) {
694- messages_.Say (
695- " Variable '%s' with EVENT_TYPE or LOCK_TYPE potential component '%s' must be a coarray" _err_en_US,
696- symbol.name (), component.BuildResultDesignatorName ());
697- }
698- }
699- } else { // it's a coarray
686+ const Symbol *commonBlock{FindCommonBlockContaining (symbol)};
687+ bool isLocalVariable{!commonBlock && !isComponent && !details.isDummy () &&
688+ symbol.owner ().kind () != Scope::Kind::OtherConstruct};
689+ if (int corank{evaluate::GetCorank (symbol)}; corank > 0 ) { // it's a coarray
700690 bool isDeferredCoshape{details.coshape ().CanBeDeferredShape ()};
701691 if (IsAllocatable (symbol)) {
702692 if (!isDeferredCoshape) { // C827
@@ -726,6 +716,46 @@ void CheckHelper::CheckObjectEntity(
726716 messages_.Say (" Coarray '%s' may not be an assumed-rank array" _err_en_US,
727717 symbol.name ());
728718 }
719+ if (IsNamedConstant (symbol)) {
720+ messages_.Say (
721+ " Coarray '%s' may not be a named constant" _err_en_US, symbol.name ());
722+ }
723+ if (IsFunctionResult (symbol)) {
724+ messages_.Say (" Function result may not be a coarray" _err_en_US);
725+ } else if (commonBlock) {
726+ messages_.Say (" Coarray '%s' may not be in COMMON block '/%s/'" _err_en_US,
727+ symbol.name (), commonBlock->name ());
728+ } else if (isLocalVariable && !IsAllocatableOrPointer (symbol) &&
729+ !IsSaved (symbol)) {
730+ messages_.Say (" Local coarray must have the SAVE attribute" _err_en_US);
731+ }
732+ for (int j{0 }; j < corank; ++j) {
733+ if (auto lcbv{evaluate::ToInt64 (evaluate::Fold (
734+ context ().foldingContext (), evaluate::GetLCOBOUND (symbol, j)))}) {
735+ if (auto ucbv{
736+ evaluate::ToInt64 (evaluate::Fold (context ().foldingContext (),
737+ evaluate::GetUCOBOUND (symbol, j)))}) {
738+ if (ucbv < lcbv) {
739+ messages_.Say (
740+ " Cobounds %jd:%jd of codimension %d produce an empty coarray" _err_en_US,
741+ std::intmax_t {*lcbv}, std::intmax_t {*ucbv}, j + 1 );
742+ }
743+ }
744+ }
745+ }
746+ } else { // not a coarray
747+ if (!isComponent && !IsPointer (symbol) && derived) {
748+ if (IsEventTypeOrLockType (derived)) {
749+ messages_.Say (
750+ " Variable '%s' with EVENT_TYPE or LOCK_TYPE must be a coarray" _err_en_US,
751+ symbol.name ());
752+ } else if (auto component{FindEventOrLockPotentialComponent (
753+ *derived, /* ignoreCoarrays=*/ true )}) {
754+ messages_.Say (
755+ " Variable '%s' with EVENT_TYPE or LOCK_TYPE potential component '%s' must be a coarray" _err_en_US,
756+ symbol.name (), component.BuildResultDesignatorName ());
757+ }
758+ }
729759 }
730760 if (details.isDummy ()) {
731761 if (IsIntentOut (symbol)) {
@@ -926,6 +956,42 @@ void CheckHelper::CheckObjectEntity(
926956 symbol.name ());
927957 }
928958
959+ if (derived) {
960+ bool isUnsavedLocal{
961+ isLocalVariable && !IsAllocatable (symbol) && !IsSaved (symbol)};
962+ if (IsFunctionResult (symbol) || IsPointer (symbol) ||
963+ evaluate::IsCoarray (symbol) || isUnsavedLocal) {
964+ if (auto badPotential{FindCoarrayPotentialComponent (*derived)}) {
965+ if (IsFunctionResult (symbol)) { // F'2023 C825
966+ SayWithDeclaration (*badPotential,
967+ " Function result '%s' may not have a coarray potential component '%s'" _err_en_US,
968+ symbol.name (), badPotential.BuildResultDesignatorName ());
969+ } else if (IsPointer (symbol)) { // F'2023 C825
970+ SayWithDeclaration (*badPotential,
971+ " Pointer '%s' may not have a coarray potential component '%s'" _err_en_US,
972+ symbol.name (), badPotential.BuildResultDesignatorName ());
973+ } else if (evaluate::IsCoarray (symbol)) { // F'2023 C825
974+ SayWithDeclaration (*badPotential,
975+ " Coarray '%s' may not have a coarray potential component '%s'" _err_en_US,
976+ symbol.name (), badPotential.BuildResultDesignatorName ());
977+ } else if (isUnsavedLocal) { // F'2023 C826
978+ SayWithDeclaration (*badPotential,
979+ " Local variable '%s' without the SAVE attribute may not have a coarray potential subobject component '%s'" _err_en_US,
980+ symbol.name (), badPotential.BuildResultDesignatorName ());
981+ } else {
982+ DIE (" caught unexpected bad coarray potential component" );
983+ }
984+ }
985+ } else if (isComponent && (IsAllocatable (symbol) || symbol.Rank () > 0 )) {
986+ if (auto badUltimate{FindCoarrayUltimateComponent (*derived)}) {
987+ // TODO: still an error in F'2023?
988+ SayWithDeclaration (*badUltimate,
989+ " Allocatable or array component '%s' may not have a coarray ultimate component '%s'" _err_en_US,
990+ symbol.name (), badUltimate.BuildResultDesignatorName ());
991+ }
992+ }
993+ }
994+
929995 // Check CUDA attributes and special circumstances of being in device
930996 // subprograms
931997 const Scope &progUnit{GetProgramUnitContaining (symbol)};
@@ -3161,10 +3227,6 @@ parser::Messages CheckHelper::WhyNotInteroperableFunctionResult(
31613227 msgs.Say (symbol.name (),
31623228 " Interoperable function result must be scalar" _err_en_US);
31633229 }
3164- if (symbol.Corank ()) {
3165- msgs.Say (symbol.name (),
3166- " Interoperable function result may not be a coarray" _err_en_US);
3167- }
31683230 return msgs;
31693231}
31703232
0 commit comments