[flang-commits] [flang] 3196161 - [flang] To issue error message for unsupported usage of vector type. (#215248)
via flang-commits
flang-commits at lists.llvm.org
Sat Aug 15 08:20:27 PDT 2026
Author: Daniel Chen
Date: 2026-08-15T11:20:22-04:00
New Revision: 3196161be84becc68c891517a707daf6739a2dd3
URL: https://github.com/llvm/llvm-project/commit/3196161be84becc68c891517a707daf6739a2dd3
DIFF: https://github.com/llvm/llvm-project/commit/3196161be84becc68c891517a707daf6739a2dd3.diff
LOG: [flang] To issue error message for unsupported usage of vector type. (#215248)
As discussed in PR #214219, we don't plan to support any usage that
requires runtime descriptor for vector type object.
Flang has already disallowed ALLOCATABLE, POINTER, ASSUMED-SHAPE and
ASSUMED-RANK for vector types.
The test reducer posted by @eugeneepshteyn should also be flagged by the
compiler as an error.
This PR is to add semantic check for that case. It covers
1. Vector type declaration statement that has ALLOCATABLE or POINTER
attribute.
2. ALLOCATE statement where SOURCE= or MOLD= has a vector type object.
3. Auto-allocation intrinsic assignment where the RHS is a vector type
object.
4. A vector type object being used as an argument of SAME_TYPE_AS or
EXTENDs_TYPE_OF.
5. A vector type object being used as the `dtv` argument of a UDIO.
6. A vector type object being used as the argument of `CLASSOF`.
Added:
Modified:
flang/lib/Evaluate/tools.cpp
flang/lib/Semantics/check-allocate.cpp
flang/lib/Semantics/check-declarations.cpp
flang/lib/Semantics/expression.cpp
flang/test/Semantics/PowerPC/ppc-vector-diagnostics.f90
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 589aab5132a65..5eceb4562c4ba 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -2767,7 +2767,8 @@ bool IsLenTypeParameter(const Symbol &symbol) {
}
bool IsExtensibleType(const DerivedTypeSpec *derived) {
- return !IsSequenceOrBindCType(derived) && !IsIsoCType(derived);
+ return !IsSequenceOrBindCType(derived) && !IsIsoCType(derived) &&
+ !(derived && derived->IsVectorType());
}
bool IsSequenceOrBindCType(const DerivedTypeSpec *derived) {
diff --git a/flang/lib/Semantics/check-allocate.cpp b/flang/lib/Semantics/check-allocate.cpp
index 7f099d51221c0..2ac242abd5788 100644
--- a/flang/lib/Semantics/check-allocate.cpp
+++ b/flang/lib/Semantics/check-allocate.cpp
@@ -238,6 +238,12 @@ static std::optional<AllocateCheckerInfo> CheckAllocateOptions(
info.sourceExprLoc = parserSourceExpr->source;
if (const DerivedTypeSpec *
derived{evaluate::GetDerivedTypeSpec(info.sourceExprType)}) {
+ if (derived->IsVectorType()) {
+ context.Say(at,
+ "SOURCE or MOLD expression must not be a vector type '%s'"_err_en_US,
+ info.sourceExprType.value().AsFortran());
+ return std::nullopt;
+ }
// C949
if (auto it{FindCoarrayUltimateComponent(*derived)}) {
context
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index a4cb1c4e9f90c..07c6b88f0562a 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -1323,6 +1323,12 @@ void CheckHelper::CheckObjectEntity(
SayWithDeclaration(symbol,
"Assumed rank entity of %s type is not supported"_err_en_US,
typeName);
+ } else if (IsPointer(symbol)) {
+ SayWithDeclaration(
+ symbol, "Pointer to %s type is not supported"_err_en_US, typeName);
+ } else if (IsAllocatable(symbol)) {
+ SayWithDeclaration(symbol,
+ "Allocatable entity of %s type is not supported"_err_en_US, typeName);
}
}
}
@@ -3679,6 +3685,12 @@ void CheckHelper::CheckDioDummyIsDerived(const Symbol &proc, const Symbol &arg,
common::DefinedIo ioKind, const Symbol &generic) {
if (const DeclTypeSpec *type{arg.GetType()}) {
if (const DerivedTypeSpec *derivedType{type->AsDerived()}) {
+ if (derivedType->IsVectorType()) {
+ messages_.Say(arg.name(),
+ "Dummy argument '%s' of a defined input/output procedure must not be a vector type"_err_en_US,
+ arg.name());
+ return;
+ }
CheckAlreadySeenDefinedIo(*derivedType, ioKind, proc, generic);
bool isPolymorphic{type->IsPolymorphic()};
if (isPolymorphic != IsExtensibleType(derivedType)) {
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 766198c87945b..633c778915a76 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3852,6 +3852,16 @@ const Assignment *ExpressionAnalyzer::Analyze(const parser::AssignmentStmt &x) {
Warn(common::UsageWarning::IgnoredNoReallocateLHS,
"-fno-realloc-lhs is ignored for assignment to polymorphic allocatable"_warn_en_US);
}
+ const Expr<SomeType> &rhs{analyzer.GetExpr(1)};
+ if (auto rhsType{rhs.GetType()}) {
+ if (const auto *rhsDerived{GetDerivedTypeSpec(*rhsType)}) {
+ if (rhsDerived->IsVectorType()) {
+ Say(rhsExpr.source,
+ "Vector type '%s' may not be used as the right-hand side of a polymorphic intrinsic assignment"_err_en_US,
+ rhsType->AsFortran());
+ }
+ }
+ }
}
if (auto *derived{GetDerivedTypeSpec(*dyType)}) {
if (auto iter{FindAllocatableUltimateComponent(*derived)}) {
diff --git a/flang/test/Semantics/PowerPC/ppc-vector-diagnostics.f90 b/flang/test/Semantics/PowerPC/ppc-vector-diagnostics.f90
index 636c3a764f055..4cb21e936e8f6 100644
--- a/flang/test/Semantics/PowerPC/ppc-vector-diagnostics.f90
+++ b/flang/test/Semantics/PowerPC/ppc-vector-diagnostics.f90
@@ -13,3 +13,106 @@ subroutine test_vector_assignment()
!ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches operand types vector(integer(4)) and vector(real(4))
v1 = v2
end subroutine
+
+! Test that vector types are rejected in polymorphic contexts:
+! 1. ALLOCATE SOURCE=/MOLD= must not have a vector type expression
+! 2. RHS of intrinsic assignment must not be a vector type when LHS is polymorphic
+! (uses Fortran standard auto-allocation, no prior ALLOCATE)
+! 3. SAME_TYPE_AS / EXTENDS_TYPE_OF must not receive a vector type argument
+! (enforced via IsExtensibleType returning false for vector types)
+
+subroutine test_allocate_source()
+ vector(integer(4)) :: vi(2)
+ class(*), allocatable :: x(:)
+ !ERROR: SOURCE or MOLD expression must not be a vector type 'vector(integer(4))'
+ allocate(x(2), source=vi)
+end subroutine
+
+subroutine test_allocate_mold()
+ vector(real(4)) :: vr(2)
+ class(*), allocatable :: x(:)
+ !ERROR: SOURCE or MOLD expression must not be a vector type 'vector(real(4))'
+ allocate(x(2), mold=vr)
+end subroutine
+
+subroutine test_poly_assign_vector_rhs()
+ vector(real(4)) :: vr(2)
+ class(*), allocatable :: x(:)
+ ! x is unallocated; auto-allocation from RHS type must be rejected
+ !ERROR: Vector type 'vector(real(4))' may not be used as the right-hand side of a polymorphic intrinsic assignment
+ x = vr
+end subroutine
+
+subroutine test_same_type_as()
+ vector(integer(4)) :: vi(2)
+ logical :: res
+ !ERROR: Actual argument for 'a=' has type 'vector(integer(4))', but was expected to be an extensible or unlimited polymorphic type
+ res = same_type_as(vi, vi)
+end subroutine
+
+subroutine test_extends_type_of()
+ vector(real(4)) :: vr(2)
+ logical :: res
+ !ERROR: Actual argument for 'a=' has type 'vector(real(4))', but was expected to be an extensible or unlimited polymorphic type
+ res = extends_type_of(vr, vr)
+end subroutine
+
+! Test scalar POINTER and ALLOCATABLE vector type declarations (not supported)
+subroutine test_scalar_pointer()
+ !ERROR: Pointer to vector(integer(4)) type is not supported
+ vector(integer(4)), pointer :: p
+end subroutine
+
+subroutine test_scalar_allocatable()
+ !ERROR: Allocatable entity of vector(integer(4)) type is not supported
+ vector(integer(4)), allocatable :: v
+end subroutine
+
+! SAME_TYPE_AS with one unlimited polymorphic arg and one vector arg
+subroutine test_same_type_as_mixed(x)
+ class(*), intent(in) :: x
+ vector(integer(4)) :: vi(2)
+ logical :: res
+ !ERROR: Actual argument for 'b=' has type 'vector(integer(4))', but was expected to be an extensible or unlimited polymorphic type
+ res = same_type_as(x, vi)
+end subroutine
+
+! UDTI: dtv argument must not be a vector type
+module test_udti_vector_read_mod
+ interface read(formatted)
+ module procedure rf
+ end interface
+contains
+ subroutine rf(dtv, unit, iotype, vlist, iostat, iomsg)
+ !ERROR: Dummy argument 'dtv' of a defined input/output procedure must not be a vector type
+ vector(integer(4)), intent(inout) :: dtv
+ integer, intent(in) :: unit
+ character(*), intent(in) :: iotype
+ integer, intent(in) :: vlist(:)
+ integer, intent(out) :: iostat
+ character(*), intent(inout) :: iomsg
+ end subroutine
+end module
+
+module test_udti_vector_write_mod
+ interface write(formatted)
+ module procedure wf
+ end interface
+contains
+ subroutine wf(dtv, unit, iotype, vlist, iostat, iomsg)
+ !ERROR: Dummy argument 'dtv' of a defined input/output procedure must not be a vector type
+ vector(integer(4)), intent(in) :: dtv
+ integer, intent(in) :: unit
+ character(*), intent(in) :: iotype
+ integer, intent(in) :: vlist(:)
+ integer, intent(out) :: iostat
+ character(*), intent(inout) :: iomsg
+ end subroutine
+end module
+
+! CLASSOF with a vector type data-ref must be rejected (vector types are not extensible)
+subroutine test_classof_vector(c, vi)
+ vector(integer(4)), intent(in) :: vi(2)
+ !ERROR: CLASSOF requires a data-ref of extensible type
+ classof(vi) :: c
+end subroutine
More information about the flang-commits
mailing list