<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Aug 27, 2014 at 11:06 AM, Alexey Samsonov <span dir="ltr"><<a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Nice, but now we have another crash:<div><div>
<div><br></div><div><div>$ cat bad.cpp </div><div>__attribute__((nonnull)) void foo(int x) {}</div><div>$ ./bin/clang++ bad.cpp -S -emit-llvm -o -<br></div><div>
bad.cpp:1:16: warning: 'nonnull' attribute applied to function with no pointer arguments [-Wignored-attributes]</div><div>__attribute__((nonnull)) void foo(int x) {}</div><div>               ^</div><div>Wrong types for attribute: byval inalloca nest noalias nocapture nonnull readnone readonly sret dereferenceable(1)</div>

<div>void (i32)* @_Z3fooi</div><div>fatal error: error in backend: Broken function found, compilation aborted!</div><div>clang-3.5: error: clang frontend command failed with exit code 70 (use -v to see invocation)</div><div>

clang version 3.6.0 (216565)</div><div>Target: x86_64-unknown-linux-gnu</div><div>Thread model: posix</div><div>clang-3.5: note: diagnostic msg: PLEASE submit a bug report to <a href="http://llvm.org/bugs/" target="_blank">http://llvm.org/bugs/</a> and include the crash backtrace, preprocessed source, and associated run script.</div>

<div>clang-3.5: note: diagnostic msg: </div><div>********************</div><div><br></div><div>PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:</div><div>Preprocessed source(s) and associated run script(s) are located at:</div>

<div>clang-3.5: note: diagnostic msg: /tmp/bad-c25b9c.cpp</div><div>clang-3.5: note: diagnostic msg: /tmp/bad-c25b9c.sh</div><div>clang-3.5: note: diagnostic msg: </div><div><br></div><div>********************</div></div>

</div></div><div><br></div><div>Same codegen crash for this declaration:</div><div>__attribute__((nonnull(1))) void foo(int x) {}<br></div><div><br></div><div>If you don't immediately flatten nonull arguments, that printing diagnostic messages is not enough - you should ensure that non-pointer arguments don't get nonnull</div>

<div>attribute in LLVM IR declarations. This probably means fixing EmitFunctionProlog in CodeGen, but I don't know if it's OK to use <span style="font-family:arial,sans-serif;font-size:13px">isValidNonNullAttrType from Sema in that place.</span></div>
</div></blockquote><div><br></div><div>Thanks, fixed in r216574. Turns out that it's not appropriate to use isValidNonNullAttrType in CodeGen, because there are types for which the frontend supports the nonnull attribute but CodeGen cannot.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="gmail_extra"><div><div class="h5">
<div class="gmail_quote">On Tue, Aug 26, 2014 at 9:59 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: rsmith<br>
Date: Tue Aug 26 23:59:42 2014<br>
New Revision: 216520<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=216520&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=216520&view=rev</a><br>
Log:<br>
Fix representation of __attribute__((nonnull)) to support correctly modeling<br>
the no-arguments case. Don't expand this to an __attribute__((nonnull(A, B,<br>
C))) attribute, since that does the wrong thing for function templates and<br>
varargs functions.<br>
<br>
In passing, fix a grammar error in the diagnostic, a crash if<br>
__attribute__((nonnull(N))) is applied to a varargs function,<br>
a bug where the same null argument could be diagnosed multiple<br>
times if there were multiple nonnull attributes referring to it,<br>
and a bug where nonnull attributes would not be accumulated correctly<br>
across redeclarations.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/Attr.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Sema/SemaChecking.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
    cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp<br>
    cfe/trunk/test/Sema/nonnull.c<br>
    cfe/trunk/test/Sema/static-array.c<br>
    cfe/trunk/test/SemaCXX/attr-nonnull.cpp<br>
    cfe/trunk/test/SemaCXX/nonnull.cpp<br>
    cfe/trunk/test/SemaObjC/nonnull.m<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Attr.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
