forked from OSchip/llvm-project
Fix an edge case in determining is a function has a prototype
Given the declaration: typedef void func_t(unsigned); __attribute__((noreturn)) func_t func; we would incorrectly determine that `func` had no prototype because the `noreturn` attribute would convert the underlying type directly into a FunctionProtoType, but the declarator for `func` itself was not one for a function with a prototype. This adds an additional check for when the declarator is a type representation for a function with a prototype.
This commit is contained in:
parent
2f78f9455f
commit
8fd3b5de3f
|
@ -8803,15 +8803,21 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
|
|||
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,
|
||||
|
|
|
@ -80,3 +80,13 @@ void foo13(...) __attribute__((overloadable)) {}
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue