Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3267,6 +3267,14 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
if (isa<UsedAttr>(I) || isa<RetainAttr>(I))
continue;

if (isa<InferredNoReturnAttr>(I)) {
if (auto *FD = dyn_cast<FunctionDecl>(New)) {
if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
continue; // Don't propagate inferred noreturn attributes to explicit
// specializations.
}
}

if (mergeDeclAttribute(*this, New, I, LocalAMK))
foundAny = true;
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1970,6 +1970,9 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) {
if (!FD)
return;

if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
return; // Don't infer noreturn for explicit specializations.

auto *NonConstFD = const_cast<FunctionDecl *>(FD);
DiagnosticsEngine &Diags = S.getDiagnostics();
if (Diags.isIgnored(diag::warn_falloff_nonvoid, FD->getLocation()) &&
Expand Down
15 changes: 15 additions & 0 deletions clang/test/SemaCXX/wreturn-always-throws.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,18 @@ void testTemplates() {
throwErrorTemplate("ERROR");
(void)ensureZeroTemplate(42);
}

// Ensure that explicit specialization of a member function does not inherit
// the warning from the primary template.

template<typename T>
struct S {
void f();
};

template<typename T>
void S<T>::f() { throw 0; }
template<>
void S<int>::f() {} // expected-no-diagnostics