+++ cfe/trunk/include/clang/Basic/Attr.td Tue Aug 26 23:59:42 2014<br>
@@ -845,11 +845,15 @@ def NonNull : InheritableAttr {<br>
   let Args = [VariadicUnsignedArgument<"Args">];<br>
   let AdditionalMembers =<br>
 [{bool isNonNull(unsigned idx) const {<br>
+    if (!args_size())<br>
+      return true;<br>
     for (const auto &V : args())<br>
       if (V == idx)<br>
         return true;<br>
     return false;<br>
   } }];<br>
+  // FIXME: We should merge duplicates into a single nonnull attribute.<br>
+  let DuplicatesAllowedWhileMerging = 1;<br>
   let Documentation = [Undocumented];<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 26 23:59:42 2014<br>
@@ -6470,7 +6470,7 @@ def note_format_fix_specifier : Note<"di<br>
 def note_printf_c_str: Note<"did you mean to call the %0 method?">;<br>
<br>
 def warn_null_arg : Warning<<br>
-  "null passed to a callee which requires a non-null argument">,<br>
+  "null passed to a callee that requires a non-null argument">,<br>
   InGroup<NonNull>;<br>
 def warn_null_ret : Warning<<br>
   "null returned from %select{function|method}0 that requires a non-null return value">,<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Aug 26 23:59:42 2014<br>
@@ -129,7 +129,6 @@ namespace clang {<br>
   class ModuleLoader;<br>
   class MultiLevelTemplateArgumentList;<br>
   class NamedDecl;<br>
-  class NonNullAttr;<br>
   class ObjCCategoryDecl;<br>
   class ObjCCategoryImplDecl;<br>
   class ObjCCompatibleAliasDecl;<br>
@@ -2706,6 +2705,9 @@ public:<br>
<br>
   void checkUnusedDeclAttributes(Declarator &D);<br>
<br>
+  /// Determine if type T is a valid subject for a nonnull attribute.<br>
+  bool isValidNonNullAttrType(QualType T);<br>
+<br>
   bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);<br>
   bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,<br>
                             const FunctionDecl *FD = nullptr);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Aug 26 23:59:42 2014<br>
@@ -764,12 +764,26 @@ static void CheckNonNullArgument(Sema &S<br>
<br>
 static void CheckNonNullArguments(Sema &S,<br>
                                   const NamedDecl *FDecl,<br>
-                                  const Expr * const *ExprArgs,<br>
+                                  ArrayRef<const Expr *> Args,<br>
                                   SourceLocation CallSiteLoc) {<br>
   // Check the attributes attached to the method/function itself.<br>
+  llvm::SmallBitVector NonNullArgs;<br>
   for (const auto *NonNull : FDecl->specific_attrs<NonNullAttr>()) {<br>
-    for (const auto &Val : NonNull->args())<br>
-      CheckNonNullArgument(S, ExprArgs[Val], CallSiteLoc);<br>
+    if (!NonNull->args_size()) {<br>
+      // Easy case: all pointer arguments are nonnull.<br>
+      for (const auto *Arg : Args)<br>
+        if (S.isValidNonNullAttrType(Arg->getType()))<br>
+          CheckNonNullArgument(S, Arg, CallSiteLoc);<br>
+      return;<br>
+    }<br>
+<br>
+    for (unsigned Val : NonNull->args()) {<br>
+      if (Val >= Args.size())<br>
+        continue;<br>
+      if (NonNullArgs.empty())<br>
+        NonNullArgs.resize(Args.size());<br>
+      NonNullArgs.set(Val);<br>
+    }<br>
   }<br>
<br>
   // Check the attributes on the parameters.<br>
@@ -779,13 +793,19 @@ static void CheckNonNullArguments(Sema &<br>
   else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(FDecl))<br>
     parms = MD->parameters();<br>
<br>
-  unsigned argIndex = 0;<br>
+  unsigned ArgIndex = 0;<br>
   for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end();<br>
-       I != E; ++I, ++argIndex) {<br>
+       I != E; ++I, ++ArgIndex) {<br>
     const ParmVarDecl *PVD = *I;<br>
-    if (PVD->hasAttr<NonNullAttr>())<br>
-      CheckNonNullArgument(S, ExprArgs[argIndex], CallSiteLoc);<br>
+    if (PVD->hasAttr<NonNullAttr>() ||<br>
+        (ArgIndex < NonNullArgs.size() && NonNullArgs[ArgIndex]))<br>
+      CheckNonNullArgument(S, Args[ArgIndex], CallSiteLoc);<br>
   }<br>
+<br>
+  // In case this is a variadic call, check any remaining arguments.<br>
+  for (/**/; ArgIndex < NonNullArgs.size(); ++ArgIndex)<br>
+    if (NonNullArgs[ArgIndex])<br>
+      CheckNonNullArgument(S, Args[ArgIndex], CallSiteLoc);<br>
 }<br>
