@@ -15837,17 +15837,18 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
15837
15837
if (TypoCorrectedFunctionDefinitions.count(Definition))
15838
15838
return;
15839
15839
15840
- // If we don't have a visible definition of the function, and it's inline or
15841
- // a template, skip the new definition.
15842
- if (SkipBody && !hasVisibleDefinition(Definition) &&
15840
+ bool DefinitionVisible = false;
15841
+ if (SkipBody && isRedefinitionAllowedFor(Definition, DefinitionVisible) &&
15843
15842
(Definition->getFormalLinkage() == Linkage::Internal ||
15844
15843
Definition->isInlined() || Definition->getDescribedFunctionTemplate() ||
15845
15844
Definition->getNumTemplateParameterLists())) {
15846
15845
SkipBody->ShouldSkip = true;
15847
15846
SkipBody->Previous = const_cast<FunctionDecl*>(Definition);
15848
- if (auto *TD = Definition->getDescribedFunctionTemplate())
15849
- makeMergedDefinitionVisible(TD);
15850
- makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition));
15847
+ if (!DefinitionVisible) {
15848
+ if (auto *TD = Definition->getDescribedFunctionTemplate())
15849
+ makeMergedDefinitionVisible(TD);
15850
+ makeMergedDefinitionVisible(const_cast<FunctionDecl *>(Definition));
15851
+ }
15851
15852
return;
15852
15853
}
15853
15854
@@ -18196,8 +18197,10 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
18196
18197
// However, ensure the decl passes the structural compatibility
18197
18198
// check in C11 6.2.7/1 (or 6.1.2.6/1 in C89).
18198
18199
NamedDecl *Hidden = nullptr;
18199
- if (SkipBody && (!hasVisibleDefinition(Def, &Hidden) ||
18200
- getLangOpts().C23)) {
18200
+ bool HiddenDefVisible = false;
18201
+ if (SkipBody &&
18202
+ (isRedefinitionAllowedFor(Def, &Hidden, HiddenDefVisible) ||
18203
+ getLangOpts().C23)) {
18201
18204
// There is a definition of this tag, but it is not visible.
18202
18205
// We explicitly make use of C++'s one definition rule here,
18203
18206
// and assume that this definition is identical to the hidden
@@ -18213,13 +18216,15 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
18213
18216
18214
18217
ProcessDeclAttributeList(S, SkipBody->New, Attrs);
18215
18218
return Def;
18216
- } else {
18217
- SkipBody->ShouldSkip = true;
18218
- SkipBody->Previous = Def;
18219
- makeMergedDefinitionVisible(Hidden);
18220
- // Carry on and handle it like a normal definition. We'll
18221
- // skip starting the definition later.
18222
18219
}
18220
+
18221
+ SkipBody->ShouldSkip = true;
18222
+ SkipBody->Previous = Def;
18223
+ if (!HiddenDefVisible && Hidden)
18224
+ makeMergedDefinitionVisible(Hidden);
18225
+ // Carry on and handle it like a normal definition. We'll
18226
+ // skip starting the definition later.
18227
+
18223
18228
} else if (!IsExplicitSpecializationAfterInstantiation) {
18224
18229
// A redeclaration in function prototype scope in C isn't
18225
18230
// visible elsewhere, so merely issue a warning.
@@ -20842,3 +20847,13 @@ bool Sema::shouldIgnoreInHostDeviceCheck(FunctionDecl *Callee) {
20842
20847
return LangOpts.CUDA && !LangOpts.CUDAIsDevice &&
20843
20848
CUDA().IdentifyTarget(Callee) == CUDAFunctionTarget::Global;
20844
20849
}
20850
+
20851
+ bool Sema::isRedefinitionAllowedFor(NamedDecl *D, NamedDecl **Suggested,
20852
+ bool &Visible) {
20853
+ Visible = hasVisibleDefinition(D, Suggested);
20854
+ // The redefinition of D in the **current** TU is allowed if D is invisible or
20855
+ // D is defined in the global module of other module units. We didn't check if
20856
+ // it is in global module as, we'll check the redefinition in named module
20857
+ // later with better diagnostic message.
20858
+ return D->isInAnotherModuleUnit() || !Visible;
20859
+ }
0 commit comments