r202216 - PR16074, implement warnings to catch pointer to boolean true and pointer to

Richard Trieu rtrieu at google.com
Tue Feb 25 18:36:06 PST 2014


Author: rtrieu
Date: Tue Feb 25 20:36:06 2014
New Revision: 202216

URL: http://llvm.org/viewvc/llvm-project?rev=202216&view=rev
Log:
PR16074, implement warnings to catch pointer to boolean true and pointer to
null comparison when the pointer is known to be non-null.

This catches the array to pointer decay, function to pointer decay and
address of variables.  This does not catch address of function since this
has been previously used to silence a warning.

Pointer to bool conversion is under -Wbool-conversion.
Pointer to null comparison is under -Wtautological-pointer-compare, a sub-group
of -Wtautological-compare.

void foo() {
  int arr[5];
  int x;
  // warn on these conditionals
  if (foo);
  if (arr);
  if (&x);
  if (foo == null);
  if (arr == null);
  if (&x == null);

  if (&foo);  // no warning
}

Removed:
    cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.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/SemaExpr.cpp
    cfe/trunk/test/Analysis/casts.c
    cfe/trunk/test/Analysis/ptr-arith.c
    cfe/trunk/test/Analysis/stackaddrleak.c
    cfe/trunk/test/Analysis/weak-functions.c
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
    cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
    cfe/trunk/test/Sema/const-eval.c
    cfe/trunk/test/Sema/static-init.c
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
    cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
    cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp
    cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp
    cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Feb 25 20:36:06 2014
@@ -285,8 +285,10 @@ def StringPlusInt : DiagGroup<"string-pl
 def StringPlusChar : DiagGroup<"string-plus-char">;
 def StrncatSize : DiagGroup<"strncat-size">;
 def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
+def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
 def TautologicalCompare : DiagGroup<"tautological-compare",
-                                    [TautologicalOutOfRangeCompare]>;
+                                    [TautologicalOutOfRangeCompare,
+                                     TautologicalPointerCompare]>;
 def HeaderHygiene : DiagGroup<"header-hygiene">;
 def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
 def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 25 20:36:06 2014
@@ -2322,12 +2322,19 @@ def warn_impcast_null_pointer_to_integer
 def warn_impcast_floating_point_to_bool : Warning<
     "implicit conversion turns floating-point number into bool: %0 to %1">,
     InGroup<ImplicitConversionFloatingPointToBool>;
-def warn_impcast_function_to_bool : Warning<
-    "address of function %q0 will always evaluate to 'true'">,
+
+def warn_impcast_pointer_to_bool : Warning<
+    "address of%select{| function| array}0 '%1' will always evaluate to "
+    "'true'">,
     InGroup<BoolConversion>;
-def note_function_to_bool_silence : Note<
+def warn_null_pointer_compare : Warning<
+    "comparison of %select{address of|function|array}0 '%1' %select{not |}2"
+    "equal to a null pointer is always %select{true|false}2">,
+    InGroup<TautologicalPointerCompare>;
+
+def note_function_warning_silence : Note<
     "prefix with the address-of operator to silence this warning">;
-def note_function_to_bool_call : Note<
+def note_function_to_function_call : Note<
     "suffix with parentheses to turn this into a function call">;
 def warn_impcast_objective_c_literal_to_bool : Warning<
     "implicit boolean conversion of Objective-C object literal always "

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Feb 25 20:36:06 2014
@@ -7470,6 +7470,10 @@ public:
   bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
                                   SourceLocation QuestionLoc);
 
+  void DiagnoseAlwaysNonNullPointer(Expr *E,
+                                    Expr::NullPointerConstantKind NullType,
+                                    bool IsEqual, SourceRange Range);
+
   /// type checking for vector binary operators.
   QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
                                SourceLocation Loc, bool IsCompAssign);

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Feb 25 20:36:06 2014
@@ -5690,35 +5690,10 @@ void CheckImplicitConversion(Sema &S, Ex
       return DiagnoseImpCast(S, E, T, CC,
                              diag::warn_impcast_objective_c_literal_to_bool);
     }
