Skip to content

Commit 5adb4f5

Browse files
committed
de-duplicating warning emission for template instantiations
1 parent 730562b commit 5adb4f5

File tree

7 files changed

+72
-37
lines changed

7 files changed

+72
-37
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6477,14 +6477,34 @@ static bool shouldDiagnoseMissingReturnsRetained(const clang::NamedDecl *ND,
64776477
return isa<clang::ObjCMethodDecl>(ND);
64786478
}
64796479

6480+
static const clang::FunctionDecl *
6481+
getDiagnosticTarget(const clang::NamedDecl *ND) {
6482+
if (auto *FD = dyn_cast<clang::FunctionDecl>(ND)) {
6483+
if (FD->isTemplateInstantiation()) {
6484+
if (const auto *pattern = FD->getTemplateInstantiationPattern())
6485+
return pattern;
6486+
}
6487+
return FD;
6488+
}
6489+
return nullptr;
6490+
}
6491+
64806492
// Diagnose calls to imported C++ functions that return `SWIFT_SHARED_REFERENCE`
64816493
// types without explicit ownership annotations SWIFT_RETURNS_(UN)RETAINED
64826494
static void diagnoseCxxFunctionCalls(const Expr *E, const DeclContext *DC) {
6495+
static llvm::SmallPtrSet<const clang::FunctionDecl *, 8>
6496+
DiagnosedTemplatePatterns;
6497+
64836498
class DiagnoseWalker : public BaseDiagnosticWalker {
64846499
ASTContext &Ctx;
6500+
llvm::SmallPtrSet<const clang::FunctionDecl *, 8>
6501+
&DiagnosedTemplatePatterns;
64856502

64866503
public:
6487-
DiagnoseWalker(ASTContext &ctx) : Ctx(ctx) {}
6504+
DiagnoseWalker(
6505+
ASTContext &ctx,
6506+
llvm::SmallPtrSet<const clang::FunctionDecl *, 8> &diagnosedPatterns)
6507+
: Ctx(ctx), DiagnosedTemplatePatterns(diagnosedPatterns) {}
64886508

64896509
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
64906510
if (!E)
@@ -6498,7 +6518,11 @@ static void diagnoseCxxFunctionCalls(const Expr *E, const DeclContext *DC) {
64986518
if (!func)
64996519
return Action::Continue(E);
65006520

6501-
auto *ND = dyn_cast_or_null<clang::NamedDecl>(func->getClangDecl());
6521+
auto *clangDecl = func->getClangDecl();
6522+
if (!clangDecl)
6523+
return Action::Continue(E);
6524+
6525+
auto *ND = dyn_cast<clang::NamedDecl>(clangDecl);
65026526
if (!ND)
65036527
return Action::Continue(E);
65046528

@@ -6507,9 +6531,17 @@ static void diagnoseCxxFunctionCalls(const Expr *E, const DeclContext *DC) {
65076531
return Action::Continue(E);
65086532

65096533
if (shouldDiagnoseMissingReturnsRetained(ND, retType, Ctx)) {
6510-
Ctx.Diags.diagnose(func->getLoc(),
6511-
diag::warn_unannotated_cxx_func_returning_frt,
6512-
const_cast<ValueDecl *>(func));
6534+
bool shouldEmitWarning = true;
6535+
if (const auto *diagnosticTarget = getDiagnosticTarget(ND))
6536+
shouldEmitWarning =
6537+
DiagnosedTemplatePatterns.insert(diagnosticTarget).second;
6538+
6539+
if (shouldEmitWarning) {
6540+
Ctx.Diags.diagnose(func->getLoc(),
6541+
diag::warn_unannotated_cxx_func_returning_frt,
6542+
const_cast<ValueDecl *>(func));
6543+
}
6544+
65136545
Ctx.Diags.diagnose(CE->getLoc(),
65146546
diag::note_unannotated_cxx_func_returning_frt,
65156547
const_cast<ValueDecl *>(func));
@@ -6519,7 +6551,7 @@ static void diagnoseCxxFunctionCalls(const Expr *E, const DeclContext *DC) {
65196551
}
65206552
};
65216553

6522-
DiagnoseWalker walker(DC->getASTContext());
6554+
DiagnoseWalker walker(DC->getASTContext(), DiagnosedTemplatePatterns);
65236555
const_cast<Expr *>(E)->walk(walker);
65246556
}
65256557

test/Interop/Cxx/foreign-reference/Inputs/cxx-functions-and-methods-returning-frt.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,12 @@ __attribute__((swift_attr("unsafe")));
179179

180180
// C++ APIs returning cxx frts (for testing diagnostics)
181181
struct StructWithAPIsReturningCxxFrt {
182-
static FRTStruct *_Nonnull StaticMethodReturningCxxFrt(); // expected-warning {{'StaticMethodReturningCxxFrt' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
182+
static FRTStruct *_Nonnull StaticMethodReturningCxxFrt(); // expected-warning {{'StaticMethodReturningCxxFrt()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
183183
static FRTStruct *_Nonnull StaticMethodReturningCxxFrtWithAnnotation()
184184
__attribute__((swift_attr("returns_retained")));
185185
};
186186

187-
FRTStruct *_Nonnull global_function_returning_cxx_frt(); // expected-warning {{'global_function_returning_cxx_frt' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
187+
FRTStruct *_Nonnull global_function_returning_cxx_frt(); // expected-warning {{'global_function_returning_cxx_frt()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
188188
FRTStruct *_Nonnull global_function_returning_cxx_frt_with_annotations()
189189
__attribute__((swift_attr("returns_retained")));
190190

@@ -303,7 +303,7 @@ __attribute__((swift_attr(
303303
operator-(const FRTOverloadedOperators &other);
304304
};
305305

306-
FRTOverloadedOperators *_Nonnull returnFRTOverloadedOperators(); // expected-warning {{'returnFRTOverloadedOperators' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
306+
FRTOverloadedOperators *_Nonnull returnFRTOverloadedOperators(); // expected-warning {{'returnFRTOverloadedOperators()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
307307

308308
void retain_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);
309309
void release_FRTOverloadedOperators(FRTOverloadedOperators *_Nonnull v);
@@ -371,7 +371,7 @@ struct __attribute__((swift_attr("import_reference")))
371371
__attribute__((swift_attr("retain:rretain")))
372372
__attribute__((swift_attr("release:rrelease"))) RefType {};
373373

374-
RefType *returnRefType() { return new RefType(); } // expected-warning {{'returnRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
374+
RefType *returnRefType() { return new RefType(); } // expected-warning {{'returnRefType()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
375375

376376
struct __attribute__((swift_attr("import_reference")))
377377
__attribute__((swift_attr("retain:dretain")))
@@ -420,10 +420,10 @@ __attribute__((swift_attr("retain:dRetain")))
420420
__attribute__((swift_attr("release:dRelease"))) DerivedTypeNonDefault
421421
: public BaseTypeNonDefault {};
422422

423-
BaseTypeNonDefault *createBaseTypeNonDefault() { // expected-warning {{'createBaseTypeNonDefault' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
423+
BaseTypeNonDefault *createBaseTypeNonDefault() { // expected-warning {{'createBaseTypeNonDefault()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
424424
return new BaseTypeNonDefault();
425425
}
426-
DerivedTypeNonDefault *createDerivedTypeNonDefault() { // expected-warning {{'createDerivedTypeNonDefault' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
426+
DerivedTypeNonDefault *createDerivedTypeNonDefault() { // expected-warning {{'createDerivedTypeNonDefault()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
427427
return new DerivedTypeNonDefault();
428428
}
429429

@@ -464,7 +464,7 @@ __attribute__((swift_attr("release:release_SourceLocCacheB"))) TypeB {};
464464

465465
template <typename T>
466466
struct Factory {
467-
static T *make() { return new T(); } // expected-warning {{'make' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
467+
static T *make() { return new T(); } // expected-warning {{'make()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
468468
};
469469

470470
using FactoryA = Factory<TypeA>;

test/Interop/Cxx/foreign-reference/Inputs/inheritance.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ __attribute__((swift_attr("release:immortal"))) ImmortalRefType {};
109109
ImmortalRefType *returnImmortalRefType() { return new ImmortalRefType(); };
110110

111111
struct DerivedFromImmortalRefType : ImmortalRefType {};
112-
DerivedFromImmortalRefType *returnDerivedFromImmortalRefType() { // expected-warning {{'returnDerivedFromImmortalRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
112+
DerivedFromImmortalRefType *returnDerivedFromImmortalRefType() { // expected-warning {{'returnDerivedFromImmortalRefType()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
113113
return new DerivedFromImmortalRefType();
114114
};
115115

@@ -122,7 +122,7 @@ ValueType *returnValueType() { return new ValueType(); }
122122
struct __attribute__((swift_attr("import_reference")))
123123
__attribute__((swift_attr("retain:ret1")))
124124
__attribute__((swift_attr("release:rel1"))) RefType {};
125-
RefType *returnRefType() { return new RefType(); } // expected-warning {{'returnRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
125+
RefType *returnRefType() { return new RefType(); } // expected-warning {{'returnRefType()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
126126

127127
struct DerivedFromValueType : ValueType {};
128128
DerivedFromValueType *returnDerivedFromValueType() {
@@ -133,20 +133,20 @@ struct __attribute__((swift_attr("import_reference")))
133133
__attribute__((swift_attr("retain:ret2")))
134134
__attribute__((swift_attr("release:rel2"))) DerivedFromValueTypeAndAnnotated
135135
: ValueType {};
136-
DerivedFromValueTypeAndAnnotated *returnDerivedFromValueTypeAndAnnotated() { // expected-warning {{'returnDerivedFromValueTypeAndAnnotated' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
136+
DerivedFromValueTypeAndAnnotated *returnDerivedFromValueTypeAndAnnotated() { // expected-warning {{'returnDerivedFromValueTypeAndAnnotated()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
137137
return new DerivedFromValueTypeAndAnnotated();
138138
}
139139

140140
struct DerivedFromRefType final : RefType {};
141-
DerivedFromRefType *returnDerivedFromRefType() { // expected-warning {{'returnDerivedFromRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
141+
DerivedFromRefType *returnDerivedFromRefType() { // expected-warning {{'returnDerivedFromRefType()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
142142
return new DerivedFromRefType();
143143
}
144144

145145
struct __attribute__((swift_attr("import_reference")))
146146
__attribute__((swift_attr("retain:ret3")))
147147
__attribute__((swift_attr("release:rel3"))) DerivedFromRefTypeAndAnnotated
148148
: RefType {};
149-
DerivedFromRefTypeAndAnnotated *returnDerivedFromRefTypeAndAnnotated() { // expected-warning {{'returnDerivedFromRefTypeAndAnnotated' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
149+
DerivedFromRefTypeAndAnnotated *returnDerivedFromRefTypeAndAnnotated() { // expected-warning {{'returnDerivedFromRefTypeAndAnnotated()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
150150
return new DerivedFromRefTypeAndAnnotated();
151151
}
152152
} // namespace ExplicitAnnotationHasPrecedence1
@@ -184,7 +184,7 @@ __attribute__((swift_attr("retain:retain_C")))
184184
__attribute__((swift_attr("release:release_C"))) DerivedFromRefTypeAAndBAnnotated
185185
: RefTypeA,
186186
RefTypeB {};
187-
DerivedFromRefTypeAAndBAnnotated *returnDerivedFromRefTypeAAndBAnnotated() { // expected-warning {{'returnDerivedFromRefTypeAAndBAnnotated' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
187+
DerivedFromRefTypeAAndBAnnotated *returnDerivedFromRefTypeAAndBAnnotated() { // expected-warning {{'returnDerivedFromRefTypeAAndBAnnotated()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
188188
return new DerivedFromRefTypeAAndBAnnotated();
189189
}
190190
} // namespace ExplicitAnnotationHasPrecedence2
@@ -206,10 +206,10 @@ struct __attribute__((swift_attr("import_reference")))
206206
__attribute__((swift_attr("retain:RCRetain")))
207207
__attribute__((swift_attr("release:RCRelease"))) RefType {};
208208

209-
RefType *returnRefType() { return new RefType(); }; // expected-warning {{'returnRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENC}}
209+
RefType *returnRefType() { return new RefType(); }; // expected-warning {{'returnRefType()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENC}}
210210

211211
struct DerivedFromRefType final : RefType {};
212-
DerivedFromRefType *returnDerivedFromRefType() { // expected-warning {{'returnDerivedFromRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
212+
DerivedFromRefType *returnDerivedFromRefType() { // expected-warning {{'returnDerivedFromRefType()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
213213
return new DerivedFromRefType();
214214
};
215215
} // namespace BasicInheritanceExample
@@ -236,7 +236,7 @@ DerivedFromBaseRef1AndBaseRef2 *returnDerivedFromBaseRef1AndBaseRef2() {
236236
};
237237

238238
struct DerivedFromBaseRef3 : BaseRef3 {};
239-
DerivedFromBaseRef3 *returnDerivedFromBaseRef3() { // expected-warning {{'returnDerivedFromBaseRef3' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
239+
DerivedFromBaseRef3 *returnDerivedFromBaseRef3() { // expected-warning {{'returnDerivedFromBaseRef3()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
240240
return new DerivedFromBaseRef3();
241241
};
242242
} // namespace MultipleInheritanceExample1
@@ -312,7 +312,7 @@ __attribute__((swift_attr("release:samerelease"))) B2 {}; // expected-error {{m
312312

313313
struct D : B1, B2 {}; // expected-error {{multiple functions 'sameretain' found; there must be exactly one retain function for reference type 'D'}}
314314
// expected-error@-1 {{multiple functions 'samerelease' found; there must be exactly one release function for reference type 'D'}}
315-
D *returnD() { return new D(); }; // expected-warning {{'returnD' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
315+
D *returnD() { return new D(); }; // expected-warning {{'returnD()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
316316
} // namespace OverloadedRetainRelease
317317

318318
void sameretain(OverloadedRetainRelease::B1 *v) {}
@@ -339,7 +339,7 @@ struct BVirtual : virtual A {};
339339
struct CVirtual : virtual A {};
340340

341341
struct VirtualDiamond : BVirtual, CVirtual {};
342-
VirtualDiamond *returnVirtualDiamond() { return new VirtualDiamond(); }; // expected-warning {{'returnVirtualDiamond' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
342+
VirtualDiamond *returnVirtualDiamond() { return new VirtualDiamond(); }; // expected-warning {{'returnVirtualDiamond()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
343343
} // namespace RefTypeDiamondInheritance
344344

345345
void retainA(RefTypeDiamondInheritance::A *a) {};
@@ -355,7 +355,7 @@ __attribute__((swift_attr("release:releaseB"))) B : A {};
355355
struct C : A {};
356356

357357
struct Diamond : B, C {};
358-
Diamond *returnDiamond() { return new Diamond(); }; // expected-warning {{'returnDiamond' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
358+
Diamond *returnDiamond() { return new Diamond(); }; // expected-warning {{'returnDiamond()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
359359

360360
} // namespace NonRefTypeDiamondInheritance
361361

@@ -384,7 +384,7 @@ __attribute__((swift_attr("retain:forestRetain"))) __attribute__((
384384
};
385385

386386
class Forest : public IntrusiveRefCountedTemplate<Forest> {};
387-
Forest *returnForest() { return new Forest(); }; // expected-warning {{'returnForest' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
387+
Forest *returnForest() { return new Forest(); }; // expected-warning {{'returnForest()' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it returns a SWIFT_SHARED_REFERENCE}}
388388
} // namespace InheritingTemplatedRefType
389389

390390
void forestRetain(InheritingTemplatedRefType::IntrusiveRefCountedTemplate<

0 commit comments

Comments
 (0)