diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp index 72e021d03a969..fe9b2fd222827 100644 --- a/flang/lib/Semantics/check-data.cpp +++ b/flang/lib/Semantics/check-data.cpp @@ -58,21 +58,24 @@ class DataVarChecker : public evaluate::AllTraverse { const Scope &scope{context_.FindScope(source_)}; bool isFirstSymbol{isFirstSymbol_}; isFirstSymbol_ = false; - if (const char *whyNot{IsAutomatic(symbol) ? "Automatic variable" - : IsDummy(symbol) ? "Dummy argument" - : IsFunctionResult(symbol) ? "Function result" - : IsAllocatable(symbol) ? "Allocatable" + // Ordered so that most egregious errors are first + if (const char *whyNot{IsProcedure(symbol) && !IsPointer(symbol) + ? "Procedure" + : isFirstSymbol && IsHostAssociated(symbol, scope) + ? "Host-associated object" + : isFirstSymbol && IsUseAssociated(symbol, scope) + ? "USE-associated object" + : IsDummy(symbol) ? "Dummy argument" + : IsFunctionResult(symbol) ? "Function result" + : IsAutomatic(symbol) ? "Automatic variable" + : IsAllocatable(symbol) ? "Allocatable" : IsInitialized(symbol, true /*ignore DATA*/, true /*ignore allocatable components*/, true /*ignore uninitialized pointer components*/) ? "Default-initialized" - : IsProcedure(symbol) && !IsPointer(symbol) ? "Procedure" - // remaining checks don't apply to components - : !isFirstSymbol ? nullptr - : IsHostAssociated(symbol, scope) ? "Host-associated object" - : IsUseAssociated(symbol, scope) ? "USE-associated object" : symbol.has() ? "Construct association" - : IsPointer(symbol) && (hasComponent_ || hasSubscript_) + : isFirstSymbol && IsPointer(symbol) && + (hasComponent_ || hasSubscript_) ? "Target of pointer" : nullptr}) { context_.Say(source_, diff --git a/flang/test/Semantics/data18.f90 b/flang/test/Semantics/data18.f90 new file mode 100644 index 0000000000000..e278c537cd8b5 --- /dev/null +++ b/flang/test/Semantics/data18.f90 @@ -0,0 +1,59 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Test error message priorities for DATA problems +module m + integer useAlloc + allocatable useAlloc + integer, pointer :: usePtr(:) + contains + subroutine useProc + end +end +function f(hostDummy, hostProc) result(hostResult) + integer hostDummy, hostResult + external hostProc + integer hostAuto(hostDummy) + integer, allocatable :: hostAlloc + integer :: hostInit = 1 + integer, pointer :: hostPtr(:) + contains + subroutine test(innerDummy, innerProc) + use m + external innerProc + integer innerAuto(innerDummy) + integer, allocatable :: innerAlloc + integer :: innerInit = 1 + integer, pointer :: innerPtr(:) + !ERROR: Procedure 'useproc' must not be initialized in a DATA statement + data useProc/0/ + !ERROR: Procedure 'hostproc' must not be initialized in a DATA statement + data hostProc/0/ + !ERROR: Procedure 'innerproc' must not be initialized in a DATA statement + data innerProc/0/ + !ERROR: Host-associated object 'hostdummy' must not be initialized in a DATA statement + data hostDummy/1/ + !ERROR: Host-associated object 'hostresult' must not be initialized in a DATA statement + data hostResult/1/ + !ERROR: Host-associated object 'hostauto' must not be initialized in a DATA statement + data hostAuto/1/ + !ERROR: Host-associated object 'hostalloc' must not be initialized in a DATA statement + data hostAlloc/1/ + !ERROR: Host-associated object 'hostinit' must not be initialized in a DATA statement + data hostInit/1/ + !ERROR: Host-associated object 'hostptr' must not be initialized in a DATA statement + data hostPtr(1)/1/ + !ERROR: USE-associated object 'usealloc' must not be initialized in a DATA statement + data useAlloc/1/ + !ERROR: USE-associated object 'useptr' must not be initialized in a DATA statement + data usePtr(1)/1/ + !ERROR: Dummy argument 'innerdummy' must not be initialized in a DATA statement + data innerDummy/1/ + !ERROR: Automatic variable 'innerauto' must not be initialized in a DATA statement + data innerAuto/1/ + !ERROR: Allocatable 'inneralloc' must not be initialized in a DATA statement + data innerAlloc/1/ + !ERROR: Default-initialized 'innerinit' must not be initialized in a DATA statement + data innerInit/1/ + !ERROR: Target of pointer 'innerptr' must not be initialized in a DATA statement + data innerptr(1)/1/ + end +end