mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 04:14:03 +08:00
[flang] Handle large integer literals without kinds better
Original-commit: flang-compiler/f18@381ea32d57 Reviewed-on: https://github.com/flang-compiler/f18/pull/472 Tree-same-pre-rewrite: false
This commit is contained in:
@@ -63,6 +63,9 @@ Extensions, deletions, and legacy features supported by default
|
||||
* $ and \ edit descriptors are supported in FORMAT to suppress newline
|
||||
output on user prompts.
|
||||
* REAL variable and bounds in DO loops
|
||||
* Integer literals without explicit kind specifiers that are out of range
|
||||
for the default kind of INTEGER are assumed to have the least larger kind
|
||||
that can hold them, if one exists.
|
||||
|
||||
Extensions supported when enabled by options
|
||||
--------------------------------------------
|
||||
|
||||
@@ -30,7 +30,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
|
||||
Convert, Dispose, IOListLeadingComma, AbbreviatedEditDescriptor,
|
||||
ProgramParentheses, PercentRefAndVal, OmitFunctionDummies, CrayPointer,
|
||||
Hollerith, ArithmeticIF, Assign, AssignedGOTO, Pause, OpenMP,
|
||||
CruftAfterAmpersand, ClassicCComments, AdditionalFormats)
|
||||
CruftAfterAmpersand, ClassicCComments, AdditionalFormats, BigIntLiterals)
|
||||
|
||||
using LanguageFeatures =
|
||||
common::EnumSet<LanguageFeature, LanguageFeature_enumSize>;
|
||||
|
||||
@@ -357,30 +357,51 @@ struct IntTypeVisitor {
|
||||
using Result = MaybeExpr;
|
||||
using Types = IntegerTypes;
|
||||
template<typename T> Result Test() {
|
||||
if (T::kind == kind) {
|
||||
if (T::kind >= kind) {
|
||||
const char *p{digits.begin()};
|
||||
auto value{T::Scalar::Read(p, 10, true)};
|
||||
auto value{T::Scalar::Read(p, 10, true /*signed*/)};
|
||||
if (!value.overflow) {
|
||||
if (T::kind > kind) {
|
||||
if (!isDefaultKind ||
|
||||
!analyzer.context().IsEnabled(
|
||||
parser::LanguageFeature::BigIntLiterals)) {
|
||||
return std::nullopt;
|
||||
} else if (analyzer.context().ShouldWarn(
|
||||
parser::LanguageFeature::BigIntLiterals)) {
|
||||
analyzer.Say(digits,
|
||||
"Integer literal is too large for default INTEGER(KIND=%d); "
|
||||
"assuming INTEGER(KIND=%d)"_en_US,
|
||||
kind, T::kind);
|
||||
}
|
||||
}
|
||||
return Expr<SomeType>{
|
||||
Expr<SomeInteger>{Expr<T>{Constant<T>{std::move(value.value)}}}};
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
ExpressionAnalyzer &analyzer;
|
||||
parser::CharBlock digits;
|
||||
int kind;
|
||||
bool isDefaultKind;
|
||||
};
|
||||
|
||||
template<typename PARSED>
|
||||
MaybeExpr ExpressionAnalyzer::IntLiteralConstant(const PARSED &x) {
|
||||
int kind{AnalyzeKindParam(std::get<std::optional<parser::KindParam>>(x.t),
|
||||
GetDefaultKind(TypeCategory::Integer))};
|
||||
const auto &kindParam{std::get<std::optional<parser::KindParam>>(x.t)};
|
||||
bool isDefaultKind{!kindParam.has_value()};
|
||||
int kind{AnalyzeKindParam(kindParam, GetDefaultKind(TypeCategory::Integer))};
|
||||
if (CheckIntrinsicKind(TypeCategory::Integer, kind)) {
|
||||
auto digits{std::get<parser::CharBlock>(x.t)};
|
||||
if (MaybeExpr result{common::SearchTypes(IntTypeVisitor{digits, kind})}) {
|
||||
if (MaybeExpr result{common::SearchTypes(
|
||||
IntTypeVisitor{*this, digits, kind, isDefaultKind})}) {
|
||||
return result;
|
||||
} else if (isDefaultKind) {
|
||||
Say(digits,
|
||||
"Integer literal is too large for any allowable "
|
||||
"kind of INTEGER"_err_en_US);
|
||||
} else {
|
||||
Say(digits, "Integer literal too large for INTEGER(KIND=%d)"_err_en_US,
|
||||
Say(digits, "Integer literal is too large for INTEGER(KIND=%d)"_err_en_US,
|
||||
kind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,48 +19,48 @@
|
||||
! as part of expressions that name resolution must analyze.
|
||||
|
||||
complex, parameter :: okj1 = 127_1, okz1 = (+127_1, -128_1)
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=1)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=1)
|
||||
complex, parameter :: badj1 = 128_1
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=1)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=1)
|
||||
complex, parameter :: badz1 = (+128_1, 0)
|
||||
complex, parameter :: okj1a = 128_2
|
||||
complex, parameter :: okz1a = (+128_2, 0)
|
||||
|
||||
complex, parameter :: okj2 = 32767_2, okz2 = (+32767_2, -32768_2)
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=2)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=2)
|
||||
complex, parameter :: badj2 = 32768_2
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=2)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=2)
|
||||
complex, parameter :: badz2 = (+32768_2, 0)
|
||||
complex, parameter :: okj2a = 32768_4
|
||||
complex, parameter :: okz2a = (+32768_4, 0)
|
||||
|
||||
complex, parameter :: okj4 = 2147483647_4, okz4 = (+2147483647_4, -2147483648_4)
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=4)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=4)
|
||||
complex, parameter :: badj4 = 2147483648_4
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=4)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=4)
|
||||
complex, parameter :: badz4 = (+2147483648_4, 0)
|
||||
complex, parameter :: okj4a = 2147483648_8
|
||||
complex, parameter :: okz4a = (+2147483648_8, 0)
|
||||
|
||||
complex, parameter :: okj4d = 2147483647, okz4d = (+2147483647, -2147483648)
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=4)
|
||||
complex, parameter :: badj4d = 2147483648
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=4)
|
||||
complex, parameter :: badz4d = (+2147483648, 0)
|
||||
!WARNING: Integer literal is too large for default INTEGER(KIND=4); assuming INTEGER(KIND=8)
|
||||
complex, parameter :: badj4dext = 2147483648
|
||||
!WARNING: Integer literal is too large for default INTEGER(KIND=4); assuming INTEGER(KIND=8)
|
||||
complex, parameter :: badz4dext = (+2147483648, 0)
|
||||
|
||||
complex, parameter :: okj8 = 9223372036854775807_8, okz8 = (+9223372036854775807_8, -9223372036854775808_8)
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=8)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=8)
|
||||
complex, parameter :: badj8 = 9223372036854775808_8
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=8)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=8)
|
||||
complex, parameter :: badz8 = (+9223372036854775808_8, 0)
|
||||
complex, parameter :: okj8a = 9223372036854775808_16
|
||||
complex, parameter :: okz8a = (+9223372036854775808_16, 0)
|
||||
|
||||
complex, parameter :: okj16 = 170141183460469231731687303715884105727_16
|
||||
complex, parameter :: okz16 = (+170141183460469231731687303715884105727_16, -170141183460469231731687303715884105728_16)
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=16)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=16)
|
||||
complex, parameter :: badj16 = 170141183460469231731687303715884105728_16
|
||||
!ERROR: Integer literal too large for INTEGER(KIND=16)
|
||||
!ERROR: Integer literal is too large for INTEGER(KIND=16)
|
||||
complex, parameter :: badz16 = (+170141183460469231731687303715884105728_16, 0)
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user