If the negate expression is not in the specification part of module
or submodule, it should be analyzed. Otherwise, the lowering will
fail when it checks if the negate expression is analyzed. The real
cases are in https://github.com/llvm/llvm-project/issues/55966.
Details
Diff Detail
Event Timeline
flang/lib/Semantics/expression.cpp | ||
---|---|---|
2674 | Why is this applicable only for Negate? |
flang/lib/Semantics/expression.cpp | ||
---|---|---|
2674 | The patch bringing in this bug is aimed to fix the issue https://github.com/llvm/llvm-project/issues/55086. -2147483647-1 is the special case in module/submodule and supporting it is the portability issue beyond Fortran 2018. |
flang/lib/Semantics/expression.cpp | ||
---|---|---|
2674 | I have checked current main, and D127735 can fix this problem, too. However, I think it still needs analyze the negate expression when it is not in module/submodule since doing the similar analysis as the unary plus expression is reasonable. What do you think? @jeanPerier Would it affect the lowering if the negate expression in execution part not analyzed? |
However, I think it still needs analyze the negate expression when it is not in module/submodule since doing the similar analysis as the unary plus expression is reasonable. What do you think? @jeanPerier Would it affect the lowering if the negate expression in execution part not analyzed?
I am a bit lost here, is it not analyzed currently ? Analyze seems to be called in the if (const auto *litConst{..... It would be an issue if it is not analyzed in lowering: lowering relies on evaluate::Expr, not the parse tree expression.
Where in you example is the expression not analyzed yet ?
I am a bit lost here, is it not analyzed currently ? Analyze seems to be called in the if (const auto *litConst{.....
No, it does not analyze the negate expression entirely.
Where in you example is the expression not analyzed yet ?
You can check the variable j in the test case of this patch. Without this patch, the result of dumping parse tree is as follows:
| | | | | | Name = 'j' | | | | | | Initialization -> Constant -> Expr = '-2147483648_4' | | | | | | | Subtract | | | | | | | | Expr = '-2147483647_4' | | | | | | | | | Negate -> Expr -> LiteralConstant -> IntLiteralConstant = '2147483647' | | | | | | | | Expr = '1_4' | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
If the negate expression is analyzed, it is as follows:
! CHECK: | | Expr = '-2147483647_4' ! CHECK: | | | Negate -> Expr = '2147483647_4' ! CHECK: | | | | LiteralConstant -> IntLiteralConstant = '2147483647'
Currently, I don't see any failure when testing running results. But I am worried if there will any hidden bug.
Thanks for the answer Peixin, now I see what you meant. I however think that may be a "feature", not a bug. With your patch the following code would be rejected:
integer(4), parameter :: i = -2147483648_4 end
While it is currently accepted with a warning: "portability: negated maximum INTEGER(KIND=4) literal".
I think the issue here is that if the negate operand evaluate::Expr was built/analyzed when it is a constant, it would not be possible to represent the operand "2147483648_4" as an Expr since this would overflow.
This is not an issue in lowering because if the negate operand is a constant, so is the parent expression containing the negate, which is always analyzed, and lowering never needs to visit the operand parse tree expression (*). In general, lowering always use the top level analyzed evaluate::Expr of a parse-tree expressions, so it is not an issue if some sub-expression parser::Expr are not analyzed, although I agree it is not very nice.
(*) The exception being the PFT visit to detect all symbols appearing a program parse-tree, but if a sub-node is not analyzed, the visit simply consider there is no symbols there.
Got it. Thanks for the explanations and confirmation that lowering is fine with this.
Why is this applicable only for Negate?