Skip to content

Commit b1e1090

Browse files
authored
[flang] Downgrade an error to a warning for specific circumstances (#155675)
We emit an error on the component name in the structure constructor "__builtin_c_ptr(__address=0)", which is the value of "c_ptr_null()", because the component name "__address" is PRIVATE to an intrinsic module. The error is specifically omitted, however, when the name appears in a module file, since it's what we emit for "c_ptr_null()" in initializers. This patch carves out another exception -- downgrading the error to a warning -- for the case of a PRIVATE component name in a structure constructor from an intrinsic module when the structure constructor appears in a module. This case arises when module files are being reprocessed as Fortran source in order to convert them to hermetic module files.
1 parent f19b807 commit b1e1090

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

flang/include/flang/Semantics/tools.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ bool IsAccessible(const Symbol &, const Scope &);
261261

262262
// Return an error if a symbol is not accessible from a scope
263263
std::optional<parser::MessageFormattedText> CheckAccessibleSymbol(
264-
const Scope &, const Symbol &);
264+
const Scope &, const Symbol &, bool inStructureConstructor = false);
265265

266266
// Analysis of image control statements
267267
bool IsImageControlStmt(const parser::ExecutableConstruct &);

flang/lib/Semantics/expression.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,8 @@ MaybeExpr ExpressionAnalyzer::CheckStructureConstructor(
21982198
}
21992199
if (symbol) {
22002200
const semantics::Scope &innermost{context_.FindScope(exprSource)};
2201-
if (auto msg{CheckAccessibleSymbol(innermost, *symbol)}) {
2201+
if (auto msg{CheckAccessibleSymbol(
2202+
innermost, *symbol, /*inStructureConstructor=*/true)}) {
22022203
Say(exprSource, std::move(*msg));
22032204
}
22042205
if (checkConflicts) {

flang/lib/Semantics/tools.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ bool IsAccessible(const Symbol &original, const Scope &scope) {
11701170
}
11711171

11721172
std::optional<parser::MessageFormattedText> CheckAccessibleSymbol(
1173-
const Scope &scope, const Symbol &symbol) {
1173+
const Scope &scope, const Symbol &symbol, bool inStructureConstructor) {
11741174
if (IsAccessible(symbol, scope)) {
11751175
return std::nullopt;
11761176
} else if (FindModuleFileContaining(scope)) {
@@ -1179,10 +1179,20 @@ std::optional<parser::MessageFormattedText> CheckAccessibleSymbol(
11791179
// whose structure constructors reference private components.
11801180
return std::nullopt;
11811181
} else {
1182+
const Scope &module{DEREF(FindModuleContaining(symbol.owner()))};
1183+
// Subtlety: Sometimes we want to be able to convert a generated
1184+
// module file back into Fortran, perhaps to convert it into a
1185+
// hermetic module file. Don't emit a fatal error for things like
1186+
// "__builtin_c_ptr(__address=0)" that came from expansions of
1187+
// "cptr_null()"; specifically, just warn about structure constructor
1188+
// component names from intrinsic modules when in a module.
1189+
parser::MessageFixedText text{FindModuleContaining(scope) &&
1190+
module.parent().IsIntrinsicModules() &&
1191+
inStructureConstructor && symbol.owner().IsDerivedType()
1192+
? "PRIVATE name '%s' is accessible only within module '%s'"_warn_en_US
1193+
: "PRIVATE name '%s' is accessible only within module '%s'"_err_en_US};
11821194
return parser::MessageFormattedText{
1183-
"PRIVATE name '%s' is accessible only within module '%s'"_err_en_US,
1184-
symbol.name(),
1185-
DEREF(FindModuleContaining(symbol.owner())).GetName().value()};
1195+
std::move(text), symbol.name(), module.GetName().value()};
11861196
}
11871197
}
11881198

flang/test/Semantics/c_loc01.f90

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,12 @@ pure integer function purefun2(p)
6666
purefun2 = 1
6767
end
6868
end module
69+
70+
module m2
71+
use iso_c_binding
72+
! In this context (structure constructor from intrinsic module being used directly
73+
! in another module), emit only a warning, since this module might have originally
74+
! been a module file that was converted back into Fortran.
75+
!WARNING: PRIVATE name '__address' is accessible only within module '__fortran_builtins'
76+
type(c_ptr) :: p = c_ptr(0)
77+
end

0 commit comments

Comments
 (0)