r314461 - [Sema] Warn on attribute nothrow conflicting with language specifiers

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 28 13:36:54 PDT 2017


Author: erichkeane
Date: Thu Sep 28 13:36:53 2017
New Revision: 314461

URL: http://llvm.org/viewvc/llvm-project?rev=314461&view=rev
Log:
[Sema] Warn on attribute nothrow conflicting with language specifiers

I discovered it was possible to create a 'nothrow' noexcept(false)
function, which is both non-sensical as well as seemingly breaking.

This patch warns if attribute nothrow is used with anything besides "noexcept".

"noexcept(true)" isn't possible, because the noexcept decl isn't parsed until
later.

Differential Revision: https://reviews.llvm.org/D38205

Added:
    cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp   (with props)
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=314461&r1=314460&r2=314461&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 28 13:36:53 2017
@@ -1407,6 +1407,10 @@ def err_noexcept_needs_constant_expressi
   "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<

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=314461&r1=314460&r2=314461&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Sep 28 13:36:53 2017
@@ -1985,6 +1985,25 @@ static void handleNoReturnAttr(Sema &S,
       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 @@ static void ProcessDeclAttribute(Sema &S
     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);

Added: cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp?rev=314461&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp (added)
+++ cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp Thu Sep 28 13:36:53 2017
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -fcxx-exceptions -fsyntax-only -Wexceptions -verify -std=c++14
+
+struct S {
+  //expected-warning at +2 {{attribute 'nothrow' ignored due to conflicting exception specification}}
+  //expected-note at +1 {{exception specification declared here}}
+  __attribute__((nothrow)) S() noexcept(true);
+  //expected-warning at +2 {{attribute 'nothrow' ignored due to conflicting exception specification}}
+  //expected-note at +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 at -3 {{attribute 'nothrow' ignored due to conflicting exception specification}}
+//expected-note at -4 {{exception specification declared here}}
+template struct T<decltype(throwing)>;
+template struct T<decltype(non_throwing)>;

Propchange: cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: cfe/trunk/test/SemaCXX/warn-conflicting-nothrow-attr-exception-spec.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the cfe-commits mailing list