This revision was automatically updated to reflect the committed changes. Closed by commit rL314461: [Sema] Warn on attribute nothrow conflicting with language specifiers (authored by erichkeane).
Changed prior to commit: https://reviews.llvm.org/D38205?vs=116892&id=117050#toc Repository: rL LLVM https://reviews.llvm.org/D38205 Files: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -1985,6 +1985,25 @@ Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex())); } +static void handleNoThrowAttr(Sema &S, Decl *D, const AttributeList &Attrs) { + assert(isa<FunctionDecl>(D) && "attribute nothrow only valid on functions"); + + auto *FD = cast<FunctionDecl>(D); + const auto *FPT = FD->getType()->getAs<FunctionProtoType>(); + + if (FPT && FPT->hasExceptionSpec() && + FPT->getExceptionSpecType() != EST_BasicNoexcept) { + S.Diag(Attrs.getLoc(), + diag::warn_nothrow_attr_disagrees_with_exception_specification); + S.Diag(FD->getExceptionSpecSourceRange().getBegin(), + diag::note_previous_decl) + << "exception specification"; + } + + D->addAttr(::new (S.Context) NoThrowAttr( + Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex())); +} + static void handleNoCallerSavedRegsAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (S.CheckNoCallerSavedRegsAttr(Attr)) @@ -6211,7 +6230,7 @@ handleNoReturnAttr(S, D, Attr); break; case AttributeList::AT_NoThrow: - handleSimpleAttribute<NoThrowAttr>(S, D, Attr); + handleNoThrowAttr(S, D, Attr); break; case AttributeList::AT_CUDAShared: handleSharedAttr(S, D, Attr); Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -1407,6 +1407,10 @@ "argument to noexcept specifier must be a constant expression">; def err_exception_spec_not_parsed : Error< "exception specification is not available until end of class definition">; +def warn_nothrow_attr_disagrees_with_exception_specification + : ExtWarn<"attribute 'nothrow' ignored due to conflicting exception " + "specification">, + InGroup<IgnoredAttributes>; // C++ access checking def err_class_redeclared_with_different_access : Error< Index: cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp =================================================================== --- cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp +++ cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++14 + +struct S { + //expected-warning@+2 {{attribute 'nothrow' ignored due to conflicting exception specification}} + //expected-note@+1 {{exception specification declared here}} + __attribute__((nothrow)) S() noexcept(true); + //expected-warning@+2 {{attribute 'nothrow' ignored due to conflicting exception specification}} + //expected-note@+1 {{exception specification declared here}} + __attribute__((nothrow)) void Func1() noexcept(false); + __attribute__((nothrow)) void Func3() noexcept; +}; + +void throwing() noexcept(false); +void non_throwing(bool b = true) noexcept; + +template <typename Fn> +struct T { + __attribute__((nothrow)) void f(Fn) noexcept(Fn()); +}; + +//expected-warning@-3 {{attribute 'nothrow' ignored due to conflicting exception specification}} +//expected-note@-4 {{exception specification declared here}} +template struct T<decltype(throwing)>; +template struct T<decltype(non_throwing)>;
Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -1985,6 +1985,25 @@ Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex())); } +static void handleNoThrowAttr(Sema &S, Decl *D, const AttributeList &Attrs) { + assert(isa<FunctionDecl>(D) && "attribute nothrow only valid on functions"); + + auto *FD = cast<FunctionDecl>(D); + const auto *FPT = FD->getType()->getAs<FunctionProtoType>(); + + if (FPT && FPT->hasExceptionSpec() && + FPT->getExceptionSpecType() != EST_BasicNoexcept) { + S.Diag(Attrs.getLoc(), + diag::warn_nothrow_attr_disagrees_with_exception_specification); + S.Diag(FD->getExceptionSpecSourceRange().getBegin(), + diag::note_previous_decl) + << "exception specification"; + } + + D->addAttr(::new (S.Context) NoThrowAttr( + Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex())); +} + static void handleNoCallerSavedRegsAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (S.CheckNoCallerSavedRegsAttr(Attr)) @@ -6211,7 +6230,7 @@ handleNoReturnAttr(S, D, Attr); break; case AttributeList::AT_NoThrow: - handleSimpleAttribute<NoThrowAttr>(S, D, Attr); + handleNoThrowAttr(S, D, Attr); break; case AttributeList::AT_CUDAShared: handleSharedAttr(S, D, Attr); Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -1407,6 +1407,10 @@ "argument to noexcept specifier must be a constant expression">; def err_exception_spec_not_parsed : Error< "exception specification is not available until end of class definition">; +def warn_nothrow_attr_disagrees_with_exception_specification + : ExtWarn<"attribute 'nothrow' ignored due to conflicting exception " + "specification">, + InGroup<IgnoredAttributes>; // C++ access checking def err_class_redeclared_with_different_access : Error< Index: cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp =================================================================== --- cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp +++ cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++14 + +struct S { + //expected-warning@+2 {{attribute 'nothrow' ignored due to conflicting exception specification}} + //expected-note@+1 {{exception specification declared here}} + __attribute__((nothrow)) S() noexcept(true); + //expected-warning@+2 {{attribute 'nothrow' ignored due to conflicting exception specification}} + //expected-note@+1 {{exception specification declared here}} + __attribute__((nothrow)) void Func1() noexcept(false); + __attribute__((nothrow)) void Func3() noexcept; +}; + +void throwing() noexcept(false); +void non_throwing(bool b = true) noexcept; + +template <typename Fn> +struct T { + __attribute__((nothrow)) void f(Fn) noexcept(Fn()); +}; + +//expected-warning@-3 {{attribute 'nothrow' ignored due to conflicting exception specification}} +//expected-note@-4 {{exception specification declared here}} +template struct T<decltype(throwing)>; +template struct T<decltype(non_throwing)>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits