From fb3894ce5dbbd2944e3d7a7f48c7cfa1060cba93 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Mon, 11 Sep 2023 16:48:44 -0700 Subject: [PATCH] [flang] Prioritize DATA object error messages a little better When a DATA statement object is not valid, there's a number of possible reasons. Emit an error message for the most egregious violation, so that an unlucky user doesn't fix something easy (due to a less-severe error message masking one that is worse) and then run into something that might be more serious. Pull request: https://github.com/llvm/llvm-project/pull/66258 --- flang/lib/Semantics/check-data.cpp | 23 +++++++----- flang/test/Semantics/data18.f90 | 59 ++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 flang/test/Semantics/data18.f90 diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp index 6916870907a63..750f0bd810a69 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