mirror of
https://github.com/intel/llvm.git
synced 2026-01-31 16:29:50 +08:00
[flang] Check for undefined derived types
It's possible to specify refer to an undefined derived type as the type of a component of another derived type and then never define the type of the component. We were not detecting this situation. To fix this, I changed the value of isForwardReferenced_ in the symbol's DerivedTypeDetails and checked for it when performing other derived type checks. I also had to record the fact that error messages were previously emitted for the same problem in some cases so that I could avoid duplicate messages. I also added a test. Differential Revision: https://reviews.llvm.org/D103714
This commit is contained in:
@@ -259,7 +259,7 @@ public:
|
||||
void add_paramDecl(const Symbol &symbol) { paramDecls_.push_back(symbol); }
|
||||
void add_component(const Symbol &);
|
||||
void set_sequence(bool x = true) { sequence_ = x; }
|
||||
void set_isForwardReferenced() { isForwardReferenced_ = true; }
|
||||
void set_isForwardReferenced(bool value) { isForwardReferenced_ = value; }
|
||||
const std::list<SourceName> &componentNames() const {
|
||||
return componentNames_;
|
||||
}
|
||||
|
||||
@@ -845,6 +845,10 @@ void CheckHelper::CheckSubprogram(
|
||||
|
||||
void CheckHelper::CheckDerivedType(
|
||||
const Symbol &derivedType, const DerivedTypeDetails &details) {
|
||||
if (details.isForwardReferenced() && !context_.HasError(derivedType)) {
|
||||
messages_.Say("The derived type '%s' has not been defined"_err_en_US,
|
||||
derivedType.name());
|
||||
}
|
||||
const Scope *scope{derivedType.scope()};
|
||||
if (!scope) {
|
||||
CHECK(details.isForwardReferenced());
|
||||
|
||||
@@ -3957,6 +3957,7 @@ bool DeclarationVisitor::Pre(const parser::DerivedTypeDef &x) {
|
||||
CHECK(scope.symbol());
|
||||
CHECK(scope.symbol()->scope() == &scope);
|
||||
auto &details{scope.symbol()->get<DerivedTypeDetails>()};
|
||||
details.set_isForwardReferenced(false);
|
||||
std::set<SourceName> paramNames;
|
||||
for (auto ¶mName : std::get<std::list<parser::Name>>(stmt.statement.t)) {
|
||||
details.add_paramName(paramName.source);
|
||||
@@ -5027,7 +5028,7 @@ std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveDerivedType(
|
||||
Resolve(name, *symbol);
|
||||
};
|
||||
DerivedTypeDetails details;
|
||||
details.set_isForwardReferenced();
|
||||
details.set_isForwardReferenced(true);
|
||||
symbol->set_details(std::move(details));
|
||||
} else { // C732
|
||||
Say(name, "Derived type '%s' not found"_err_en_US);
|
||||
|
||||
@@ -244,6 +244,7 @@ void DerivedTypeSpec::Instantiate(Scope &containingScope) {
|
||||
foldingContext.messages().Say(typeSymbol_.name(),
|
||||
"The derived type '%s' was forward-referenced but not defined"_err_en_US,
|
||||
typeSymbol_.name());
|
||||
context.SetError(typeSymbol_);
|
||||
return;
|
||||
}
|
||||
EvaluateParameters(context);
|
||||
|
||||
@@ -90,3 +90,10 @@ subroutine s9
|
||||
integer, kind :: n = 3
|
||||
end type
|
||||
end subroutine s9
|
||||
|
||||
subroutine s10
|
||||
type t
|
||||
!ERROR: The derived type 'undef' has not been defined
|
||||
type(undef), pointer :: y
|
||||
end type
|
||||
end subroutine s10
|
||||
|
||||
Reference in New Issue
Block a user