[Sema] Improve -Wstrict-prototypes diagnostic message for blocks.
Print "this block declaration is not a prototype" for non-prototype declarations of blocks instead of "this function declaration ...". rdar://problem/32461723 Differential Revision: https://reviews.llvm.org/D33739 llvm-svn: 304507
This commit is contained in:
parent
4b46f72c7f
commit
13b333108e
|
@ -4584,7 +4584,7 @@ def warn_missing_prototype : Warning<
|
||||||
def note_declaration_not_a_prototype : Note<
|
def note_declaration_not_a_prototype : Note<
|
||||||
"this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function">;
|
"this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function">;
|
||||||
def warn_strict_prototypes : Warning<
|
def warn_strict_prototypes : Warning<
|
||||||
"this %select{function declaration is not|"
|
"this %select{function declaration is not|block declaration is not|"
|
||||||
"old-style function definition is not preceded by}0 a prototype">,
|
"old-style function definition is not preceded by}0 a prototype">,
|
||||||
InGroup<DiagGroup<"strict-prototypes">>, DefaultIgnore;
|
InGroup<DiagGroup<"strict-prototypes">>, DefaultIgnore;
|
||||||
def warn_missing_variable_declarations : Warning<
|
def warn_missing_variable_declarations : Warning<
|
||||||
|
|
|
@ -12309,7 +12309,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
|
||||||
TypeSourceInfo *TI = FD->getTypeSourceInfo();
|
TypeSourceInfo *TI = FD->getTypeSourceInfo();
|
||||||
TypeLoc TL = TI->getTypeLoc();
|
TypeLoc TL = TI->getTypeLoc();
|
||||||
FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
|
FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
|
||||||
Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1;
|
Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4347,19 +4347,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||||
if (FTI.isAmbiguous)
|
if (FTI.isAmbiguous)
|
||||||
warnAboutAmbiguousFunction(S, D, DeclType, T);
|
warnAboutAmbiguousFunction(S, D, DeclType, T);
|
||||||
|
|
||||||
// GNU warning -Wstrict-prototypes
|
|
||||||
// Warn if a function declaration is without a prototype.
|
|
||||||
// This warning is issued for all kinds of unprototyped function
|
|
||||||
// declarations (i.e. function type typedef, function pointer etc.)
|
|
||||||
// C99 6.7.5.3p14:
|
|
||||||
// The empty list in a function declarator that is not part of a
|
|
||||||
// definition of that function specifies that no information
|
|
||||||
// about the number or types of the parameters is supplied.
|
|
||||||
if (D.getFunctionDefinitionKind() == FDK_Declaration &&
|
|
||||||
FTI.NumParams == 0 && !LangOpts.CPlusPlus)
|
|
||||||
S.Diag(DeclType.Loc, diag::warn_strict_prototypes)
|
|
||||||
<< 0 << FixItHint::CreateInsertion(FTI.getRParenLoc(), "void");
|
|
||||||
|
|
||||||
FunctionType::ExtInfo EI(getCCForDeclaratorChunk(S, D, FTI, chunkIndex));
|
FunctionType::ExtInfo EI(getCCForDeclaratorChunk(S, D, FTI, chunkIndex));
|
||||||
|
|
||||||
if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus) {
|
if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus) {
|
||||||
|
@ -4602,6 +4589,36 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||||
const_cast<AttributeList *>(DeclType.getAttrs()));
|
const_cast<AttributeList *>(DeclType.getAttrs()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GNU warning -Wstrict-prototypes
|
||||||
|
// Warn if a function declaration is without a prototype.
|
||||||
|
// This warning is issued for all kinds of unprototyped function
|
||||||
|
// declarations (i.e. function type typedef, function pointer etc.)
|
||||||
|
// C99 6.7.5.3p14:
|
||||||
|
// The empty list in a function declarator that is not part of a definition
|
||||||
|
// of that function specifies that no information about the number or types
|
||||||
|
// of the parameters is supplied.
|
||||||
|
if (!LangOpts.CPlusPlus && D.getFunctionDefinitionKind() == FDK_Declaration) {
|
||||||
|
bool IsBlock = false;
|
||||||
|
for (const DeclaratorChunk &DeclType : D.type_objects()) {
|
||||||
|
switch (DeclType.Kind) {
|
||||||
|
case DeclaratorChunk::BlockPointer:
|
||||||
|
IsBlock = true;
|
||||||
|
break;
|
||||||
|
case DeclaratorChunk::Function: {
|
||||||
|
const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
|
||||||
|
if (FTI.NumParams == 0)
|
||||||
|
S.Diag(DeclType.Loc, diag::warn_strict_prototypes)
|
||||||
|
<< IsBlock
|
||||||
|
<< FixItHint::CreateInsertion(FTI.getRParenLoc(), "void");
|
||||||
|
IsBlock = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(!T.isNull() && "T must not be null after this point");
|
assert(!T.isNull() && "T must not be null after this point");
|
||||||
|
|
||||||
if (LangOpts.CPlusPlus && T->isFunctionType()) {
|
if (LangOpts.CPlusPlus && T->isFunctionType()) {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
@interface Foo
|
@interface Foo
|
||||||
|
|
||||||
@property (nonatomic, copy) void (^noProtoBlock)(); // expected-warning {{this function declaration is not a prototype}}
|
@property (nonatomic, copy) void (^noProtoBlock)(); // expected-warning {{this block declaration is not a prototype}}
|
||||||
@property (nonatomic, copy) void (^block)(void); // no warning
|
@property (nonatomic, copy) void (^block)(void); // no warning
|
||||||
|
|
||||||
- doStuff:(void (^)()) completionHandler; // expected-warning {{this function declaration is not a prototype}}
|
- doStuff:(void (^)()) completionHandler; // expected-warning {{this block declaration is not a prototype}}
|
||||||
- doOtherStuff:(void (^)(void)) completionHandler; // no warning
|
- doOtherStuff:(void (^)(void)) completionHandler; // no warning
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
void foo() {
|
void foo() {
|
||||||
void (^block)() = // expected-warning {{this function declaration is not a prototype}}
|
void (^block)() = // expected-warning {{this block declaration is not a prototype}}
|
||||||
^void(int arg) { // no warning
|
^void(int arg) { // no warning
|
||||||
};
|
};
|
||||||
void (^block2)(void) = ^void() { // no warning
|
void (^block2)(void) = ^void() { // no warning
|
||||||
|
@ -19,3 +19,8 @@ void foo() {
|
||||||
void (^block3)(void) = ^ { // no warning
|
void (^block3)(void) = ^ { // no warning
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void (*(^(*(^block4)()) // expected-warning {{this block declaration is not a prototype}}
|
||||||
|
()) // expected-warning {{this function declaration is not a prototype}}
|
||||||
|
()) // expected-warning {{this block declaration is not a prototype}}
|
||||||
|
(); // expected-warning {{this function declaration is not a prototype}}
|
||||||
|
|
Loading…
Reference in New Issue