-    if (Source->isFunctionType()) {
-      // Warn on function to bool. Checks free functions and static member
-      // functions. Weakly imported functions are excluded from the check,
-      // since it's common to test their value to check whether the linker
-      // found a definition for them.
-      ValueDecl *D = 0;
-      if (DeclRefExpr* R = dyn_cast<DeclRefExpr>(E)) {
-        D = R->getDecl();
-      } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {
-        D = M->getMemberDecl();
-      }
-
-      if (D && !D->isWeak()) {
-        if (FunctionDecl* F = dyn_cast<FunctionDecl>(D)) {
-          S.Diag(E->getExprLoc(), diag::warn_impcast_function_to_bool)
-            << F << E->getSourceRange() << SourceRange(CC);
-          S.Diag(E->getExprLoc(), diag::note_function_to_bool_silence)
-            << FixItHint::CreateInsertion(E->getExprLoc(), "&");
-          QualType ReturnType;
-          UnresolvedSet<4> NonTemplateOverloads;
-          S.tryExprAsCall(*E, ReturnType, NonTemplateOverloads);
-          if (!ReturnType.isNull() 
-              && ReturnType->isSpecificBuiltinType(BuiltinType::Bool))
-            S.Diag(E->getExprLoc(), diag::note_function_to_bool_call)
-              << FixItHint::CreateInsertion(
-                 S.getPreprocessor().getLocForEndOfToken(E->getLocEnd()), "()");
-          return;
-        }
-      }
+    if (Source->isPointerType() || Source->canDecayToPointerType()) {
+      // Warn on pointer to bool conversion that is always true.
+      S.DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, /*IsEqual*/ false,
+                                     SourceRange(CC));
     }
   }
 
@@ -6055,6 +6030,125 @@ void AnalyzeImplicitConversions(Sema &S,
 
 } // end anonymous namespace
 
+enum {
+  AddressOf,
+  FunctionPointer,
+  ArrayPointer
+};
+
+/// \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
+/// compared to a null pointer
+/// \param IsEqual True when the comparison is equal to a null pointer
+/// \param Range Extra SourceRange to highlight in the diagnostic
+void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
+                                        Expr::NullPointerConstantKind NullKind,
+                                        bool IsEqual, SourceRange Range) {
+
+  // Don't warn inside macros.
+  if (E->getExprLoc().isMacroID())
+      return;
+  E = E->IgnoreImpCasts();
+
+  const bool IsCompare = NullKind != Expr::NPCK_NotNull;
+
+  bool IsAddressOf = false;
+
+  if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
+    if (UO->getOpcode() != UO_AddrOf)
+      return;
+    IsAddressOf = true;
+    E = UO->getSubExpr();
+  }
+
+  // Expect to find a single Decl.  Skip anything more complicated.
+  ValueDecl *D = 0;
+  if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) {
+    D = R->getDecl();
+  } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {
+    D = M->getMemberDecl();
+  }
+
+  // Weak Decls can be null.
+  if (!D || D->isWeak())
+    return;
+
+  QualType T = D->getType();
+  const bool IsArray = T->isArrayType();
+  const bool IsFunction = T->isFunctionType();
+
+  if (IsAddressOf) {
+    // Address of function is used to silence the function warning.
+    if (IsFunction)
+      return;
+    // Address of reference can be null.
+    if (T->isReferenceType())
+      return;
+  }
+
+  // Found nothing.
+  if (!IsAddressOf && !IsFunction && !IsArray)
+    return;
+
+  // Pretty print the expression for the diagnostic.
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  E->printPretty(S, 0, getPrintingPolicy());
+
+  unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
+                              : diag::warn_impcast_pointer_to_bool;
+  unsigned DiagType;
+  if (IsAddressOf)
+    DiagType = AddressOf;
+  else if (IsFunction)
+    DiagType = FunctionPointer;
+  else if (IsArray)
+    DiagType = ArrayPointer;
+  else
+    llvm_unreachable("Could not determine diagnostic.");
+  Diag(E->getExprLoc(), DiagID) << DiagType << S.str() << E->getSourceRange()
+                                << Range << IsEqual;
+
+  if (!IsFunction)
+    return;
+
+  // Suggest '&' to silence the function warning.
+  Diag(E->getExprLoc(), diag::note_function_warning_silence)
+      << FixItHint::CreateInsertion(E->getLocStart(), "&");
+
+  // Check to see if '()' fixit should be emitted.
+  QualType ReturnType;
+  UnresolvedSet<4> NonTemplateOverloads;
+  tryExprAsCall(*E, ReturnType, NonTemplateOverloads);
+  if (ReturnType.isNull())
+    return;
+
+  if (IsCompare) {
+    // There are two cases here.  If there is null constant, the only suggest
+    // for a pointer return type.  If the null is 0, then suggest if the return
+    // type is a pointer or an integer type.
+    if (!ReturnType->isPointerType()) {
+      if (NullKind == Expr::NPCK_ZeroExpression ||
+          NullKind == Expr::NPCK_ZeroLiteral) {
+        if (!ReturnType->isIntegerType())
+          return;
+      } else {
+        return;
+      }
+    }
+  } else { // !IsCompare
+    // For function to bool, only suggest if the function pointer has bool
+    // return type.
+    if (!ReturnType->isSpecificBuiltinType(BuiltinType::Bool))
+      return;
+  }
+  Diag(E->getExprLoc(), diag::note_function_to_function_call)
+      << FixItHint::CreateInsertion(
+             getPreprocessor().getLocForEndOfToken(E->getLocEnd()), "()");
+}
+
+
 /// Diagnoses "dangerous" implicit conversions within the given
 /// expression (which is a full expression).  Implements -Wconversion
 /// and -Wsign-compare.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Feb 25 20:36:06 2014
@@ -7867,10 +7867,22 @@ QualType Sema::CheckCompareOperands(Expr
       return ResultTy;
   }
 
-  bool LHSIsNull = LHS.get()->isNullPointerConstant(Context,
-                                              Expr::NPC_ValueDependentIsNull);
-  bool RHSIsNull = RHS.get()->isNullPointerConstant(Context,
-                                              Expr::NPC_ValueDependentIsNull);
+  const Expr::NullPointerConstantKind LHSNullKind =
+      LHS.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull);
+  const Expr::NullPointerConstantKind RHSNullKind =
+      RHS.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull);
+  bool LHSIsNull = LHSNullKind != Expr::NPCK_NotNull;
+  bool RHSIsNull = RHSNullKind != Expr::NPCK_NotNull;
+
+  if (!IsRelational && LHSIsNull != RHSIsNull) {
+    bool IsEquality = Opc == BO_EQ;
+    if (RHSIsNull)
+      DiagnoseAlwaysNonNullPointer(LHS.get(), RHSNullKind, IsEquality,
+                                   RHS.get()->getSourceRange());
+    else
+      DiagnoseAlwaysNonNullPointer(RHS.get(), LHSNullKind, IsEquality,
+                                   LHS.get()->getSourceRange());
+  }
 
   // All of the following pointer-related warnings are GCC extensions, except
   // when handling null pointer constants. 

Modified: cfe/trunk/test/Analysis/casts.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/casts.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/casts.c (original)
+++ cfe/trunk/test/Analysis/casts.c Tue Feb 25 20:36:06 2014
@@ -110,7 +110,8 @@ void castsToBool() {
     clang_analyzer_eval(symbolicPointer); // expected-warning{{TRUE}}
 
   int localInt;
-  clang_analyzer_eval(&localInt); // expected-warning{{TRUE}}
+  int* ptr = &localInt;
+  clang_analyzer_eval(ptr); // expected-warning{{TRUE}}
   clang_analyzer_eval(&castsToBool); // expected-warning{{TRUE}}
   clang_analyzer_eval("abc"); // expected-warning{{TRUE}}
 

Modified: cfe/trunk/test/Analysis/ptr-arith.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ptr-arith.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/ptr-arith.c (original)
+++ cfe/trunk/test/Analysis/ptr-arith.c Tue Feb 25 20:36:06 2014
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare %s
 
 void clang_analyzer_eval(int);
 

Modified: cfe/trunk/test/Analysis/stackaddrleak.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/stackaddrleak.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/stackaddrleak.c (original)
+++ cfe/trunk/test/Analysis/stackaddrleak.c Tue Feb 25 20:36:06 2014
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool -Wno-bool-conversion %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ -Wno-bool-conversion %s
 
 typedef __INTPTR_TYPE__ intptr_t;
 char const *p;

Modified: cfe/trunk/test/Analysis/weak-functions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/weak-functions.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/weak-functions.c (original)
+++ cfe/trunk/test/Analysis/weak-functions.c Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -Wno-tautological-compare -analyzer-store=region -fblocks -verify %s
 #define NULL 0
 void clang_analyzer_eval(int);
 void myFunc();

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp Tue Feb 25 20:36:06 2014
@@ -163,7 +163,8 @@ void shrink_int() {
   Agg<bool> b3 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
 
   // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg<bool> b = {&b1};  // OK
+  Agg<bool>* ptr = &b1;
+  Agg<bool> b = {ptr};  // OK
 
   Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}}
   Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp Tue Feb 25 20:36:06 2014
