mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-14 12:12:07 +00:00
[flang] Allow some BOZ usage when unambiguous (extension)
Original-commit: flang-compiler/f18@bf3bd54c88 Reviewed-on: https://github.com/flang-compiler/f18/pull/477 Tree-same-pre-rewrite: false
This commit is contained in:
parent
0ddea8ae24
commit
d72fd348f7
@ -66,6 +66,9 @@ Extensions, deletions, and legacy features supported by default
|
||||
* 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.
|
||||
* BOZ literals can be used as INTEGER values in contexts where the type is
|
||||
unambiguous (including the right hand sides of assigments and initializations
|
||||
of INTEGER entities).
|
||||
|
||||
Extensions supported when enabled by options
|
||||
--------------------------------------------
|
||||
@ -91,6 +94,6 @@ Extensions and legacy features deliberately not supported
|
||||
* Characters in defined operators that are neither letters nor digits
|
||||
* `B` suffix on unquoted octal constants
|
||||
* `Z` prefix on unquoted hexadecimal constants (dangerous)
|
||||
* `T` and `F` as abbreviations for `.TRUE.` and `.FALSE.` (dangerous)
|
||||
* `T` and `F` as abbreviations for `.TRUE.` and `.FALSE.` in DATA (PGI/XLF)
|
||||
* Use of host FORMAT labels in internal subprograms (PGI-only feature)
|
||||
* ALLOCATE(TYPE(derived)::...) as variant of correct ALLOCATE(derived::...) (PGI only)
|
||||
|
@ -410,13 +410,13 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
|
||||
RelationalOperator opr, Expr<SomeType> &&x, Expr<SomeType> &&y) {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
[=](Expr<SomeInteger> &&ix, Expr<SomeInteger> &&iy) {
|
||||
return std::make_optional(
|
||||
PromoteAndRelate(opr, std::move(ix), std::move(iy)));
|
||||
[=](Expr<SomeInteger> &&ix,
|
||||
Expr<SomeInteger> &&iy) -> std::optional<Expr<LogicalResult>> {
|
||||
return PromoteAndRelate(opr, std::move(ix), std::move(iy));
|
||||
},
|
||||
[=](Expr<SomeReal> &&rx, Expr<SomeReal> &&ry) {
|
||||
return std::make_optional(
|
||||
PromoteAndRelate(opr, std::move(rx), std::move(ry)));
|
||||
[=](Expr<SomeReal> &&rx,
|
||||
Expr<SomeReal> &&ry) -> std::optional<Expr<LogicalResult>> {
|
||||
return PromoteAndRelate(opr, std::move(rx), std::move(ry));
|
||||
},
|
||||
[&](Expr<SomeReal> &&rx, Expr<SomeInteger> &&iy) {
|
||||
return Relate(messages, opr, std::move(x),
|
||||
@ -426,12 +426,12 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
|
||||
return Relate(messages, opr,
|
||||
AsGenericExpr(ConvertTo(ry, std::move(ix))), std::move(y));
|
||||
},
|
||||
[&](Expr<SomeComplex> &&zx, Expr<SomeComplex> &&zy) {
|
||||
[&](Expr<SomeComplex> &&zx,
|
||||
Expr<SomeComplex> &&zy) -> std::optional<Expr<LogicalResult>> {
|
||||
if (opr != RelationalOperator::EQ &&
|
||||
opr != RelationalOperator::NE) {
|
||||
messages.Say(
|
||||
"COMPLEX data may be compared only for equality"_err_en_US);
|
||||
return std::optional<Expr<LogicalResult>>{};
|
||||
} else {
|
||||
auto rr{Relate(messages, opr,
|
||||
AsGenericExpr(GetComplexPart(zx, false)),
|
||||
@ -446,14 +446,13 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
|
||||
LogicalOperator combine{opr == RelationalOperator::EQ
|
||||
? LogicalOperator::And
|
||||
: LogicalOperator::Or};
|
||||
return std::make_optional(
|
||||
Expr<LogicalResult>{LogicalOperation<LogicalResult::kind>{
|
||||
combine, std::move(std::get<0>(*parts)),
|
||||
std::move(std::get<1>(*parts))}});
|
||||
} else {
|
||||
return std::optional<Expr<LogicalResult>>{};
|
||||
return Expr<LogicalResult>{
|
||||
LogicalOperation<LogicalResult::kind>{combine,
|
||||
std::move(std::get<0>(*parts)),
|
||||
std::move(std::get<1>(*parts))}};
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
},
|
||||
[&](Expr<SomeComplex> &&zx, Expr<SomeInteger> &&iy) {
|
||||
return Relate(messages, opr, std::move(x),
|
||||
@ -473,11 +472,11 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
|
||||
},
|
||||
[&](Expr<SomeCharacter> &&cx, Expr<SomeCharacter> &&cy) {
|
||||
return std::visit(
|
||||
[&](auto &&cxk, auto &&cyk) {
|
||||
[&](auto &&cxk,
|
||||
auto &&cyk) -> std::optional<Expr<LogicalResult>> {
|
||||
using Ty = ResultType<decltype(cxk)>;
|
||||
if constexpr (std::is_same_v<Ty, ResultType<decltype(cyk)>>) {
|
||||
return std::make_optional(
|
||||
PackageRelation(opr, std::move(cxk), std::move(cyk)));
|
||||
return PackageRelation(opr, std::move(cxk), std::move(cyk));
|
||||
} else {
|
||||
messages.Say(
|
||||
"CHARACTER operands do not have same KIND"_err_en_US);
|
||||
@ -487,11 +486,11 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
|
||||
std::move(cx.u), std::move(cy.u));
|
||||
},
|
||||
// Default case
|
||||
[&](auto &&, auto &&) {
|
||||
[&](auto &&, auto &&) -> std::optional<Expr<LogicalResult>> {
|
||||
// TODO: defined operator
|
||||
messages.Say(
|
||||
"relational operands do not have comparable types"_err_en_US);
|
||||
return std::optional<Expr<LogicalResult>>{};
|
||||
return std::nullopt;
|
||||
},
|
||||
},
|
||||
std::move(x.u), std::move(y.u));
|
||||
@ -516,8 +515,7 @@ std::optional<Expr<SomeType>> ConvertToNumeric(int kind, Expr<SomeType> &&x) {
|
||||
using cxType = std::decay_t<decltype(cx)>;
|
||||
if constexpr (!common::HasMember<cxType, TypelessExpression>) {
|
||||
if constexpr (IsNumericTypeCategory(ResultType<cxType>::category)) {
|
||||
return std::make_optional(
|
||||
Expr<SomeType>{ConvertToKind<TO>(kind, std::move(cx))});
|
||||
return Expr<SomeType>{ConvertToKind<TO>(kind, std::move(cx))};
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
@ -529,6 +527,12 @@ std::optional<Expr<SomeType>> ConvertToType(
|
||||
const DynamicType &type, Expr<SomeType> &&x) {
|
||||
switch (type.category()) {
|
||||
case TypeCategory::Integer:
|
||||
if (auto *boz{std::get_if<BOZLiteralConstant>(&x.u)}) {
|
||||
// Extension to C7109: allow BOZ literals to appear in integer contexts
|
||||
// when the type is unambiguous.
|
||||
return Expr<SomeType>{
|
||||
ConvertToKind<TypeCategory::Integer>(type.kind(), std::move(*boz))};
|
||||
}
|
||||
return ConvertToNumeric<TypeCategory::Integer>(type.kind(), std::move(x));
|
||||
case TypeCategory::Real:
|
||||
return ConvertToNumeric<TypeCategory::Real>(type.kind(), std::move(x));
|
||||
|
@ -637,7 +637,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
|
||||
// derived type definition)
|
||||
return AsMaybeExpr(MakeBareTypeParamInquiry(&ultimate));
|
||||
} else {
|
||||
return Designate(DataRef{*n.symbol});
|
||||
return Designate(DataRef{ultimate});
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
|
Loading…
x
Reference in New Issue
Block a user