[flang-commits] [flang] a73f7ab - [flang] Error handling for out-of-range CASE values
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Wed Apr 13 18:35:07 PDT 2022
Author: Peter Klausler
Date: 2022-04-13T18:35:00-07:00
New Revision: a73f7ababb4b2de65c6e2cdd832fc1f8c21207cf
URL: https://github.com/llvm/llvm-project/commit/a73f7ababb4b2de65c6e2cdd832fc1f8c21207cf
DIFF: https://github.com/llvm/llvm-project/commit/a73f7ababb4b2de65c6e2cdd832fc1f8c21207cf.diff
LOG: [flang] Error handling for out-of-range CASE values
Catch and nicely describe errors in CASE range values
that are out of range for the type of the SELECT CASE.
Differential Revision: https://reviews.llvm.org/D123708
Added:
Modified:
flang/lib/Semantics/check-case.cpp
flang/test/Semantics/case01.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-case.cpp b/flang/lib/Semantics/check-case.cpp
index 3c52de8306b69..262a68596ae7d 100644
--- a/flang/lib/Semantics/check-case.cpp
+++ b/flang/lib/Semantics/check-case.cpp
@@ -79,15 +79,31 @@ template <typename T> class CaseValues {
if (type && type->category() == caseExprType_.category() &&
(type->category() != TypeCategory::Character ||
type->kind() == caseExprType_.kind())) {
- x->v = evaluate::Fold(context_.foldingContext(),
- evaluate::ConvertToType(T::GetType(), std::move(*x->v)));
- if (x->v) {
- if (auto value{evaluate::GetScalarConstantValue<T>(*x->v)}) {
- return *value;
+ parser::Messages buffer; // discarded folding messages
+ parser::ContextualMessages foldingMessages{expr.source, &buffer};
+ evaluate::FoldingContext foldingContext{
+ context_.foldingContext(), foldingMessages};
+ auto folded{evaluate::Fold(foldingContext, SomeExpr{*x->v})};
+ if (auto converted{evaluate::Fold(foldingContext,
+ evaluate::ConvertToType(T::GetType(), SomeExpr{folded}))}) {
+ if (auto value{evaluate::GetScalarConstantValue<T>(*converted)}) {
+ auto back{evaluate::Fold(foldingContext,
+ evaluate::ConvertToType(*type, SomeExpr{*converted}))};
+ if (back == folded) {
+ x->v = converted;
+ return value;
+ } else {
+ context_.Say(expr.source,
+ "CASE value (%s) overflows type (%s) of SELECT CASE expression"_err_en_US,
+ folded.AsFortran(), caseExprType_.AsFortran());
+ hasErrors_ = true;
+ return std::nullopt;
+ }
}
}
- context_.Say(
- expr.source, "CASE value must be a constant scalar"_err_en_US);
+ context_.Say(expr.source,
+ "CASE value (%s) must be a constant scalar"_err_en_US,
+ x->v->AsFortran());
} else {
std::string typeStr{type ? type->AsFortran() : "typeless"s};
context_.Say(expr.source,
diff --git a/flang/test/Semantics/case01.f90 b/flang/test/Semantics/case01.f90
index 42eb07d20982f..020f25119b708 100644
--- a/flang/test/Semantics/case01.f90
+++ b/flang/test/Semantics/case01.f90
@@ -177,3 +177,24 @@ program test_overlap
case(:0)
end select
end
+
+program test_overflow
+ integer :: j
+ select case(1_1)
+ case (127)
+ !ERROR: CASE value (128_4) overflows type (INTEGER(1)) of SELECT CASE expression
+ case (128)
+ !ERROR: CASE value (129_4) overflows type (INTEGER(1)) of SELECT CASE expression
+ !ERROR: CASE value (130_4) overflows type (INTEGER(1)) of SELECT CASE expression
+ case (129:130)
+ !ERROR: CASE value (-130_4) overflows type (INTEGER(1)) of SELECT CASE expression
+ !ERROR: CASE value (-129_4) overflows type (INTEGER(1)) of SELECT CASE expression
+ case (-130:-129)
+ case (-128)
+ !ERROR: Must be a scalar value, but is a rank-1 array
+ case ([1, 2])
+ !ERROR: Must be a constant value
+ case (j)
+ case default
+ end select
+end
More information about the flang-commits
mailing list