@@ -164,7 +164,8 @@ void shrink_int() {
   Agg<bool> b3 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
 
   // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg<bool> b = {&b1};  // OK
+  Agg<bool>* ptr = &b1;
+  Agg<bool> b = {ptr};  // OK
 
   Agg<short> ce1 = { Convert<int>(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}}
   Agg<char> ce2 = { ConvertVar<short>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}

Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp Tue Feb 25 20:36:06 2014
@@ -15,7 +15,7 @@ bool b4 = !E;
 bool b5 = !F;
 
 // --  pointer, 
-bool b6 = !&b4;
+bool b6 = !&b4; // expected-warning{{address of 'b4' will always evaluate to 'true'}}
 void f();
 bool b61 = !&f;
 

Modified: cfe/trunk/test/Sema/const-eval.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-eval.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Sema/const-eval.c (original)
+++ cfe/trunk/test/Sema/const-eval.c Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux %s -Wno-tautological-pointer-compare
 
 #define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});
 int x;

Modified: cfe/trunk/test/Sema/static-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-init.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Sema/static-init.c (original)
+++ cfe/trunk/test/Sema/static-init.c Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion %s
 
 typedef __typeof((int*) 0 - (int*) 0) intptr_t;
 

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment
+// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
 
 namespace StaticAssertFoldTest {
 

Modified: cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int -Wno-tautological-pointer-compare %s
 #include <stddef.h>
 
 void f() {

Modified: cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s
 
 void foo() {
   int a;

Modified: cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp Tue Feb 25 20:36:06 2014
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
+namespace BooleanFalse {
 int* j = false; // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
 
 void foo(int* i, int *j=(false)) // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
@@ -22,3 +23,98 @@ double f(...);
 // isn't flagged.
 template <int N> struct S {};
 S<sizeof(f(false))> s;
+
+}
+
+namespace Function {
+void f1();
+
+struct S {
+  static void f2();
+};
+
+extern void f3() __attribute__((weak_import));
+
+struct S2 {
+  static void f4() __attribute__((weak_import));
+};
+
+bool f5();
+bool f6(int);
+
+void bar() {
+  bool b;
+
+  b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+             expected-note {{prefix with the address-of operator to silence this warning}}
+  if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+                expected-note {{prefix with the address-of operator to silence this warning}}
+  b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+                expected-note {{prefix with the address-of operator to silence this warning}}
+  if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+                   expected-note {{prefix with the address-of operator to silence this warning}}
+  b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
+             expected-note {{prefix with the address-of operator to silence this warning}} \
+             expected-note {{suffix with parentheses to turn this into a function call}}
+  b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
+             expected-note {{prefix with the address-of operator to silence this warning}}
+
+  // implicit casts of weakly imported symbols are ok:
+  b = f3;
+  if (f3) {}
+  b = S2::f4;
+  if (S2::f4) {}
+}
+}
+
+namespace Array {
+  #define GetValue(ptr)  ((ptr) ? ptr[0] : 0)
+  extern int a[] __attribute__((weak));
+  int b[] = {8,13,21};
+  struct {
+    int x[10];
+  } c;
+  const char str[] = "text";
+  void ignore() {
+    if (a) {}
+    if (a) {}
+    (void)GetValue(b);
+  }
+  void test() {
+    if (b) {}
+    // expected-warning at -1{{address of array 'b' will always evaluate to 'true'}}
+    if (b) {}
+    // expected-warning at -1{{address of array 'b' will always evaluate to 'true'}}
+    if (c.x) {}
+    // expected-warning at -1{{address of array 'c.x' will always evaluate to 'true'}}
+    if (str) {}
+    // expected-warning at -1{{address of array 'str' will always evaluate to 'true'}}
+  }
+}
+
+namespace Pointer {
+  extern int a __attribute__((weak));
+  int b;
+  static int c;
+  class S {
+  public:
+    static int a;
+    int b;
+  };
+  void ignored() {
+    if (&a) {}
+  }
+  void test() {
+    S s;
+    if (&b) {}
+    // expected-warning at -1{{address of 'b' will always evaluate to 'true'}}
+    if (&c) {}
+    // expected-warning at -1{{address of 'c' will always evaluate to 'true'}}
+    if (&s.a) {}
+    // expected-warning at -1{{address of 's.a' will always evaluate to 'true'}}
+    if (&s.b) {}
+    // expected-warning at -1{{address of 's.b' will always evaluate to 'true'}}
+    if (&S::a) {}
+    // expected-warning at -1{{address of 'S::a' will always evaluate to 'true'}}
+  }
+}

Removed: cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp?rev=202215&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp (removed)
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -x c++ -verify -fsyntax-only %s
-
-void f1();
-
-struct S {
-  static void f2();
-};
-
-extern void f3() __attribute__((weak_import));
-
-struct S2 {
-  static void f4() __attribute__((weak_import));
-};
-
-bool f5();
-bool f6(int);
-
-void bar() {
-  bool b;
-
-  b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
-             expected-note {{prefix with the address-of operator to silence this warning}}
-  if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
-                expected-note {{prefix with the address-of operator to silence this warning}}
-  b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
-                expected-note {{prefix with the address-of operator to silence this warning}}
-  if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
-                   expected-note {{prefix with the address-of operator to silence this warning}}
-  b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
-             expected-note {{prefix with the address-of operator to silence this warning}} \
-             expected-note {{suffix with parentheses to turn this into a function call}}
-  b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
-             expected-note {{prefix with the address-of operator to silence this warning}}
-
-  // implicit casts of weakly imported symbols are ok:
-  b = f3;
-  if (f3) {}
-  b = S2::f4;
-  if (S2::f4) {}
-}

Modified: cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp Tue Feb 25 20:36:06 2014
@@ -25,3 +25,114 @@ namespace RuntimeBehavior {
     if (x < kintmax) {}
   }
 }
+
+namespace ArrayCompare {
+  #define GetValue(ptr)  ((ptr != 0) ? ptr[0] : 0)
+  extern int a[] __attribute__((weak));
+  int b[] = {8,13,21};
+  struct {
+    int x[10];
+  } c;
+  const char str[] = "text";
+  void ignore() {
+    if (a == 0) {}
+    if (a != 0) {}
+    (void)GetValue(b);
+  }
+  void test() {
+    if (b == 0) {}
+    // expected-warning at -1{{comparison of array 'b' equal to a null pointer is always false}}
+    if (b != 0) {}
+    // expected-warning at -1{{comparison of array 'b' not equal to a null pointer is always true}}
+    if (0 == b) {}
+    // expected-warning at -1{{comparison of array 'b' equal to a null pointer is always false}}
+    if (0 != b) {}
+    // expected-warning at -1{{comparison of array 'b' not equal to a null pointer is always true}}
+    if (c.x == 0) {}
+    // expected-warning at -1{{comparison of array 'c.x' equal to a null pointer is always false}}
+    if (c.x != 0) {}
+    // expected-warning at -1{{comparison of array 'c.x' not equal to a null pointer is always true}}
+    if (str == 0) {}
+    // expected-warning at -1{{comparison of array 'str' equal to a null pointer is always false}}
+    if (str != 0) {}
+    // expected-warning at -1{{comparison of array 'str' not equal to a null pointer is always true}}
+  }
+}
+
+namespace FunctionCompare {
+  #define CallFunction(f) ((f != 0) ? f() : 0)
+  extern void a()  __attribute__((weak));
+  void fun1();
+  int fun2();
+  int* fun3();
+  int* fun4(int);
+  class S {
+  public:
+    static int foo();
+  };
+  void ignore() {
+    if (a == 0) {}
+    if (0 != a) {}
+    (void)CallFunction(fun2);
+  }
+  void test() {
+    if (fun1 == 0) {}
+    // expected-warning at -1{{comparison of function 'fun1' equal to a null pointer is always false}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    if (fun2 == 0) {}
+    // expected-warning at -1{{comparison of function 'fun2' equal to a null pointer is always false}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+    if (fun3 == 0) {}
+    // expected-warning at -1{{comparison of function 'fun3' equal to a null pointer is always false}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+    if (fun4 == 0) {}
+    // expected-warning at -1{{comparison of function 'fun4' equal to a null pointer is always false}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    if (nullptr != fun1) {}
+    // expected-warning at -1{{comparison of function 'fun1' not equal to a null pointer is always true}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    if (nullptr != fun2) {}
+    // expected-warning at -1{{comparison of function 'fun2' not equal to a null pointer is always true}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    if (nullptr != fun3) {}
+    // expected-warning at -1{{comparison of function 'fun3' not equal to a null pointer is always true}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+    if (nullptr != fun4) {}
+    // expected-warning at -1{{comparison of function 'fun4' not equal to a null pointer is always true}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    if (S::foo == 0) {}
+    // expected-warning at -1{{comparison of function 'S::foo' equal to a null pointer is always false}}
+    // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+    // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+  }
+}
+
+namespace PointerCompare {
+  extern int a __attribute__((weak));
+  int b;
+  static int c;
+  class S {
+  public:
+    static int a;
+    int b;
+  };
+  void ignored() {
+    if (&a == 0) {}
+  }
+  void test() {
+    S s;
+    if (&b == 0) {}
+    // expected-warning at -1{{comparison of address of 'b' equal to a null pointer is always false}}
+    if (&c == 0) {}
+    // expected-warning at -1{{comparison of address of 'c' equal to a null pointer is always false}}
+    if (&s.a == 0) {}
+    // expected-warning at -1{{comparison of address of 's.a' equal to a null pointer is always false}}
+    if (&s.b == 0) {}
+    // expected-warning at -1{{comparison of address of 's.b' equal to a null pointer is always false}}
+    if (&S::a == 0) {}
+    // expected-warning at -1{{comparison of address of 'S::a' equal to a null pointer is always false}}
+  }
+}

Modified: cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp (original)
+++ cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp Tue Feb 25 20:36:06 2014
@@ -45,9 +45,15 @@ int main()
   +oneT<int>;  // expected-warning {{expression result unused}}
   -oneT<int>;  //expected-error {{invalid argument type}}
   oneT<int> == 0;   // expected-warning {{equality comparison result unused}} \
-                    // expected-note {{use '=' to turn this equality comparison into an assignment}}
-  0 == oneT<int>;   // expected-warning {{equality comparison result unused}}
-  0 != oneT<int>;    // expected-warning {{inequality comparison result unused}}
+                    // expected-note {{use '=' to turn this equality comparison into an assignment}} \
+                    // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
+  0 == oneT<int>;   // expected-warning {{equality comparison result unused}} \
+                    // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
+  0 != oneT<int>;   // expected-warning {{inequality comparison result unused}} \
+                    // expected-warning {{comparison of function 'oneT<int>' not equal to a null pointer is always true}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
   (false ? one : oneT<int>);   // expected-warning {{expression result unused}}
   void (*p1)(int); p1 = oneT<int>;
   
@@ -69,7 +75,9 @@ int main()
   two < two; //expected-error 2 {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{invalid operands to binary expression ('void' and 'void')}}
   twoT<int> < twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
   oneT<int> == 0;   // expected-warning {{equality comparison result unused}} \
-                    // expected-note {{use '=' to turn this equality comparison into an assignment}}
+                    // expected-note {{use '=' to turn this equality comparison into an assignment}} \
+                    // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
 
 }
 





More information about the cfe-commits mailing list