<br>
 /// Handles the checks for format strings, non-POD arguments to vararg<br>
@@ -823,7 +843,7 @@ void Sema::checkCall(NamedDecl *FDecl, A<br>
   }<br>
<br>
   if (FDecl) {<br>
-    CheckNonNullArguments(*this, FDecl, Args.data(), Loc);<br>
+    CheckNonNullArguments(*this, FDecl, Args, Loc);<br>
<br>
     // Type safety checking.<br>
     for (const auto *I : FDecl->specific_attrs<ArgumentWithTypeTagAttr>())<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Aug 26 23:59:42 2014<br>
@@ -1125,28 +1125,30 @@ static void handleIBOutletCollection(Sem<br>
                                     Attr.getAttributeSpellingListIndex()));<br>
 }<br>
<br>
-static void possibleTransparentUnionPointerType(QualType &T) {<br>
-  if (const RecordType *UT = T->getAsUnionType())<br>
+bool Sema::isValidNonNullAttrType(QualType T) {<br>
+  T = T.getNonReferenceType();<br>
+<br>
+  // The nonnull attribute can be applied to a transparent union that<br>
+  // contains a pointer type.<br>
+  if (const RecordType *UT = T->getAsUnionType()) {<br>
     if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {<br>
       RecordDecl *UD = UT->getDecl();<br>
       for (const auto *I : UD->fields()) {<br>
         QualType QT = I->getType();<br>
-        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {<br>
-          T = QT;<br>
-          return;<br>
-        }<br>
+        if (QT->isAnyPointerType() || QT->isBlockPointerType())<br>
+          return true;<br>
       }<br>
     }<br>
+  }<br>
+<br>
+  return T->isAnyPointerType() || T->isBlockPointerType();<br>
 }<br>
<br>
 static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr,<br>
                                 SourceRange AttrParmRange,<br>
                                 SourceRange NonNullTypeRange,<br>
                                 bool isReturnValue = false) {<br>
-  T = T.getNonReferenceType();<br>
-  possibleTransparentUnionPointerType(T);<br>
-<br>
-  if (!T->isAnyPointerType() && !T->isBlockPointerType()) {<br>
+  if (!S.isValidNonNullAttrType(T)) {<br>
     S.Diag(Attr.getLoc(), isReturnValue<br>
                               ? diag::warn_attribute_return_pointers_only<br>
                               : diag::warn_attribute_pointers_only)<br>
@@ -1158,14 +1160,15 @@ static bool attrNonNullArgCheck(Sema &S,<br>
<br>
 static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {<br>
   SmallVector<unsigned, 8> NonNullArgs;<br>
-  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {<br>
-    Expr *Ex = Attr.getArgAsExpr(i);<br>
+  for (unsigned I = 0; I < Attr.getNumArgs(); ++I) {<br>
+    Expr *Ex = Attr.getArgAsExpr(I);<br>
     uint64_t Idx;<br>
-    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, i + 1, Ex, Idx))<br>
+    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, I + 1, Ex, Idx))<br>
       return;<br>
<br>
     // Is the function argument a pointer type?<br>
-    if (!attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr,<br>
+    if (Idx < getFunctionOrMethodNumParams(D) &&<br>
+        !attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr,<br>
                              Ex->getSourceRange(),<br>
                              getFunctionOrMethodParamRange(D, Idx)))<br>
       continue;<br>
@@ -1174,30 +1177,28 @@ static void handleNonNullAttr(Sema &S, D<br>
   }<br>
<br>
   // If no arguments were specified to __attribute__((nonnull)) then all pointer<br>
-  // arguments have a nonnull attribute.<br>
-  if (NonNullArgs.empty()) {<br>
-    for (unsigned i = 0, e = getFunctionOrMethodNumParams(D); i != e; ++i) {<br>
-      QualType T = getFunctionOrMethodParamType(D, i).getNonReferenceType();<br>
-      possibleTransparentUnionPointerType(T);<br>
-      if (T->isAnyPointerType() || T->isBlockPointerType())<br>
-        NonNullArgs.push_back(i);<br>
+  // arguments have a nonnull attribute; warn if there aren't any. Skip this<br>
+  // check if the attribute came from a macro expansion or a template<br>
+  // instantiation.<br>
+  if (NonNullArgs.empty() && Attr.getLoc().isFileID() &&<br>
+      S.ActiveTemplateInstantiations.empty()) {<br>
+    bool AnyPointers = isFunctionOrMethodVariadic(D);<br>
+    for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);<br>
+         I != E && !AnyPointers; ++I) {<br>
+      QualType T = getFunctionOrMethodParamType(D, I);<br>
+      if (T->isDependentType() || S.isValidNonNullAttrType(T))<br>
+        AnyPointers = true;<br>
     }<br>
<br>
-    // No pointer arguments?<br>
-    if (NonNullArgs.empty()) {<br>
-      // Warn the trivial case only if attribute is not coming from a<br>
-      // macro instantiation.<br>
-      if (Attr.getLoc().isFileID())<br>
-        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);<br>
-      return;<br>
-    }<br>
+    if (!AnyPointers)<br>
+      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);<br>
   }<br>
<br>
-  unsigned *start = &NonNullArgs[0];<br>
-  unsigned size = NonNullArgs.size();<br>
-  llvm::array_pod_sort(start, start + size);<br>
+  unsigned *Start = NonNullArgs.data();<br>
+  unsigned Size = NonNullArgs.size();<br>
+  llvm::array_pod_sort(Start, Start + Size);<br>
   D->addAttr(::new (S.Context)<br>
-             NonNullAttr(Attr.getRange(), S.Context, start, size,<br>
+             NonNullAttr(Attr.getRange(), S.Context, Start, Size,<br>
                          Attr.getAttributeSpellingListIndex()));<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp (original)<br>
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp Tue Aug 26 23:59:42 2014<br>
@@ -49,6 +49,8 @@ void NonNullParamChecker::checkPreCall(c<br>
   if (!FD)<br>
     return;<br>
<br>
+  // FIXME: This is wrong; there can be multiple attributes with different sets<br>
+  // of non-null parameter indices.<br>
   const NonNullAttr *Att = FD->getAttr<NonNullAttr>();<br>
<br>
   ProgramStateRef state = C.getState();<br>
<br>
Modified: cfe/trunk/test/Sema/nonnull.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/nonnull.c?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/nonnull.c?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/Sema/nonnull.c (original)<br>
+++ cfe/trunk/test/Sema/nonnull.c Tue Aug 26 23:59:42 2014<br>
@@ -15,7 +15,7 @@ __attribute__((nonnull(1))) void Class_i<br>
<br>
 int main(void) {<br>
        Class *obj;<br>
-       Class_init(0, "Hello World"); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+       Class_init(0, "Hello World"); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
        Class_init(obj, "Hello World");<br>
 }<br>
<br>
@@ -27,7 +27,7 @@ void baz2(__attribute__((nonnull(1))) co<br>
 void baz3(__attribute__((nonnull)) int x); // expected-warning {{'nonnull' attribute only applies to pointer arguments}}<br>
<br>
 void test_baz() {<br>
-  baz(0); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  baz(0); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
   baz2(0); // no-warning<br>
   baz3(0); // no-warning<br>
 }<br>
@@ -47,10 +47,39 @@ void *test_bad_returns_null(void) {<br>
 }<br>
<br>
 void PR18795(int (*g)(const char *h, ...) __attribute__((nonnull(1))) __attribute__((nonnull))) {<br>
-  g(0); // expected-warning{{null passed to a callee which requires a non-null argument}}<br>
+  g(0); // expected-warning{{null passed to a callee that requires a non-null argument}}<br>
 }<br>
 void PR18795_helper() {<br>
-  PR18795(0); // expected-warning{{null passed to a callee which requires a non-null argument}}<br>
+  PR18795(0); // expected-warning{{null passed to a callee that requires a non-null argument}}<br>
 }<br>
<br>
+void vararg1(int n, ...) __attribute__((nonnull(2)));<br>
+void vararg1_test() {<br>
+  vararg1(0);<br>
+  vararg1(1, (void*)0); // expected-warning{{null passed}}<br>
+  vararg1(2, (void*)0, (void*)0); // expected-warning{{null passed}}<br>
+  vararg1(2, (void*)&vararg1, (void*)0);<br>
+}<br>
+<br>
+void vararg2(int n, ...) __attribute__((nonnull, nonnull, nonnull));<br>
+void vararg2_test() {<br>
+  vararg2(0);<br>
+  vararg2(1, (void*)0); // expected-warning{{null passed}}<br>
+  vararg2(2, (void*)0, (void*)0); // expected-warning 2{{null passed}}<br>
+}<br>
<br>
+void vararg3(int n, ...) __attribute__((nonnull, nonnull(2), nonnull(3)));<br>
+void vararg3_test() {<br>
+  vararg3(0);<br>
+  vararg3(1, (void*)0); // expected-warning{{null passed}}<br>
+  vararg3(2, (void*)0, (void*)0); // expected-warning 2{{null passed}}<br>
+}<br>
+<br>
+void redecl(void *, void *);<br>
+void redecl(void *, void *) __attribute__((nonnull(1)));<br>
+void redecl(void *, void *) __attribute__((nonnull(2)));<br>
+void redecl(void *, void *);<br>
+void redecl_test(void *p) {<br>
+  redecl(p, 0); // expected-warning{{null passed}}<br>
+  redecl(0, p); // expected-warning{{null passed}}<br>
+}<br>
<br>
Modified: cfe/trunk/test/Sema/static-array.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-array.c?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-array.c?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/Sema/static-array.c (original)<br>
+++ cfe/trunk/test/Sema/static-array.c Tue Aug 26 23:59:42 2014<br>
@@ -11,13 +11,13 @@ void f(int *p) {<br>
<br>
   cat0(0);<br>
<br>
-  cat(0); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  cat(0); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
   cat(a); // expected-warning {{array argument is too small; contains 2 elements, callee requires at least 3}}<br>
   cat(b);<br>
   cat(c);<br>
   cat(p);<br>
<br>
-  vat(1, 0); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  vat(1, 0); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
   vat(3, b);<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/attr-nonnull.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-nonnull.cpp?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-nonnull.cpp?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/SemaCXX/attr-nonnull.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/attr-nonnull.cpp Tue Aug 26 23:59:42 2014<br>
@@ -27,8 +27,8 @@ namespace rdar8769025 {<br>
   __attribute__((nonnull(2))) void f2(int i, int * const &p);<br>
<br>
   void test_f1() {<br>
-    f1(0); // expected-warning{{null passed to a callee which requires a non-null argument}}<br>
-    f2(0, 0); // expected-warning{{null passed to a callee which requires a non-null argument}}<br>
+    f1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}<br>
+    f2(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}<br>
   }<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/nonnull.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nonnull.cpp?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nonnull.cpp?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/SemaCXX/nonnull.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/nonnull.cpp Tue Aug 26 23:59:42 2014<br>
@@ -13,3 +13,8 @@ struct TS {<br>
   }<br>
 };<br>
<br>
+namespace Template {<br>
+  template<typename T> __attribute__((nonnull)) void f(T t);<br>
+  void g() { f((void*)0); } // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
+  void h() { f(0); }<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaObjC/nonnull.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/nonnull.m?rev=216520&r1=216519&r2=216520&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/nonnull.m?rev=216520&r1=216519&r2=216520&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/SemaObjC/nonnull.m (original)<br>
+++ cfe/trunk/test/SemaObjC/nonnull.m Tue Aug 26 23:59:42 2014<br>
@@ -31,16 +31,16 @@ foo (int i1, int i2, int i3, void (^cp1)<br>
 {<br>
   func1(cp1, cp2, i1);<br>
<br>
-  func1(0, cp2, i1);  // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
-  func1(cp1, 0, i1);  // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  func1(0, cp2, i1);  // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
+  func1(cp1, 0, i1);  // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
   func1(cp1, cp2, 0);<br>
<br>
<br>
-  func3(0, i2, cp3, i3); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
-  func3(cp3, i2, 0, i3);  // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  func3(0, i2, cp3, i3); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
+  func3(cp3, i2, 0, i3);  // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
<br>
-  func4(0, cp1); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
-  func4(cp1, 0); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  func4(0, cp1); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
+  func4(cp1, 0); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
<br>
   // Shouldn't these emit warnings?  Clang doesn't, and neither does GCC.  It<br>
   // seems that the checking should handle Objective-C pointers.<br>
@@ -64,7 +64,7 @@ __attribute__((nonnull))<br>
 void _dispatch_queue_push_list(dispatch_object_t _head); // no warning<br>
<br>
 void func6(dispatch_object_t _head) {<br>
-  _dispatch_queue_push_list(0); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  _dispatch_queue_push_list(0); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
   _dispatch_queue_push_list(_head._do);  // no warning<br>
 }<br>
<br>
@@ -91,10 +91,10 @@ extern void DoSomethingNotNull(void *db)<br>
 @implementation IMP<br>
 - (void) Meth {<br>
   NSObject *object;<br>
-  [object doSomethingWithNonNullPointer:NULL:1:NULL]; // expected-warning 2 {{null passed to a callee which requires a non-null argument}}<br>
-  [object doSomethingWithNonNullPointer:vp:1:NULL]; // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
-  [NSObject doSomethingClassyWithNonNullPointer:NULL]; // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
-  DoSomethingNotNull(NULL); // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  [object doSomethingWithNonNullPointer:NULL:1:NULL]; // expected-warning 2 {{null passed to a callee that requires a non-null argument}}<br>
+  [object doSomethingWithNonNullPointer:vp:1:NULL]; // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
+  [NSObject doSomethingClassyWithNonNullPointer:NULL]; // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
+  DoSomethingNotNull(NULL); // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
   [object doSomethingWithNonNullPointer:vp:1:vp];<br>
 }<br>
 - (void*) testRetNull {<br>
@@ -111,15 +111,15 @@ __attribute__((objc_root_class))<br>
 @end<br>
<br>
 void test(TestNonNullParameters *f) {<br>
-  [f doNotPassNullParameter:0]; // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  [f doNotPassNullParameter:0]; // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
   [f doNotPassNullParameterArgIndex:0]; // no-warning<br>
-  [f doNotPassNullOnMethod:0]; // expected-warning {{null passed to a callee which requires a non-null argument}}<br>
+  [f doNotPassNullOnMethod:0]; // expected-warning {{null passed to a callee that requires a non-null argument}}<br>
 }<br>
<br>
<br>
 void PR18795(int (^g)(const char *h, ...) __attribute__((nonnull(1))) __attribute__((nonnull))) {<br>
-  g(0); // expected-warning{{null passed to a callee which requires a non-null argument}}<br>
+  g(0); // expected-warning{{null passed to a callee that requires a non-null argument}}<br>
 }<br>
 void PR18795_helper() {<br>
-  PR18795(0); // expected-warning{{null passed to a callee which requires a non-null argument}}<br>
+  PR18795(0); // expected-warning{{null passed to a callee that requires a non-null argument}}<br>
 }<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class=""><font color="#888888">-- <br><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div>

</font></span></div>
</blockquote></div><br></div></div>