bool isInline = D.getDeclSpec().isInlineSpecified();
if (!SemaRef.getLangOpts().CPlusPlus) {
- // Determine whether the function was written with a
- // prototype. This true when:
+ // Determine whether the function was written with a prototype. This is
+ // true when:
// - there is a prototype in the declarator, or
// - the type R of the function is some kind of typedef or other non-
// attributed reference to a type name (which eventually refers to a
- // function type).
+ // function type). Note, we can't always look at the adjusted type to
+ // check this case because attributes may cause a non-function
+ // declarator to still have a function type. e.g.,
+ // typedef void func(int a);
+ // __attribute__((noreturn)) func other_func; // This has a prototype
bool HasPrototype =
- (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
- (!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType());
+ (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
+ (D.getDeclSpec().isTypeRep() &&
+ D.getDeclSpec().getRepAsType().get()->isFunctionProtoType()) ||
+ (!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType());
NewFD = FunctionDecl::Create(
SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC,
void foo14(void) {
foo14_call(); // no-warning
}
+
+// Ensure that redeclarations involving a typedef type work properly, even if
+// there are function attributes involved in the declaration.
+typedef void foo_t(unsigned val);
+__attribute__((noreturn)) foo_t foo15;
+foo_t foo15; // OK
+void foo15(unsigned val); // OK
+
+foo_t foo16;
+void foo16(unsigned val); // OK