ahatanak created this revision.
Currently, clang prints the same warning message "this function declaration is
not a prototype" for non-prototype declarations of blocks and normal functions.
This commit makes changes needed to print a more accurate warning "this block
declaration is not a prototype" when the declaration is a block.
rdar://problem/32461723
https://reviews.llvm.org/D33739
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaType.cpp
test/Sema/warn-strict-prototypes.m
Index: test/Sema/warn-strict-prototypes.m
===================================================================
--- test/Sema/warn-strict-prototypes.m
+++ test/Sema/warn-strict-prototypes.m
@@ -2,20 +2,25 @@
@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
-- 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
@end
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 (^block2)(void) = ^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}}
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -4351,19 +4351,6 @@
if (FTI.isAmbiguous)
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));
if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus) {
@@ -4606,6 +4593,36 @@
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");
if (LangOpts.CPlusPlus && T->isFunctionType()) {
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -12298,7 +12298,7 @@
TypeSourceInfo *TI = FD->getTypeSourceInfo();
TypeLoc TL = TI->getTypeLoc();
FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
- Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1;
+ Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 2;
}
}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -4584,7 +4584,7 @@
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">;
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">,
InGroup<DiagGroup<"strict-prototypes">>, DefaultIgnore;
def warn_missing_variable_declarations : Warning<
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits