r222009 - [Sema]. Warn when logical expression is a pointer

Timur Iskhodzhanov timurrrr at google.com
Mon Nov 17 07:18:43 PST 2014


Hi,

This has broken our -Werror internal build.
One specific thing that I consider a [noisy] false positive:

#define MY_ASSERT(cond) ((cond)? (void)0 : blah)
#define BUG(description) MY_ASSERT(!description)
...
if (some_condition)
  BUG("oh this is broken")

On Fri Nov 14 2014 at 8:16:22 PM Fariborz Jahanian <fjahanian at apple.com>
wrote:

> Author: fjahanian
> Date: Fri Nov 14 11:12:50 2014
> New Revision: 222009
>
> URL: http://llvm.org/viewvc/llvm-project?rev=222009&view=rev
> Log:
> [Sema]. Warn when logical expression is a pointer
> which evaluates to true. rdar://18716393.
> Reviewed by Richard Trieu
>
> Added:
>     cfe/trunk/test/Sema/warn-tautological-compare.c
> Modified:
>     cfe/trunk/include/clang/Sema/Sema.h
>     cfe/trunk/lib/Sema/SemaChecking.cpp
>     cfe/trunk/lib/Sema/SemaExpr.cpp
>     cfe/trunk/test/Analysis/NSContainers.m
>     cfe/trunk/test/Analysis/logical-ops.c
>     cfe/trunk/test/Analysis/objc-boxing.m
>     cfe/trunk/test/Sema/exprs.c
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Sema.h?rev=222009&r1=222008&r2=222009&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Nov 14 11:12:50 2014
> @@ -2771,6 +2771,8 @@ public:
>                                        const AttributeList *AttrList);
>
>    void checkUnusedDeclAttributes(Declarator &D);
> +
> +  void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
>
>    /// Determine if type T is a valid subject for a nonnull and similar
>    /// attributes. By default, we look through references (the behavior
> used by
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaChecking.cpp?rev=222009&r1=222008&r2=222009&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Nov 14 11:12:50 2014
> @@ -6559,6 +6559,13 @@ void AnalyzeImplicitConversions(Sema &S,
>        continue;
>      AnalyzeImplicitConversions(S, ChildExpr, CC);
>    }
> +  if (BO && BO->isLogicalOp()) {
> +    S.CheckBoolLikeConversion(BO->getLHS(), BO->getLHS()->getExprLoc());
> +    S.CheckBoolLikeConversion(BO->getRHS(), BO->getRHS()->getExprLoc());
> +  }
> +  if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E))
> +    if (U->getOpcode() == UO_LNot)
> +      S.CheckBoolLikeConversion(U->getSubExpr(), CC);
>  }
>
>  } // end anonymous namespace
> @@ -6617,6 +6624,18 @@ static bool IsInAnyMacroBody(const Sourc
>    return false;
>  }
>
> +/// CheckBoolLikeConversion - Check conversion of given expression to
> boolean.
> +/// Input argument E is a logical expression.
> +static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
> +  if (S.getLangOpts().Bool)
> +    return;
> +  CheckImplicitConversion(S, E->IgnoreParenImpCasts(), S.Context.BoolTy,
> CC);
> +}
> +
> +void Sema::CheckBoolLikeConversion(Expr *E, SourceLocation CC) {
> +  ::CheckBoolLikeConversion(*this, E, CC);
> +}
> +
>  /// \brief Diagnose pointers that are always non-null.
>  /// \param E the expression containing the pointer
>  /// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaExpr.cpp?rev=222009&r1=222008&r2=222009&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Nov 14 11:12:50 2014
> @@ -12984,6 +12984,7 @@ ExprResult Sema::CheckBooleanCondition(E
>          << T << E->getSourceRange();
>        return ExprError();
>      }
> +    CheckBoolLikeConversion(E, Loc);
>    }
>
>    return E;
>
> Modified: cfe/trunk/test/Analysis/NSContainers.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> Analysis/NSContainers.m?rev=222009&r1=222008&r2=222009&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Analysis/NSContainers.m (original)
> +++ cfe/trunk/test/Analysis/NSContainers.m Fri Nov 14 11:12:50 2014
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.
> cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection
> -verify -Wno-objc-root-class %s
> +// RUN: %clang_cc1  -Wno-objc-literal-conversion -analyze
> -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.
> cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify
> -Wno-objc-root-class %s
>
>  void clang_analyzer_eval(int);
>
>
> Modified: cfe/trunk/test/Analysis/logical-ops.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> Analysis/logical-ops.c?rev=222009&r1=222008&r2=222009&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Analysis/logical-ops.c (original)
> +++ cfe/trunk/test/Analysis/logical-ops.c Fri Nov 14 11:12:50 2014
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection
> -verify %s
> +// RUN: %clang_cc1 -Wno-pointer-bool-conversion -analyze
> -analyzer-checker=core,debug.ExprInspection -verify %s
>
>  void clang_analyzer_eval(int);
>
>
> Modified: cfe/trunk/test/Analysis/objc-boxing.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> Analysis/objc-boxing.m?rev=222009&r1=222008&r2=222009&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Analysis/objc-boxing.m (original)
> +++ cfe/trunk/test/Analysis/objc-boxing.m Fri Nov 14 11:12:50 2014
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,osx.cocoa.
> NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s
> +// RUN: %clang_cc1 -Wno-objc-literal-conversion -analyze
> -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection
> -analyzer-store=region -verify %s
>
>  void clang_analyzer_eval(int);
>
>
> Modified: cfe/trunk/test/Sema/exprs.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/
> exprs.c?rev=222009&r1=222008&r2=222009&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/exprs.c (original)
> +++ cfe/trunk/test/Sema/exprs.c Fri Nov 14 11:12:50 2014
> @@ -244,6 +244,10 @@ void test22() {
>    if ("help")
>      (void) 0;
>
> -  if (test22)
> +  if (test22) // expected-warning {{address of function 'test22' will
> always evaluate to 'true'}} \
> +             // expected-note {{prefix with the address-of operator to
> silence this warning}}
> +    (void) 0;
> +
> +  if (&test22)
>      (void) 0;
>  }
>
> Added: cfe/trunk/test/Sema/warn-tautological-compare.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/
> warn-tautological-compare.c?rev=222009&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/warn-tautological-compare.c (added)
> +++ cfe/trunk/test/Sema/warn-tautological-compare.c Fri Nov 14 11:12:50
> 2014
> @@ -0,0 +1,80 @@
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify  %s
> +// rdar://18716393
> +
> +extern int a[] __attribute__((weak));
> +int b[] = {8,13,21};
> +struct {
> +  int x[10];
> +} c;
> +const char str[] = "text";
> +
> +void ignore() {
> +  if (!a) {}
> +}
> +void test() {
> +  if (!b) {} // expected-warning {{address of array 'b' will always
> evaluate to 'true'}}
> +  if (b == 0) {} // expected-warning {{comparison of array 'b' equal to a
> null pointer is always false}}
> +  if (!c.x) {} // expected-warning {{address of array 'c.x' will always
> evaluate to 'true'}}
> +  if (c.x == 0) {} // expected-warning {{comparison of array 'c.x' equal
> to a null pointer is always false}}
> +  if (!str) {} // expected-warning {{address of array 'str' will always
> evaluate to 'true'}}
> +  if (0 == str) {} // expected-warning {{comparison of array 'str' equal
> to a null pointer is always false}}
> +}
> +
> +int array[2];
> +int test1()
> +{
> +  if (!array) { // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +    return array[0];
> +  } else if (array != 0) { // expected-warning {{comparison of array
> 'array' not equal to a null pointer is always true}}
> +    return array[1];
> +  }
> +  if (array == 0) // expected-warning {{comparison of array 'array' equal
> to a null pointer is always false}}
> +    return 1;
> +  return 0;
> +}
> +
> +#define NULL (void*)0
> +
> +int test2(int* pointer, char ch, void * pv) {
> +   if (!&pointer) {  // expected-warning {{address of 'pointer' will
> always evaluate to 'true'}}
> +     return 0;
> +   }
> +
> +   if (&pointer) {  // expected-warning {{address of 'pointer' will
> always evaluate to 'true'}}
> +     return 0;
> +   }
> +
> +   if (&pointer == NULL) {} // expected-warning {{comparison of address
> of 'pointer' equal to a null pointer is always false}}
> +
> +   if (&pointer != NULL) {} // expected-warning {{comparison of address
> of 'pointer' not equal to a null pointer is always true}}
> +
> +   return 1;
> +}
> +
> +void test3() {
> +   if (array) { } // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +   if (array != 0) {} // expected-warning {{comparison of array 'array'
> not equal to a null pointer is always true}}
> +   if (!array) { } // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +   if (array == 0) {} // expected-warning {{comparison of array 'array'
> equal to a null pointer is always false}}
> +
> +   if (array[0] &&
> +       array) {} // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +
> +   if (array[0] ||
> +       array) {} // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +
> +   if (array[0] &&
> +       !array) {} // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +   if (array[0] ||
> +       !array) {} // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +
> +   if (array && // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +       array[0]) {}
> +   if (!array || // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +       array[0]) {}
> +
> +   if (array ||  // expected-warning {{address of array 'array' will
> always evaluate to 'true'}}
> +       (!array && array[0])) {} // expected-warning {{address of array
> 'array' will always evaluate to 'true'}}
> + }
> +
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141117/b907d91c/attachment.html>


More information about the cfe-commits mailing list