New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pointer assignment semantic checks #928
Conversation
@@ -636,7 +638,7 @@ std::optional<Procedure> Procedure::Characterize( | |||
[&](const semantics::ProcEntityDetails &proc) | |||
-> std::optional<Procedure> { | |||
if (symbol.attrs().test(semantics::Attr::INTRINSIC)) { | |||
return intrinsics.IsUnrestrictedSpecificIntrinsicFunction( | |||
return intrinsics.IsSpecificIntrinsicFunction( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you summarize for me what's changed here? Do you permit procedure pointers to point to restricted specific intrinsic functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change is to be able to detect specific intrinsic functions, both restricted and unrestricted. IsSpecificIntrinsicFunction
returns a struct that has a flag to distinguish restricted and unrestricted. That flag is propagated to SpecificIntrinsic
in ProcedureDesignator
by ExpressionAnalyzer::Designate
.
The new tests in resolve46.f90
verify that procedure pointers can't point to restricted specific intrinsic functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from the uncapitalized messages in assignment.cc, all builds, tests, and looks good.
Say(elsewhereStmt.source, | ||
"mask of ELSEWHERE statement is not conformable with " | ||
"the prior mask(s) in its WHERE construct"_err_en_US); | ||
context_.Say("mask of ELSEWHERE statement is not conformable with " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other error messages begin with a capital letter.
for (const auto &x : | ||
std::get<std::list<parser::WhereBodyConstruct>>(elsewhere.t)) { | ||
Analyze(x); | ||
context_.Say("effective mask of ELSEWHERE statement is not conformable " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find a test that produces this error message.
|
||
template<typename A> void PointerAssignmentChecker::Check(const A &) { | ||
// Catch-all case for really bad target expression | ||
Say("Target associated with %s must be a designator or a call to a" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No test case for this message.
std::optional<parser::MessageFixedText> msg; | ||
const auto &funcResult{proc->functionResult}; // C1025 | ||
if (!funcResult) { | ||
msg = "%s is associated with the non-existent result of reference to" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't find a test case for this message.
" procedure"_err_en_US; | ||
} else if (procedure_) { | ||
// Shouldn't be here in this function unless lhs is an object pointer. | ||
msg = "Procedure %s is associated with the result of a reference to" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't find a test case for this message.
std::optional<parser::MessageFixedText> msg; | ||
if (procedure_) { | ||
// Shouldn't be here in this function unless lhs is an object pointer. | ||
msg = "In assignment to procedure %s, the target is not a procedure or" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No test for this message.
msg = "In assignment to procedure %s, the target is not a procedure or" | ||
" procedure pointer"_err_en_US; | ||
} else if (!evaluate::GetLastTarget(GetSymbolVector(d))) { // C1025 | ||
msg = "In assignment to object %s, the target '%s' is not an object with" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No test for this message.
" POINTER or TARGET attributes"_err_en_US; | ||
} else if (auto rhsType{TypeAndShape::Characterize(*last, context_)}) { | ||
if (!lhsType_) { | ||
msg = "%s associated with object '%s' with incompatible type or" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No test for this message.
parser::CharBlock rhsName, bool isCall, const Procedure *rhsProcedure) { | ||
std::optional<parser::MessageFixedText> msg; | ||
if (!procedure_) { | ||
msg = "In assignment to object %s, the target '%s' is a procedure" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No test for this message.
msg = "In assignment to object %s, the target '%s' is a procedure" | ||
" designator"_err_en_US; | ||
} else if (!rhsProcedure) { | ||
msg = "In assignment to procedure %s, the characteristics of the target" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No test for this message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed that all of these messages without tests were just copied from assignment.cc. Feel free to ignore my comments.
Eliminate `at_` and use location from `SemanticsContext` instead. Add and use Analyze functions for `std::optional` and `std::list`.
Create `pointer-assignment.{h,cc}` for pointer assignment checking. It doesn't share with assignment checking so it should be its own file. Move the code into semantics namespace.
`DynamicType::AsFortran` was using mixed case for intrinic type names. Make it upper case for consistency with TYPE(...) and CHARACTER when a length is present and other error messages.
This replaces IsUnrestrictedSpecificIntrinsicFunction and returns information that allows the caller to distinguish between restricted and unrestricted intrinsics. The new case in `resolve46.f90` used to get an internal error.
Call `CheckPointerAssignment()` when analyzing a pointer assignment statement. NOTE: the cases with bounds-spec and bounds-remapping are still to be done. Perform checks on pointer symbols in `check-declarations.cc`. Check for pointer to generic intrinsic in `semantics/expression.cc`. Add the other required pointer assignment checks to `pointer-assignment.cc`.
23b5195
to
3dc5fd6
Compare
Eliminate `at_` and use location from `SemanticsContext` instead. Add and use Analyze functions for `std::optional` and `std::list`. Original-commit: flang-compiler/f18@e171029 Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
Create `pointer-assignment.{h,cc}` for pointer assignment checking. It doesn't share with assignment checking so it should be its own file. Move the code into semantics namespace. Original-commit: flang-compiler/f18@1658aba Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
`DynamicType::AsFortran` was using mixed case for intrinic type names. Make it upper case for consistency with TYPE(...) and CHARACTER when a length is present and other error messages. Original-commit: flang-compiler/f18@e16909d Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
This replaces IsUnrestrictedSpecificIntrinsicFunction and returns information that allows the caller to distinguish between restricted and unrestricted intrinsics. The new case in `resolve46.f90` used to get an internal error. Original-commit: flang-compiler/f18@4cb1ee1 Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
Original-commit: flang-compiler/f18@4261daf Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
Call `CheckPointerAssignment()` when analyzing a pointer assignment statement. NOTE: the cases with bounds-spec and bounds-remapping are still to be done. Perform checks on pointer symbols in `check-declarations.cc`. Check for pointer to generic intrinsic in `semantics/expression.cc`. Add the other required pointer assignment checks to `pointer-assignment.cc`. Original-commit: flang-compiler/f18@3dc5fd6 Reviewed-on: flang-compiler/f18#928
…/tsk-assignment3 Pointer assignment semantic checks Original-commit: flang-compiler/f18@fc600af Reviewed-on: flang-compiler/f18#928
Eliminate `at_` and use location from `SemanticsContext` instead. Add and use Analyze functions for `std::optional` and `std::list`. Original-commit: flang-compiler/f18@e171029 Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
Create `pointer-assignment.{h,cc}` for pointer assignment checking. It doesn't share with assignment checking so it should be its own file. Move the code into semantics namespace. Original-commit: flang-compiler/f18@1658aba Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
`DynamicType::AsFortran` was using mixed case for intrinic type names. Make it upper case for consistency with TYPE(...) and CHARACTER when a length is present and other error messages. Original-commit: flang-compiler/f18@e16909d Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
This replaces IsUnrestrictedSpecificIntrinsicFunction and returns information that allows the caller to distinguish between restricted and unrestricted intrinsics. The new case in `resolve46.f90` used to get an internal error. Original-commit: flang-compiler/f18@4cb1ee1 Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
Original-commit: flang-compiler/f18@4261daf Reviewed-on: flang-compiler/f18#928 Tree-same-pre-rewrite: false
Call `CheckPointerAssignment()` when analyzing a pointer assignment statement. NOTE: the cases with bounds-spec and bounds-remapping are still to be done. Perform checks on pointer symbols in `check-declarations.cc`. Check for pointer to generic intrinsic in `semantics/expression.cc`. Add the other required pointer assignment checks to `pointer-assignment.cc`. Original-commit: flang-compiler/f18@3dc5fd6 Reviewed-on: flang-compiler/f18#928
See individual commits.