r362119 - Add Attribute NoThrow as an Exception Specifier Type
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Thu May 30 18:14:40 PDT 2019
Hello,
this causes this diagnostic when building on Windows:
In file included from
../../ui/accessibility/platform/ax_platform_node_textchildprovider_win.cc:10:
../..\ui/accessibility/platform/ax_platform_node_textprovider_win.h(22,3):
error: 'nothrow' attribute conflicts with exception specification;
attribute ignored [-Werror,-Wignored-attributes]
END_COM_MAP()
^
..\..\third_party\depot_tools\win_toolchain\vs_files\
818a152b3f1da991c1725d85be19a0f27af6bab4\VC\Tools\MSVC\14.16.27023\atlmfc\include\atlcom.h(2358,2):
note: expanded from macro 'END_COM_MAP'
STDMETHOD(QueryInterface)( \
^
..\..\third_party\depot_tools\win_toolchain\vs_files\
818a152b3f1da991c1725d85be19a0f27af6bab4\win_sdk\Include\10.0.17763.0\um\combaseapi.h(170,42):
note: expanded from macro 'STDMETHOD'
#define STDMETHOD(method) virtual COM_DECLSPEC_NOTHROW HRESULT
STDMETHODCALLTYPE method
^
..\..\third_party\depot_tools\win_toolchain\vs_files\
818a152b3f1da991c1725d85be19a0f27af6bab4\win_sdk\Include\10.0.17763.0\um\combaseapi.h(165,30):
note: expanded from macro 'COM_DECLSPEC_NOTHROW'
#define COM_DECLSPEC_NOTHROW DECLSPEC_NOTHROW
^
..\..\third_party\depot_tools\win_toolchain\vs_files\
818a152b3f1da991c1725d85be19a0f27af6bab4\win_sdk\Include\10.0.17763.0\um\winnt.h(200,39):
note: expanded from macro 'DECLSPEC_NOTHROW'
#define DECLSPEC_NOTHROW __declspec(nothrow)
^
Suggestions? We don't want to use -Wno-ignored-attributes since that
disables this warning for all attributes.
All the involved macros are in system headers and we have no control over
them.
On Thu, May 30, 2019 at 1:28 PM Erich Keane via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: erichkeane
> Date: Thu May 30 10:31:54 2019
> New Revision: 362119
>
> URL: http://llvm.org/viewvc/llvm-project?rev=362119&view=rev
> Log:
> Add Attribute NoThrow as an Exception Specifier Type
>
> In response to https://bugs.llvm.org/show_bug.cgi?id=33235, it became
> clear that the current mechanism of hacking through checks for the
> exception specification of a function gets confused really quickly when
> there are alternate exception specifiers.
>
> This patch introcues EST_NoThrow, which is the equivilent of
> EST_noexcept when caused by EST_noThrow. The existing implementation is
> left in place to cover functions with no FunctionProtoType.
>
> Differential Revision: https://reviews.llvm.org/D62435
>
> Added:
> cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp (with props)
> Modified:
> cfe/trunk/include/clang-c/Index.h
> cfe/trunk/include/clang/AST/Decl.h
> cfe/trunk/include/clang/AST/Type.h
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/include/clang/Basic/ExceptionSpecificationType.h
> cfe/trunk/lib/AST/ASTContext.cpp
> cfe/trunk/lib/AST/JSONNodeDumper.cpp
> cfe/trunk/lib/AST/Type.cpp
> cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> cfe/trunk/lib/Sema/SemaExprCXX.cpp
> cfe/trunk/lib/Sema/SemaType.cpp
> cfe/trunk/tools/libclang/CXType.cpp
>
> Modified: cfe/trunk/include/clang-c/Index.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang-c/Index.h (original)
> +++ cfe/trunk/include/clang-c/Index.h Thu May 30 10:31:54 2019
> @@ -32,7 +32,7 @@
> * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
> */
> #define CINDEX_VERSION_MAJOR 0
> -#define CINDEX_VERSION_MINOR 57
> +#define CINDEX_VERSION_MINOR 58
>
> #define CINDEX_VERSION_ENCODE(major, minor) ( \
> ((major) * 10000) \
> @@ -221,7 +221,12 @@ enum CXCursor_ExceptionSpecificationKind
> /**
> * The exception specification has not been parsed yet.
> */
> - CXCursor_ExceptionSpecificationKind_Unparsed
> + CXCursor_ExceptionSpecificationKind_Unparsed,
> +
> + /**
> + * The cursor has a __declspec(nothrow) exception specification.
> + */
> + CXCursor_ExceptionSpecificationKind_NoThrow
> };
>
> /**
>
> Modified: cfe/trunk/include/clang/AST/Decl.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Decl.h (original)
> +++ cfe/trunk/include/clang/AST/Decl.h Thu May 30 10:31:54 2019
> @@ -2330,6 +2330,14 @@ public:
> return T->castAs<FunctionType>()->getReturnType();
> }
>
> + /// Gets the ExceptionSpecificationType as declared.
> + ExceptionSpecificationType getExceptionSpecType() const {
> + auto *TSI = getTypeSourceInfo();
> + QualType T = TSI ? TSI->getType() : getType();
> + const auto *FPT = T->getAs<FunctionProtoType>();
> + return FPT ? FPT->getExceptionSpecType() : EST_None;
> + }
> +
> /// Attempt to compute an informative source range covering the
> /// function exception specification, if any.
> SourceRange getExceptionSpecSourceRange() const;
>
> Modified: cfe/trunk/include/clang/AST/Type.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Type.h (original)
> +++ cfe/trunk/include/clang/AST/Type.h Thu May 30 10:31:54 2019
> @@ -3855,6 +3855,7 @@ private:
> case EST_MSAny:
> case EST_BasicNoexcept:
> case EST_Unparsed:
> + case EST_NoThrow:
> return {0, 0, 0};
>
> case EST_Dynamic:
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 30
> 10:31:54 2019
> @@ -2792,6 +2792,9 @@ def warn_dllimport_dropped_from_inline_f
> InGroup<IgnoredAttributes>;
> def warn_attribute_ignored : Warning<"%0 attribute ignored">,
> InGroup<IgnoredAttributes>;
> +def warn_nothrow_attribute_ignored : Warning<"'nothrow' attribute
> conflicts with"
> + " exception specification; attribute ignored">,
> + InGroup<IgnoredAttributes>;
> def warn_attribute_ignored_on_inline :
> Warning<"%0 attribute ignored on inline function">,
> InGroup<IgnoredAttributes>;
>
> Modified: cfe/trunk/include/clang/Basic/ExceptionSpecificationType.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/ExceptionSpecificationType.h?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/ExceptionSpecificationType.h (original)
> +++ cfe/trunk/include/clang/Basic/ExceptionSpecificationType.h Thu May 30
> 10:31:54 2019
> @@ -22,6 +22,7 @@ enum ExceptionSpecificationType {
> EST_DynamicNone, ///< throw()
> EST_Dynamic, ///< throw(T1, T2)
> EST_MSAny, ///< Microsoft throw(...) extension
> + EST_NoThrow, ///< Microsoft __declspec(nothrow) extension
> EST_BasicNoexcept, ///< noexcept
> EST_DependentNoexcept,///< noexcept(expression), value-dependent
> EST_NoexceptFalse, ///< noexcept(expression), evals to 'false'
> @@ -41,7 +42,8 @@ inline bool isComputedNoexcept(Exception
> }
>
> inline bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
> {
> - return ESpecType == EST_BasicNoexcept || isComputedNoexcept(ESpecType);
> + return ESpecType == EST_BasicNoexcept || ESpecType == EST_NoThrow ||
> + isComputedNoexcept(ESpecType);
> }
>
> inline bool isUnresolvedExceptionSpec(ExceptionSpecificationType
> ESpecType) {
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Thu May 30 10:31:54 2019
> @@ -3742,7 +3742,10 @@ QualType ASTContext::getFunctionTypeInte
> break;
> }
>
> - case EST_DynamicNone: case EST_BasicNoexcept: case EST_NoexceptTrue:
> + case EST_DynamicNone:
> + case EST_BasicNoexcept:
> + case EST_NoexceptTrue:
> + case EST_NoThrow:
> CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept;
> break;
>
>
> Modified: cfe/trunk/lib/AST/JSONNodeDumper.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/JSONNodeDumper.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/JSONNodeDumper.cpp (original)
> +++ cfe/trunk/lib/AST/JSONNodeDumper.cpp Thu May 30 10:31:54 2019
> @@ -464,7 +464,9 @@ void JSONNodeDumper::VisitFunctionProtoT
> //JOS.attributeWithCall("exceptionSpecExpr",
> // [this, E]() {
> Visit(E.ExceptionSpec.NoexceptExpr); });
> break;
> -
> + case EST_NoThrow:
> + JOS.attribute("exceptionSpec", "nothrow");
> + break;
> // FIXME: I cannot find a way to trigger these cases while dumping the
> AST. I
> // suspect you can only run into them when executing an AST dump from
> within
> // the debugger, which is not a use case we worry about for the JSON
> dumping
>
> Modified: cfe/trunk/lib/AST/Type.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/Type.cpp (original)
> +++ cfe/trunk/lib/AST/Type.cpp Thu May 30 10:31:54 2019
> @@ -3077,6 +3077,7 @@ CanThrowResult FunctionProtoType::canThr
> case EST_DynamicNone:
> case EST_BasicNoexcept:
> case EST_NoexceptTrue:
> + case EST_NoThrow:
> return CT_Cannot;
>
> case EST_None:
>
> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu May 30 10:31:54 2019
> @@ -6853,7 +6853,8 @@ static void ProcessDeclAttribute(Sema &S
> handleNoCfCheckAttr(S, D, AL);
> break;
> case ParsedAttr::AT_NoThrow:
> - handleSimpleAttribute<NoThrowAttr>(S, D, AL);
> + if (!AL.isUsedAsTypeAttr())
> + handleSimpleAttribute<NoThrowAttr>(S, D, AL);
> break;
> case ParsedAttr::AT_CUDAShared:
> handleSharedAttr(S, D, AL);
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu May 30 10:31:54 2019
> @@ -192,6 +192,7 @@ Sema::ImplicitExceptionSpecification::Ca
> // If this function has a basic noexcept, it doesn't affect the outcome.
> case EST_BasicNoexcept:
> case EST_NoexceptTrue:
> + case EST_NoThrow:
> return;
> // If we're still at noexcept(true) and there's a throw() callee,
> // change to that specification.
> @@ -15457,6 +15458,7 @@ bool Sema::checkThisInStaticMemberFuncti
> case EST_Uninstantiated:
> case EST_Unevaluated:
> case EST_BasicNoexcept:
> + case EST_NoThrow:
> case EST_DynamicNone:
> case EST_MSAny:
> case EST_None:
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu May 30 10:31:54 2019
> @@ -6045,6 +6045,8 @@ mergeExceptionSpecs(Sema &S, FunctionPro
> if (EST2 == EST_NoexceptFalse) return ESI2;
>
> // If either of them is non-throwing, the result is the other.
> + if (EST1 == EST_NoThrow) return ESI2;
> + if (EST2 == EST_NoThrow) return ESI1;
> if (EST1 == EST_DynamicNone) return ESI2;
> if (EST2 == EST_DynamicNone) return ESI1;
> if (EST1 == EST_BasicNoexcept) return ESI2;
> @@ -6073,6 +6075,7 @@ mergeExceptionSpecs(Sema &S, FunctionPro
> case EST_DependentNoexcept:
> case EST_NoexceptFalse:
> case EST_NoexceptTrue:
> + case EST_NoThrow:
> llvm_unreachable("handled above");
>
> case EST_Dynamic: {
>
> Modified: cfe/trunk/lib/Sema/SemaType.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaType.cpp Thu May 30 10:31:54 2019
> @@ -130,6 +130,7 @@ static void diagnoseBadTypeAttribute(Sem
> case ParsedAttr::AT_Regparm:
> \
> case ParsedAttr::AT_AnyX86NoCallerSavedRegisters:
> \
> case ParsedAttr::AT_AnyX86NoCfCheck:
> \
> + case ParsedAttr::AT_NoThrow:
> \
> CALLING_CONV_ATTRS_CASELIST
>
> // Microsoft-specific type qualifiers.
> @@ -4516,7 +4517,7 @@ static TypeSourceInfo *GetFullTypeForDec
> // If the function declarator has a prototype (i.e. it is not () and
> // does not have a K&R-style identifier list), then the arguments
> are part
> // of the type, otherwise the argument list is ().
> - const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
> + DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
> IsQualifiedFunction =
> FTI.hasMethodTypeQualifiers() || FTI.hasRefQualifier();
>
> @@ -6945,6 +6946,61 @@ static bool handleFunctionTypeAttr(TypeP
> return true;
> }
>
> + if (attr.getKind() == ParsedAttr::AT_NoThrow) {
> + if (S.CheckAttrNoArgs(attr))
> + return true;
> +
> + // Delay if this is not a function type.
> + if (!unwrapped.isFunctionType())
> + return false;
> +
> + // Otherwise we can process right away.
> + auto *Proto = unwrapped.get()->getAs<FunctionProtoType>();
> +
> + // In the case where this is a FunctionNoProtoType instead of a
> + // FunctionProtoType, let the existing NoThrowAttr implementation do
> its
> + // thing.
> + if (!Proto)
> + return false;
> +
> + attr.setUsedAsTypeAttr();
> +
> + // MSVC ignores nothrow if it is in conflict with an explicit
> exception
> + // specification.
> + if (Proto->hasExceptionSpec()) {
> + switch (Proto->getExceptionSpecType()) {
> + case EST_None:
> + llvm_unreachable("This doesn't have an exception spec!");
> + LLVM_FALLTHROUGH;
> + case EST_DynamicNone:
> + case EST_BasicNoexcept:
> + case EST_NoexceptTrue:
> + case EST_NoThrow:
> + // Exception spec doesn't conflict with nothrow, so don't warn.
> + break;
> +
> + case EST_Dynamic:
> + case EST_MSAny:
> + case EST_NoexceptFalse:
> + case EST_DependentNoexcept:
> + case EST_Unevaluated:
> + case EST_Uninstantiated:
> + case EST_Unparsed:
> + S.Diag(attr.getLoc(), diag::warn_nothrow_attribute_ignored);
> + break;
> + }
> + return true;
> + }
> +
> + type = unwrapped.wrap(
> + S, S.Context
> + .getFunctionTypeWithExceptionSpec(
> + QualType{Proto, 0},
> + FunctionProtoType::ExceptionSpecInfo{EST_NoThrow})
> + ->getAs<FunctionType>());
> + return true;
> + }
> +
> // Delay if the type didn't work out to a function.
> if (!unwrapped.isFunctionType()) return false;
>
>
> Added: cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp?rev=362119&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp (added)
> +++ cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp Thu May 30
> 10:31:54 2019
> @@ -0,0 +1,55 @@
> +// RUN: %clang_cc1 %s -fcxx-exceptions -fdeclspec -fsyntax-only
> -Wexceptions -verify -std=c++14
> +// RUN: %clang_cc1 %s -fcxx-exceptions -fdeclspec -fsyntax-only
> -Wexceptions -verify -std=c++17 -DCPP17
> +
> +__attribute__((nothrow)) void f1();
> +static_assert(noexcept(f1()), "");
> +void f1() noexcept;
> +// expected-error at +2 {{exception specification in declaration does not
> match previous declaration}}
> +// expected-note at -2 {{previous declaration is here}}
> +void f1() noexcept(false);
> +
> +__attribute__((nothrow)) void f2();
> +static_assert(noexcept(f2()), "");
> +// expected-error at +2 {{exception specification in declaration does not
> match previous declaration}}
> +// expected-note at -3 {{previous declaration is here}}
> +void f2() noexcept(false);
> +
> +void f3() __attribute__((nothrow));
> +static_assert(noexcept(f3()), "");
> +void f3() noexcept;
> +// expected-error at +2 {{exception specification in declaration does not
> match previous declaration}}
> +// expected-note at -2 {{previous declaration is here}}
> +void f3() noexcept(false);
> +
> +// Still noexcept due to throw()
> +__attribute__((nothrow)) void f4() throw();
> +static_assert(noexcept(f4()), "");
> +
> +// Still noexcept due to noexcept
> +__attribute__((nothrow)) void f5() noexcept;
> +static_assert(noexcept(f5()), "");
> +
> +// Still noexcept due to noexcept(true)
> +__attribute__((nothrow)) void f6() noexcept(true);
> +static_assert(noexcept(f6()), "");
> +
> +#ifndef CPP17
> +// Doesn't override C++ implementation.
> +// expected-warning at +1{{'nothrow' attribute conflicts with exception
> specification; attribute ignored}}
> +__attribute__((nothrow)) void f7() throw(int);
> +static_assert(!noexcept(f7()), "");
> +#endif
> +
> +// Doesn't override C++ implementation.
> +// expected-warning at +1{{'nothrow' attribute conflicts with exception
> specification; attribute ignored}}
> +__attribute__((nothrow)) void f8() noexcept(false);
> +static_assert(!noexcept(f8()), "");
> +
> +__declspec(nothrow) void foo1() noexcept;
> +__declspec(nothrow) void foo2() noexcept(true);
> +// expected-warning at +1{{'nothrow' attribute conflicts with exception
> specification; attribute ignored}}
> +__declspec(nothrow) void foo3() noexcept(false);
> +__declspec(nothrow) void foo4() noexcept(noexcept(foo1()));
> +__declspec(nothrow) void foo5() noexcept(noexcept(foo2()));
> +// expected-warning at +1{{'nothrow' attribute conflicts with exception
> specification; attribute ignored}}
> +__declspec(nothrow) void foo6() noexcept(noexcept(foo3()));
>
> Propchange: cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp
>
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp
>
> ------------------------------------------------------------------------------
> svn:keywords = Author Date Id Rev URL
>
> Propchange: cfe/trunk/test/SemaCXX/nothrow-vs-exception-specs.cpp
>
> ------------------------------------------------------------------------------
> svn:mime-type = text/plain
>
> Modified: cfe/trunk/tools/libclang/CXType.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXType.cpp?rev=362119&r1=362118&r2=362119&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/CXType.cpp (original)
> +++ cfe/trunk/tools/libclang/CXType.cpp Thu May 30 10:31:54 2019
> @@ -742,6 +742,8 @@ getExternalExceptionSpecificationKind(Ex
> return CXCursor_ExceptionSpecificationKind_MSAny;
> case EST_BasicNoexcept:
> return CXCursor_ExceptionSpecificationKind_BasicNoexcept;
> + case EST_NoThrow:
> + return CXCursor_ExceptionSpecificationKind_NoThrow;
> case EST_NoexceptFalse:
> case EST_NoexceptTrue:
> case EST_DependentNoexcept:
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190530/4d49d81a/attachment-0001.html>
More information about the cfe-commits
mailing list