hiraditya updated this revision to Diff 142776.
hiraditya added a comment.

Warn on bool* to bool conversion during a call only.


https://reviews.llvm.org/D45601

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaChecking.cpp
  test/SemaCXX/warn-bool-ptr-to-bool.cpp

Index: test/SemaCXX/warn-bool-ptr-to-bool.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/warn-bool-ptr-to-bool.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int foo(bool *b) {
+  if (b) // no-warning
+    return 10;
+  return 0;
+}
+
+int bar(bool b) {
+  return b;
+}
+
+int baz() {
+  bool *b;
+  bar(b);
+  // expected-warning@-1 {{passing 'bool *' as a boolean}}
+  return 0;
+}
+
+template<class T>
+T foo1(T *ptr) {
+  return ptr ? *ptr : T{}; // no-warning
+}
+
+bool bar1(bool *ptr) {
+  return foo1(ptr);
+}
+
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -2545,6 +2545,27 @@
   }
 }
 
+/// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion.
+void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T,
+                     SourceLocation CContext, unsigned diag,
+                     bool pruneControlFlow = false) {
+  if (pruneControlFlow) {
+    S.DiagRuntimeBehavior(E->getExprLoc(), E,
+                          S.PDiag(diag)
+                            << SourceType << T << E->getSourceRange()
+                            << SourceRange(CContext));
+    return;
+  }
+  S.Diag(E->getExprLoc(), diag)
+    << SourceType << T << E->getSourceRange() << SourceRange(CContext);
+}
+
+/// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion.
+void DiagnoseImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext,
+                     unsigned diag, bool pruneControlFlow = false) {
+  DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow);
+}
+
 /// Handles the checks for format strings, non-POD arguments to vararg
 /// functions, NULL arguments passed to non-NULL parameters, and diagnose_if
 /// attributes.
@@ -2589,6 +2610,28 @@
     }
   }
 
+  if (FD) {
+    for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
+      // Args[ArgIdx] can be null in malformed code.
+      if (const Expr *Arg = Args[ArgIdx]) {
+        if (auto C = dyn_cast<ImplicitCastExpr>(Arg)) {
+          if (C->getCastKind() == CK_PointerToBoolean) {
+            if (auto ICast = dyn_cast<ImplicitCastExpr>(C->getSubExpr())) {
+              if (ICast->getCastKind() == CK_LValueToRValue) {
+                const Expr *Pointer = ICast->getSubExpr();
+                QualType QT = Pointer->getType()->getPointeeType();
+                if (!QT.isNull() && QT->isBooleanType())
+                  // Warn on bool* to bool conversion.
+                  DiagnoseImpCast(*this, Pointer, QT, Arg->getLocStart(),
+                                  diag::warn_pointer_to_bool);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
   if (FDecl || Proto) {
     CheckNonNullArguments(*this, FDecl, Proto, Args, Loc);
 
@@ -8941,27 +8984,6 @@
   AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
 }
 
-/// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion.
-void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, 
-                     SourceLocation CContext, unsigned diag,
-                     bool pruneControlFlow = false) {
-  if (pruneControlFlow) {
-    S.DiagRuntimeBehavior(E->getExprLoc(), E,
-                          S.PDiag(diag)
-                            << SourceType << T << E->getSourceRange()
-                            << SourceRange(CContext));
-    return;
-  }
-  S.Diag(E->getExprLoc(), diag)
-    << SourceType << T << E->getSourceRange() << SourceRange(CContext);
-}
-
-/// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion.
-void DiagnoseImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext,
-                     unsigned diag, bool pruneControlFlow = false) {
-  DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow);
-}
-
 
 /// Diagnose an implicit cast from a floating point value to an integer value.
 void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -7760,6 +7760,9 @@
   "format specifies type %0 but the argument has "
   "%select{type|underlying type}2 %1">,
   InGroup<FormatPedantic>;
+def warn_pointer_to_bool : Warning<
+  "passing %0 as a boolean">,
+  InGroup<PointerBoolConversion>;
 def warn_format_argument_needs_cast : Warning<
   "%select{values of type|enum values with underlying type}2 '%0' should not "
   "be used as format arguments; add an explicit cast to %1 instead">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to