r216520 - Fix representation of __attribute__((nonnull)) to support correctly modeling

Richard Smith richard at metafoo.co.uk
Wed Aug 27 12:06:51 PDT 2014


On Wed, Aug 27, 2014 at 11:06 AM, Alexey Samsonov <vonosmas at gmail.com>
wrote:

> Nice, but now we have another crash:
>
> $ cat bad.cpp
> __attribute__((nonnull)) void foo(int x) {}
> $ ./bin/clang++ bad.cpp -S -emit-llvm -o -
> bad.cpp:1:16: warning: 'nonnull' attribute applied to function with no
> pointer arguments [-Wignored-attributes]
> __attribute__((nonnull)) void foo(int x) {}
>                ^
> Wrong types for attribute: byval inalloca nest noalias nocapture nonnull
> readnone readonly sret dereferenceable(1)
> void (i32)* @_Z3fooi
> fatal error: error in backend: Broken function found, compilation aborted!
> clang-3.5: error: clang frontend command failed with exit code 70 (use -v
> to see invocation)
> clang version 3.6.0 (216565)
> Target: x86_64-unknown-linux-gnu
> Thread model: posix
> clang-3.5: note: diagnostic msg: PLEASE submit a bug report to
> http://llvm.org/bugs/ and include the crash backtrace, preprocessed
> source, and associated run script.
> clang-3.5: note: diagnostic msg:
> ********************
>
> PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
> Preprocessed source(s) and associated run script(s) are located at:
> clang-3.5: note: diagnostic msg: /tmp/bad-c25b9c.cpp
> clang-3.5: note: diagnostic msg: /tmp/bad-c25b9c.sh
> clang-3.5: note: diagnostic msg:
>
> ********************
>
> Same codegen crash for this declaration:
> __attribute__((nonnull(1))) void foo(int x) {}
>
> 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
> attribute in LLVM IR declarations. This probably means fixing
> EmitFunctionProlog in CodeGen, but I don't know if it's OK to use isValidNonNullAttrType
> from Sema in that place.
>

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.


