bool isLValueReferenceType() const;
bool isRValueReferenceType() const;
bool isFunctionPointerType() const;
+ bool isFunctionReferenceType() const;
bool isMemberPointerType() const;
bool isMemberFunctionPointerType() const;
bool isMemberDataPointerType() const;
return false;
}
+inline bool Type::isFunctionReferenceType() const {
+ if (const auto *T = getAs<ReferenceType>())
+ return T->getPointeeType()->isFunctionType();
+ else
+ return false;
+}
+
inline bool Type::isMemberPointerType() const {
return isa<MemberPointerType>(CanonicalType);
}
def NoThrow : InheritableAttr {
let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[FunctionLike]>;
let Documentation = [NoThrowDocs];
}
if (Ty->isFunctionPointerType())
Ty = Ty->getAs<PointerType>()->getPointeeType();
+ else if (Ty->isFunctionReferenceType())
+ Ty = Ty->getAs<ReferenceType>()->getPointeeType();
else if (BlocksToo && Ty->isBlockPointerType())
Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
OS << getExceptionType(I).stream(Policy);
}
OS << ')';
+ } else if (EST_NoThrow == getExceptionSpecType()) {
+ OS << " __attribute__((nothrow))";
} else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
OS << " noexcept";
// FIXME:Is it useful to print out the expression for a non-dependent
// CHECK-NEXT: NoSplitStack (SubjectMatchRule_function)
// CHECK-NEXT: NoStackProtector (SubjectMatchRule_function)
// CHECK-NEXT: NoThreadSafetyAnalysis (SubjectMatchRule_function)
-// CHECK-NEXT: NoThrow (SubjectMatchRule_function)
+// CHECK-NEXT: NoThrow (SubjectMatchRule_hasType_functionType)
// CHECK-NEXT: NotTailCalled (SubjectMatchRule_function)
// CHECK-NEXT: OSConsumed (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: OSReturnsNotRetained (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_variable_is_parameter)
void foo() {}
};
}
+
+namespace FuncPointerReferenceConverts
+void FuncToBeRefed();
+
+#ifndef CPP17
+// expected-error@+6{{target exception specification is not superset of source}}
+// expected-error@+6{{target exception specification is not superset of source}}
+#else
+// expected-error@+3{{non-const lvalue reference to type 'void () __attribute__((nothrow))' cannot bind to a value of unrelated type 'void ()'}}
+// expected-error@+3{{cannot initialize a variable of type 'void (*)() __attribute__((nothrow))' with an lvalue of type 'void ()': different exception specifications}}
+#endif
+__declspec(nothrow) void (&FuncRef)() = FuncToBeRefed;
+__declspec(nothrow) void (*FuncPtr)() = FuncToBeRefed;
+}