Skip to content

Commit 1b4db78

Browse files
committed
[C++20] [Modules] Implement diagnose for exposured partially
Tracked at llvm#112294 This patch implements from [basic.link]p14 to [basic.link]p18 partially. The explicitly missing parts are: - Anything related to specializations. - Decide if a pointer is associated with a TU-local value at compile time. - [basic.link]p15.1.2 to decide if a type is TU-local. - Diagnose if TU-local functions from other TU are collected to the overload set. See [basic.link]p19, the call to 'h(N::A{});' in translation unit #2 There should be other implicitly missing parts as the wording uses "names" briefly several times. But to implement this precisely, we have to visit the whole AST, including Decls, Expression and Types, which may be harder to implement and be more time-consuming for compilation time. So I choose to implement the common parts. It won't be too bad to miss some cases since we DIDN'T do any such checks in the past 3 years. Any new check is an improvement. Given modules have been basically available since clang15 without such checks, it will be user unfriendly if we give a hard error now. And there are a lot of cases which violating the rule actually just fine. So I decide to emit it as warnings instead of hard errors.
1 parent eb04b69 commit 1b4db78

File tree

8 files changed

+620
-0
lines changed

8 files changed

+620
-0
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12391,6 +12391,13 @@ def err_invalid_module_name : Error<"%0 is an invalid name for a module">;
1239112391
def err_extern_def_in_header_unit : Error<
1239212392
"non-inline external definitions are not permitted in C++ header units">;
1239312393

12394+
def warn_exposure : Warning <
12395+
"TU local entity %0 is exposed">,
12396+
InGroup<DiagGroup<"TU-local-entity-exposure">>;
12397+
def warn_reference_tu_local_entity_in_other_tu : Warning <
12398+
"instantiation of %0 triggers reference to TU-local entity %1 from other TU '%2'">,
12399+
InGroup<DiagGroup<"reference-tu-local-entity-in-other-tu">>;
12400+
1239412401
def warn_experimental_header_unit : Warning<
1239512402
"the implementation of header units is in an experimental phase">,
1239612403
InGroup<DiagGroup<"experimental-header-units">>;

clang/include/clang/Sema/Sema.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9945,6 +9945,20 @@ class Sema final : public SemaBase {
99459945

99469946
VisibleModuleSet VisibleModules;
99479947

9948+
/// Whether we had imported any named modules.
9949+
bool HadImportedNamedModules = false;
9950+
/// The set of instantiations we need to check if they references TU-local
9951+
/// entity from TUs. This only makes sense if we imported any named modules.
9952+
llvm::SmallVector<std::pair<FunctionDecl *, SourceLocation>>
9953+
PendingCheckReferenceForTULocal;
9954+
/// Implement [basic.link]p18, which requires that we can't use TU-local
9955+
/// entities from other TUs (ignoring header units).
9956+
void checkReferenceToTULocalFromOtherTU(FunctionDecl *FD,
9957+
SourceLocation PointOfInstantiation);
9958+
/// Implement [basic.link]p17, which diagnose for non TU local exposure in
9959+
/// module interface or module partition.
9960+
void checkExposure(const TranslationUnitDecl *TU);
9961+
99489962
///@}
99499963

99509964
//

clang/lib/Sema/Sema.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,8 @@ void Sema::ActOnEndOfTranslationUnit() {
16161616

16171617
if (!PP.isIncrementalProcessingEnabled())
16181618
TUScope = nullptr;
1619+
1620+
checkExposure(Context.getTranslationUnitDecl());
16191621
}
16201622

16211623

0 commit comments

Comments
 (0)