> On Tue, Aug 26, 2014 at 9:59 PM, Richard Smith <richard-llvm at metafoo.co.uk
> > wrote:
>
>> Author: rsmith
>> Date: Tue Aug 26 23:59:42 2014
>> New Revision: 216520
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=216520&view=rev
>> Log:
>> Fix representation of __attribute__((nonnull)) to support correctly
>> modeling
>> the no-arguments case. Don't expand this to an __attribute__((nonnull(A,
>> B,
>> C))) attribute, since that does the wrong thing for function templates and
>> varargs functions.
>>
>> In passing, fix a grammar error in the diagnostic, a crash if
>> __attribute__((nonnull(N))) is applied to a varargs function,
>> a bug where the same null argument could be diagnosed multiple
>> times if there were multiple nonnull attributes referring to it,
>> and a bug where nonnull attributes would not be accumulated correctly
>> across redeclarations.
>>
>> Modified:
>>     cfe/trunk/include/clang/Basic/Attr.td
>>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>     cfe/trunk/include/clang/Sema/Sema.h
>>     cfe/trunk/lib/Sema/SemaChecking.cpp
>>     cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>>     cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
>>     cfe/trunk/test/Sema/nonnull.c
>>     cfe/trunk/test/Sema/static-array.c
>>     cfe/trunk/test/SemaCXX/attr-nonnull.cpp
>>     cfe/trunk/test/SemaCXX/nonnull.cpp
>>     cfe/trunk/test/SemaObjC/nonnull.m
>>
>> Modified: cfe/trunk/include/clang/Basic/Attr.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/Attr.td (original)
>> +++ cfe/trunk/include/clang/Basic/Attr.td Tue Aug 26 23:59:42 2014
>> @@ -845,11 +845,15 @@ def NonNull : InheritableAttr {
>>    let Args = [VariadicUnsignedArgument<"Args">];
>>    let AdditionalMembers =
>>  [{bool isNonNull(unsigned idx) const {
>> +    if (!args_size())
>> +      return true;
>>      for (const auto &V : args())
>>        if (V == idx)
>>          return true;
>>      return false;
>>    } }];
>> +  // FIXME: We should merge duplicates into a single nonnull attribute.
>> +  let DuplicatesAllowedWhileMerging = 1;
>>    let Documentation = [Undocumented];
>>  }
>>
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 26
>> 23:59:42 2014
>> @@ -6470,7 +6470,7 @@ def note_format_fix_specifier : Note<"di
>>  def note_printf_c_str: Note<"did you mean to call the %0 method?">;
>>
>>  def warn_null_arg : Warning<
>> -  "null passed to a callee which requires a non-null argument">,
>> +  "null passed to a callee that requires a non-null argument">,
>>    InGroup<NonNull>;
>>  def warn_null_ret : Warning<
>>    "null returned from %select{function|method}0 that requires a non-null
>> return value">,
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Tue Aug 26 23:59:42 2014
>> @@ -129,7 +129,6 @@ namespace clang {
>>    class ModuleLoader;
>>    class MultiLevelTemplateArgumentList;
>>    class NamedDecl;
>> -  class NonNullAttr;
>>    class ObjCCategoryDecl;
>>    class ObjCCategoryImplDecl;
>>    class ObjCCompatibleAliasDecl;
>> @@ -2706,6 +2705,9 @@ public:
>>
>>    void checkUnusedDeclAttributes(Declarator &D);
>>
>> +  /// Determine if type T is a valid subject for a nonnull attribute.
>> +  bool isValidNonNullAttrType(QualType T);
>> +
>>    bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
>>    bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
>>                              const FunctionDecl *FD = nullptr);
>>
>> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Aug 26 23:59:42 2014
>> @@ -764,12 +764,26 @@ static void CheckNonNullArgument(Sema &S
>>
>>  static void CheckNonNullArguments(Sema &S,
>>                                    const NamedDecl *FDecl,
>> -                                  const Expr * const *ExprArgs,
>> +                                  ArrayRef<const Expr *> Args,
>>                                    SourceLocation CallSiteLoc) {
>>    // Check the attributes attached to the method/function itself.
>> +  llvm::SmallBitVector NonNullArgs;
>>    for (const auto *NonNull : FDecl->specific_attrs<NonNullAttr>()) {
>> -    for (const auto &Val : NonNull->args())
>> -      CheckNonNullArgument(S, ExprArgs[Val], CallSiteLoc);
>> +    if (!NonNull->args_size()) {
>> +      // Easy case: all pointer arguments are nonnull.
>> +      for (const auto *Arg : Args)
>> +        if (S.isValidNonNullAttrType(Arg->getType()))
>> +          CheckNonNullArgument(S, Arg, CallSiteLoc);
>> +      return;
>> +    }
>> +
>> +    for (unsigned Val : NonNull->args()) {
>> +      if (Val >= Args.size())
>> +        continue;
>> +      if (NonNullArgs.empty())
>> +        NonNullArgs.resize(Args.size());
>> +      NonNullArgs.set(Val);
>> +    }
>>    }
>>
>>    // Check the attributes on the parameters.
>> @@ -779,13 +793,19 @@ static void CheckNonNullArguments(Sema &
>>    else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(FDecl))
>>      parms = MD->parameters();
>>
>> -  unsigned argIndex = 0;
>> +  unsigned ArgIndex = 0;
>>    for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E =
>> parms.end();
>> -       I != E; ++I, ++argIndex) {
>> +       I != E; ++I, ++ArgIndex) {
>>      const ParmVarDecl *PVD = *I;
>> -    if (PVD->hasAttr<NonNullAttr>())
>> -      CheckNonNullArgument(S, ExprArgs[argIndex], CallSiteLoc);
>> +    if (PVD->hasAttr<NonNullAttr>() ||
>> +        (ArgIndex < NonNullArgs.size() && NonNullArgs[ArgIndex]))
>> +      CheckNonNullArgument(S, Args[ArgIndex], CallSiteLoc);
>>    }
>> +
>> +  // In case this is a variadic call, check any remaining arguments.
>> +  for (/**/; ArgIndex < NonNullArgs.size(); ++ArgIndex)
>> +    if (NonNullArgs[ArgIndex])
>> +      CheckNonNullArgument(S, Args[ArgIndex], CallSiteLoc);
>>  }
>>
>>  /// Handles the checks for format strings, non-POD arguments to vararg
>> @@ -823,7 +843,7 @@ void Sema::checkCall(NamedDecl *FDecl, A
>>    }
>>
>>    if (FDecl) {
>> -    CheckNonNullArguments(*this, FDecl, Args.data(), Loc);
>> +    CheckNonNullArguments(*this, FDecl, Args, Loc);
>>
>>      // Type safety checking.
>>      for (const auto *I :
>> FDecl->specific_attrs<ArgumentWithTypeTagAttr>())
>>
>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Aug 26 23:59:42 2014
>> @@ -1125,28 +1125,30 @@ static void handleIBOutletCollection(Sem
>>
>>  Attr.getAttributeSpellingListIndex()));
>>  }
>>
>> -static void possibleTransparentUnionPointerType(QualType &T) {
>> -  if (const RecordType *UT = T->getAsUnionType())
>> +bool Sema::isValidNonNullAttrType(QualType T) {
>> +  T = T.getNonReferenceType();
>> +
>> +  // The nonnull attribute can be applied to a transparent union that
>> +  // contains a pointer type.
>> +  if (const RecordType *UT = T->getAsUnionType()) {
>>      if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
>>        RecordDecl *UD = UT->getDecl();
>>        for (const auto *I : UD->fields()) {
>>          QualType QT = I->getType();
>> -        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
>> -          T = QT;
>> -          return;
>> -        }
>> +        if (QT->isAnyPointerType() || QT->isBlockPointerType())
>> +          return true;
>>        }
>>      }
>> +  }
>> +
>> +  return T->isAnyPointerType() || T->isBlockPointerType();
>>  }
>>
>>  static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList
>> &Attr,
>>                                  SourceRange AttrParmRange,
>>                                  SourceRange NonNullTypeRange,
>>                                  bool isReturnValue = false) {
>> -  T = T.getNonReferenceType();
>> -  possibleTransparentUnionPointerType(T);
>> -
>> -  if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
>> +  if (!S.isValidNonNullAttrType(T)) {
>>      S.Diag(Attr.getLoc(), isReturnValue
>>                                ? diag::warn_attribute_return_pointers_only
>>                                : diag::warn_attribute_pointers_only)
>> @@ -1158,14 +1160,15 @@ static bool attrNonNullArgCheck(Sema &S,
>>
>>  static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList
>> &Attr) {
>>    SmallVector<unsigned, 8> NonNullArgs;
>> -  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
>> -    Expr *Ex = Attr.getArgAsExpr(i);
>> +  for (unsigned I = 0; I < Attr.getNumArgs(); ++I) {
>> +    Expr *Ex = Attr.getArgAsExpr(I);
>>      uint64_t Idx;
>> -    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, i + 1, Ex, Idx))
>> +    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, I + 1, Ex, Idx))
>>        return;
>>
>>      // Is the function argument a pointer type?
>> -    if (!attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx),
>> Attr,
>> +    if (Idx < getFunctionOrMethodNumParams(D) &&
>> +        !attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx),
>> Attr,
>>                               Ex->getSourceRange(),
>>                               getFunctionOrMethodParamRange(D, Idx)))
>>        continue;
>> @@ -1174,30 +1177,28 @@ static void handleNonNullAttr(Sema &S, D
>>    }
>>
>>    // If no arguments were specified to __attribute__((nonnull)) then all
>> pointer
>> -  // arguments have a nonnull attribute.
>> -  if (NonNullArgs.empty()) {
>> -    for (unsigned i = 0, e = getFunctionOrMethodNumParams(D); i != e;
>> ++i) {
>> -      QualType T = getFunctionOrMethodParamType(D,
>> i).getNonReferenceType();
>> -      possibleTransparentUnionPointerType(T);
>> -      if (T->isAnyPointerType() || T->isBlockPointerType())
>> -        NonNullArgs.push_back(i);
>> +  // arguments have a nonnull attribute; warn if there aren't any. Skip
>> this
>> +  // check if the attribute came from a macro expansion or a template
>> +  // instantiation.
>> +  if (NonNullArgs.empty() && Attr.getLoc().isFileID() &&
>> +      S.ActiveTemplateInstantiations.empty()) {
>> +    bool AnyPointers = isFunctionOrMethodVariadic(D);
>> +    for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
>> +         I != E && !AnyPointers; ++I) {
>> +      QualType T = getFunctionOrMethodParamType(D, I);
>> +      if (T->isDependentType() || S.isValidNonNullAttrType(T))
>> +        AnyPointers = true;
>>      }
>>
>> -    // No pointer arguments?
>> -    if (NonNullArgs.empty()) {
>> -      // Warn the trivial case only if attribute is not coming from a
>> -      // macro instantiation.
>> -      if (Attr.getLoc().isFileID())
>> -        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
>> -      return;
>> -    }
>> +    if (!AnyPointers)
>> +      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
>>    }
>>
>> -  unsigned *start = &NonNullArgs[0];
>> -  unsigned size = NonNullArgs.size();
>> -  llvm::array_pod_sort(start, start + size);
>> +  unsigned *Start = NonNullArgs.data();
>> +  unsigned Size = NonNullArgs.size();
>> +  llvm::array_pod_sort(Start, Start + Size);
>>    D->addAttr(::new (S.Context)
>> -             NonNullAttr(Attr.getRange(), S.Context, start, size,
>> +             NonNullAttr(Attr.getRange(), S.Context, Start, Size,
>>                           Attr.getAttributeSpellingListIndex()));
>>  }
>>
>>
>> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
>> (original)
>> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp Tue Aug
>> 26 23:59:42 2014
>> @@ -49,6 +49,8 @@ void NonNullParamChecker::checkPreCall(c
>>    if (!FD)
>>      return;
>>
>> +  // FIXME: This is wrong; there can be multiple attributes with
>> different sets
>> +  // of non-null parameter indices.
>>    const NonNullAttr *Att = FD->getAttr<NonNullAttr>();
>>
>>    ProgramStateRef state = C.getState();
>>
>> Modified: cfe/trunk/test/Sema/nonnull.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/nonnull.c?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Sema/nonnull.c (original)
>> +++ cfe/trunk/test/Sema/nonnull.c Tue Aug 26 23:59:42 2014
>> @@ -15,7 +15,7 @@ __attribute__((nonnull(1))) void Class_i
>>
>>  int main(void) {
>>         Class *obj;
>> -       Class_init(0, "Hello World"); // expected-warning {{null passed
>> to a callee which requires a non-null argument}}
>> +       Class_init(0, "Hello World"); // expected-warning {{null passed
>> to a callee that requires a non-null argument}}
>>         Class_init(obj, "Hello World");
>>  }
>>
>> @@ -27,7 +27,7 @@ void baz2(__attribute__((nonnull(1))) co
>>  void baz3(__attribute__((nonnull)) int x); // expected-warning
>> {{'nonnull' attribute only applies to pointer arguments}}
>>
>>  void test_baz() {
>> -  baz(0); // expected-warning {{null passed to a callee which requires a
>> non-null argument}}
>> +  baz(0); // expected-warning {{null passed to a callee that requires a
>> non-null argument}}
>>    baz2(0); // no-warning
>>    baz3(0); // no-warning
>>  }
>> @@ -47,10 +47,39 @@ void *test_bad_returns_null(void) {
>>  }
>>
>>  void PR18795(int (*g)(const char *h, ...) __attribute__((nonnull(1)))
>> __attribute__((nonnull))) {
>> -  g(0); // expected-warning{{null passed to a callee which requires a
>> non-null argument}}
>> +  g(0); // expected-warning{{null passed to a callee that requires a
>> non-null argument}}
>>  }
>>  void PR18795_helper() {
>> -  PR18795(0); // expected-warning{{null passed to a callee which
>> requires a non-null argument}}
>> +  PR18795(0); // expected-warning{{null passed to a callee that requires
>> a non-null argument}}
>>  }
>>
>> +void vararg1(int n, ...) __attribute__((nonnull(2)));
>> +void vararg1_test() {
>> +  vararg1(0);
>> +  vararg1(1, (void*)0); // expected-warning{{null passed}}
>> +  vararg1(2, (void*)0, (void*)0); // expected-warning{{null passed}}
>> +  vararg1(2, (void*)&vararg1, (void*)0);
>> +}
>> +
>> +void vararg2(int n, ...) __attribute__((nonnull, nonnull, nonnull));
>> +void vararg2_test() {
>> +  vararg2(0);
>> +  vararg2(1, (void*)0); // expected-warning{{null passed}}
>> +  vararg2(2, (void*)0, (void*)0); // expected-warning 2{{null passed}}
>> +}
>>
>> +void vararg3(int n, ...) __attribute__((nonnull, nonnull(2),
>> nonnull(3)));
>> +void vararg3_test() {
>> +  vararg3(0);
>> +  vararg3(1, (void*)0); // expected-warning{{null passed}}
>> +  vararg3(2, (void*)0, (void*)0); // expected-warning 2{{null passed}}
>> +}
>> +
>> +void redecl(void *, void *);
>> +void redecl(void *, void *) __attribute__((nonnull(1)));
>> +void redecl(void *, void *) __attribute__((nonnull(2)));
>> +void redecl(void *, void *);
>> +void redecl_test(void *p) {
>> +  redecl(p, 0); // expected-warning{{null passed}}
>> +  redecl(0, p); // expected-warning{{null passed}}
>> +}
>>
>> Modified: cfe/trunk/test/Sema/static-array.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-array.c?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Sema/static-array.c (original)
>> +++ cfe/trunk/test/Sema/static-array.c Tue Aug 26 23:59:42 2014
>> @@ -11,13 +11,13 @@ void f(int *p) {
>>
>>    cat0(0);
>>
>> -  cat(0); // expected-warning {{null passed to a callee which requires a
>> non-null argument}}
>> +  cat(0); // expected-warning {{null passed to a callee that requires a
>> non-null argument}}
>>    cat(a); // expected-warning {{array argument is too small; contains 2
>> elements, callee requires at least 3}}
>>    cat(b);
>>    cat(c);
>>    cat(p);
>>
>> -  vat(1, 0); // expected-warning {{null passed to a callee which
>> requires a non-null argument}}
>> +  vat(1, 0); // expected-warning {{null passed to a callee that requires
>> a non-null argument}}
>>    vat(3, b);
>>  }
>>
>>
>> Modified: cfe/trunk/test/SemaCXX/attr-nonnull.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-nonnull.cpp?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/attr-nonnull.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/attr-nonnull.cpp Tue Aug 26 23:59:42 2014
>> @@ -27,8 +27,8 @@ namespace rdar8769025 {
>>    __attribute__((nonnull(2))) void f2(int i, int * const &p);
>>
>>    void test_f1() {
>> -    f1(0); // expected-warning{{null passed to a callee which requires a
>> non-null argument}}
>> -    f2(0, 0); // expected-warning{{null passed to a callee which
>> requires a non-null argument}}
>> +    f1(0); // expected-warning{{null passed to a callee that requires a
>> non-null argument}}
>> +    f2(0, 0); // expected-warning{{null passed to a callee that requires
>> a non-null argument}}
>>    }
>>  }
>>
>>
>> Modified: cfe/trunk/test/SemaCXX/nonnull.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nonnull.cpp?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/nonnull.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/nonnull.cpp Tue Aug 26 23:59:42 2014
>> @@ -13,3 +13,8 @@ struct TS {
>>    }
>>  };
>>
>> +namespace Template {
>> +  template<typename T> __attribute__((nonnull)) void f(T t);
>> +  void g() { f((void*)0); } // expected-warning {{null passed to a
>> callee that requires a non-null argument}}
>> +  void h() { f(0); }
>> +}
>>
>> Modified: cfe/trunk/test/SemaObjC/nonnull.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/nonnull.m?rev=216520&r1=216519&r2=216520&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaObjC/nonnull.m (original)
>> +++ cfe/trunk/test/SemaObjC/nonnull.m Tue Aug 26 23:59:42 2014
>> @@ -31,16 +31,16 @@ foo (int i1, int i2, int i3, void (^cp1)
>>  {
>>    func1(cp1, cp2, i1);
>>
>> -  func1(0, cp2, i1);  // expected-warning {{null passed to a callee
>> which requires a non-null argument}}
>> -  func1(cp1, 0, i1);  // expected-warning {{null passed to a callee
>> which requires a non-null argument}}
>> +  func1(0, cp2, i1);  // expected-warning {{null passed to a callee that
>> requires a non-null argument}}
>> +  func1(cp1, 0, i1);  // expected-warning {{null passed to a callee that
>> requires a non-null argument}}
>>    func1(cp1, cp2, 0);
>>
>>
>> -  func3(0, i2, cp3, i3); // expected-warning {{null passed to a callee
>> which requires a non-null argument}}
>> -  func3(cp3, i2, 0, i3);  // expected-warning {{null passed to a callee
>> which requires a non-null argument}}
>> +  func3(0, i2, cp3, i3); // expected-warning {{null passed to a callee
>> that requires a non-null argument}}
>> +  func3(cp3, i2, 0, i3);  // expected-warning {{null passed to a callee
>> that requires a non-null argument}}
>>
>> -  func4(0, cp1); // expected-warning {{null passed to a callee which
>> requires a non-null argument}}
>> -  func4(cp1, 0); // expected-warning {{null passed to a callee which
>> requires a non-null argument}}
>> +  func4(0, cp1); // expected-warning {{null passed to a callee that
>> requires a non-null argument}}
>> +  func4(cp1, 0); // expected-warning {{null passed to a callee that
>> requires a non-null argument}}
>>
>>    // Shouldn't these emit warnings?  Clang doesn't, and neither does
>> GCC.  It
>>    // seems that the checking should handle Objective-C pointers.
>> @@ -64,7 +64,7 @@ __attribute__((nonnull))
>>  void _dispatch_queue_push_list(dispatch_object_t _head); // no warning
>>
>>  void func6(dispatch_object_t _head) {
>> -  _dispatch_queue_push_list(0); // expected-warning {{null passed to a
>> callee which requires a non-null argument}}
>> +  _dispatch_queue_push_list(0); // expected-warning {{null passed to a
>> callee that requires a non-null argument}}
>>    _dispatch_queue_push_list(_head._do);  // no warning
>>  }
>>
>> @@ -91,10 +91,10 @@ extern void DoSomethingNotNull(void *db)
>>  @implementation IMP
>>  - (void) Meth {
>>    NSObject *object;
>> -  [object doSomethingWithNonNullPointer:NULL:1:NULL]; //
>> expected-warning 2 {{null passed to a callee which requires a non-null
>> argument}}
>> -  [object doSomethingWithNonNullPointer:vp:1:NULL]; // expected-warning
>> {{null passed to a callee which requires a non-null argument}}
>> -  [NSObject doSomethingClassyWithNonNullPointer:NULL]; //
>> expected-warning {{null passed to a callee which requires a non-null
>> argument}}
>> -  DoSomethingNotNull(NULL); // expected-warning {{null passed to a
>> callee which requires a non-null argument}}
>> +  [object doSomethingWithNonNullPointer:NULL:1:NULL]; //
>> expected-warning 2 {{null passed to a callee that requires a non-null
>> argument}}
>> +  [object doSomethingWithNonNullPointer:vp:1:NULL]; // expected-warning
>> {{null passed to a callee that requires a non-null argument}}
>> +  [NSObject doSomethingClassyWithNonNullPointer:NULL]; //
>> expected-warning {{null passed to a callee that requires a non-null
>> argument}}
>> +  DoSomethingNotNull(NULL); // expected-warning {{null passed to a
>> callee that requires a non-null argument}}
>>    [object doSomethingWithNonNullPointer:vp:1:vp];
>>  }
>>  - (void*) testRetNull {
>> @@ -111,15 +111,15 @@ __attribute__((objc_root_class))
>>  @end
>>
>>  void test(TestNonNullParameters *f) {
>> -  [f doNotPassNullParameter:0]; // expected-warning {{null passed to a
>> callee which requires a non-null argument}}
>> +  [f doNotPassNullParameter:0]; // expected-warning {{null passed to a
>> callee that requires a non-null argument}}
>>    [f doNotPassNullParameterArgIndex:0]; // no-warning
>> -  [f doNotPassNullOnMethod:0]; // expected-warning {{null passed to a
>> callee which requires a non-null argument}}
>> +  [f doNotPassNullOnMethod:0]; // expected-warning {{null passed to a
>> callee that requires a non-null argument}}
>>  }
>>
>>
>>  void PR18795(int (^g)(const char *h, ...) __attribute__((nonnull(1)))
>> __attribute__((nonnull))) {
>> -  g(0); // expected-warning{{null passed to a callee which requires a
>> non-null argument}}
>> +  g(0); // expected-warning{{null passed to a callee that requires a
>> non-null argument}}
>>  }
>>  void PR18795_helper() {
>> -  PR18795(0); // expected-warning{{null passed to a callee which
>> requires a non-null argument}}
>> +  PR18795(0); // expected-warning{{null passed to a callee that requires
>> a non-null argument}}
>>  }
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
>
> --
> Alexey Samsonov
> vonosmas at gmail.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140827/1e37ac78/attachment.html>


More information about the cfe-commits mailing list