]> granicus.if.org Git - clang/commitdiff
Introduce a Fix-It for the "missing sentinel" warning, adding an
authorDouglas Gregor <dgregor@apple.com>
Sat, 30 Jul 2011 08:57:03 +0000 (08:57 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 30 Jul 2011 08:57:03 +0000 (08:57 +0000)
appropriate sentinel at the end of the argument list. Also, put the
sentinel warnings under -Wsentinel. Fixes <rdar://problem/8764236>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136566 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/FixIt/fixit-objc.m

index af31baf6279b29ba4060a31ac70063c8ad81b9fb..c4ba82aab66d6f34c38d9d8007fe0c7f90a06766 100644 (file)
@@ -109,6 +109,7 @@ def ReturnType : DiagGroup<"return-type">;
 def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy">;
 def SelfAssignment : DiagGroup<"self-assign">;
 def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
+def Sentinel : DiagGroup<"sentinel">;
 def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
 def : DiagGroup<"sequence-point">;
 def Shadow : DiagGroup<"shadow">;
index 4f776c42c627228aa3284fe225b7dab790f77ec8..cd27636fca71e458ebbe4fcfdfa29e5effe52946 100644 (file)
@@ -2299,9 +2299,11 @@ def note_unavailable_here : Note<
   "%select{declaration|function}0 has been explicitly marked "
   "%select{unavailable|deleted|deprecated}1 here">;
 def warn_not_enough_argument : Warning<
-  "not enough variable arguments in %0 declaration to fit a sentinel">;
+  "not enough variable arguments in %0 declaration to fit a sentinel">,
+  InGroup<Sentinel>;
 def warn_missing_sentinel : Warning <
-  "missing sentinel in %select{function call|method dispatch|block call}0">;
+  "missing sentinel in %select{function call|method dispatch|block call}0">,
+  InGroup<Sentinel>;
 def note_sentinel_here : Note<
   "%select{function|method|block}0 has been explicitly marked sentinel here">;
 def warn_missing_prototype : Warning<
index 966fcbffcf2bf9a18d2d5496380ac187c01d7c0d..43e3807e21d5c4640f0bb67c8737935479b5e14c 100644 (file)
@@ -156,13 +156,9 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
   if (!attr)
     return;
 
-  // FIXME: In C++0x, if any of the arguments are parameter pack
-  // expansions, we can't check for the sentinel now.
   int sentinelPos = attr->getSentinel();
   int nullPos = attr->getNullPos();
 
-  // FIXME. ObjCMethodDecl and FunctionDecl need be derived from the same common
-  // base class. Then we won't be needing two versions of the same code.
   unsigned int i = 0;
   bool warnNotEnoughArgs = false;
   int isMethod = 0;
@@ -247,7 +243,22 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
   // Unfortunately, __null has type 'int'.
   if (isa<GNUNullExpr>(sentinelExpr)) return;
 
-  Diag(Loc, diag::warn_missing_sentinel) << isMethod;
+  SourceLocation MissingNilLoc 
+    = PP.getLocForEndOfToken(sentinelExpr->getLocEnd());
+  std::string NullValue;
+  if (isMethod && PP.getIdentifierInfo("nil")->hasMacroDefinition())
+    NullValue = "nil";
+  else if (PP.getIdentifierInfo("NULL")->hasMacroDefinition())
+    NullValue = "NULL";
+  else if (Context.getTypeSize(Context.IntTy)
+                                  == Context.getTypeSize(Context.getSizeType()))
+    NullValue = "0";
+  else
+    NullValue = "0L";
+  
+  Diag(MissingNilLoc, diag::warn_missing_sentinel) 
+    << isMethod 
+    << FixItHint::CreateInsertion(MissingNilLoc, ", " + NullValue);
   Diag(D->getLocation(), diag::note_sentinel_here) << isMethod;
 }
 
index 2e8bfaea6aa3a69ff2f59fe241e90a9cae154b70..df591c79229645135207a45e4b20e124185c225c 100644 (file)
@@ -53,3 +53,17 @@ int f0(Radar7861841 *a) { return a.x; } // expected-error {{property 'x' not fou
 
 int f1(Radar7861841 *a) { return a->y; } // expected-error {{property 'y' found on object of type 'Radar7861841 *'; did you mean to access it with the "." operator?}}
 
+
+#define nil ((void*)0)
+#define NULL ((void*)0)
+
+void sentinel(int x, ...) __attribute__((sentinel)); // expected-note{{function has been explicitly marked sentinel here}}
+
+@interface Sentinel
+- (void)sentinel:(int)x, ... __attribute__((sentinel)); // expected-note{{method has been explicitly marked sentinel here}}
+@end
+
+void sentinel_test(Sentinel *a) {
+  sentinel(1, 2, 3); // expected-warning{{missing sentinel in function call}}
+  [a sentinel:1, 2, 3]; // expected-warning{{missing sentinel in method dispatch}}
+}