From da59652c1ba15ee780cf38186933dcd135e36ed4 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Wed, 5 Jun 2019 14:10:39 +0000 Subject: [PATCH] Avoid using NoThrow Exception Specifier in non-C++ Modes. As reported in https://bugs.llvm.org/show_bug.cgi?id=42113, there are a number of locations in Clang where it is assumed that exception specifications are only valid in C++ mode. Since the original justification for the NoThrow Exception Specifier Type was C++ related, this patch just makes C mode use the attribute-based nothrow handling. Additionally, I noticed that the handling of non-prototype functions regressed the behavior of the nothrow attribute, in part because it is was listed in the function type macro(which I did in the previous patch). In reality, it should only be doing so in a conditional nature, so this patch removes it there and puts it directly in the switch to be handled correctly. llvm-svn: 362607 --- clang/include/clang/Sema/ParsedAttr.h | 2 +- clang/lib/Sema/SemaType.cpp | 25 ++++++++++++------------- clang/test/Sema/attr-nothrow.c | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 clang/test/Sema/attr-nothrow.c diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index a42e454..d87d5da 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -440,7 +440,7 @@ public: } bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } - void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } + void setUsedAsTypeAttr(bool Used = true) { UsedAsTypeAttr = Used; } /// True if the attribute is specified using '#pragma clang attribute'. bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index d473fb6..27f034b 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -130,7 +130,6 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr, case ParsedAttr::AT_Regparm: \ case ParsedAttr::AT_AnyX86NoCallerSavedRegisters: \ case ParsedAttr::AT_AnyX86NoCfCheck: \ - case ParsedAttr::AT_NoThrow: \ CALLING_CONV_ATTRS_CASELIST // Microsoft-specific type qualifiers. @@ -6947,23 +6946,17 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, } 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(); - - // In the case where this is a FunctionNoProtoType instead of a - // FunctionProtoType, let the existing NoThrowAttr implementation do its - // thing. - if (!Proto) - return false; + if (S.CheckAttrNoArgs(attr)) { + attr.setInvalid(); + return true; + } - attr.setUsedAsTypeAttr(); + // Otherwise we can process right away. + auto *Proto = unwrapped.get()->castAs(); // MSVC ignores nothrow if it is in conflict with an explicit exception // specification. @@ -7668,6 +7661,12 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, attr.setInvalid(); break; + case ParsedAttr::AT_NoThrow: + // Exception Specifications aren't generally supported in C mode throughout + // clang, so revert to attribute-based handling for C. + if (!state.getSema().getLangOpts().CPlusPlus) + break; + LLVM_FALLTHROUGH; FUNCTION_TYPE_ATTRS_CASELIST: attr.setUsedAsTypeAttr(); diff --git a/clang/test/Sema/attr-nothrow.c b/clang/test/Sema/attr-nothrow.c new file mode 100644 index 0000000..c444628 --- /dev/null +++ b/clang/test/Sema/attr-nothrow.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -verify +// RUN: %clang_cc1 %s -ast-dump | FileCheck %s +// expected-no-diagnostics + +// PR42113: The following caused an assertion in mergeFunctionTypes +// because it causes one side to have an exception specification, which +// isn't typically supported in C. +void PR42113a(); +void PR42113a(void) __attribute__((nothrow)); +// CHECK: FunctionDecl {{.*}} PR42113a +// CHECK: FunctionDecl {{.*}} PR42113a +// CHECK: NoThrowAttr +void PR42113b() __attribute__((nothrow)); +// CHECK: FunctionDecl {{.*}} PR42113b +// CHECK: NoThrowAttr + __attribute__((nothrow)) void PR42113c(); +// CHECK: FunctionDecl {{.*}} PR42113c +// CHECK: NoThrowAttr -- 2.7.4