hiraditya created this revision.
hiraditya added reviewers: Eugene.Zelenko, rsmith.

We found conversion from bool* to bool to be a common source of bug, so we have 
implemented this warning. Sample use case:

  int bar(bool b) {
    return b;
  }
  
  int baz() {
    bool *b; 
    bar(b);
    return 0;
  }

Typically, there would be a function which takes a bool, which gets a pointer 
to boolean at the call site. The compiler currently does not warn which results
in a difficult to debug runtime failure.


https://reviews.llvm.org/D45601

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaChecking.cpp
  test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
  test/Sema/static-init.c
  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,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int foo(bool *b) {
+  if (b)
+    // expected-warning@-1 {{comparing 'bool *' as a boolean}}
+    return 10;
+  return 0;
+}
+
+
+int bar(bool b) {
+  return b;
+}
+
+int baz() {
+  bool *b;
+  bar(b);
+  // expected-warning@-1 {{comparing 'bool *' as a boolean}}
+  return 0;
+}
+
+
+
Index: test/Sema/static-init.c
===================================================================
--- test/Sema/static-init.c
+++ test/Sema/static-init.c
@@ -7,7 +7,7 @@
 
 float r  = (float) (intptr_t) &r; // expected-error {{initializer element is 
not a compile-time constant}}
 intptr_t s = (intptr_t) &s;
-_Bool t = &t;
+_Bool t = &t; // expected-warning {{comparing '_Bool *' as a boolean}}
 
 
 union bar {
Index: test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
===================================================================
--- test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
+++ test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
@@ -16,6 +16,7 @@
 
 // --  pointer, 
 bool b6 = !&b4; // expected-warning{{address of 'b4' will always evaluate to 
'true'}}
+// expected-warning@-1 {{comparing 'bool *' as a boolean}}
 void f();
 bool b61 = !&f;
 
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -9610,6 +9610,12 @@
       S.DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, /*IsEqual*/ false,
                                      SourceRange(CC));
     }
+    if (Source->isPointerType() || Source->canDecayToPointerType()) {
+      QualType PointeeType = Source->getPointeeType();
+      // Warn on bool* to bool conversion.
+      if (!PointeeType.isNull() && PointeeType->isBooleanType())
+        return DiagnoseImpCast(S, E, T, CC, diag::warn_pointer_to_bool);
+    }
   }
 
   // Check implicit casts from Objective-C collection literals to specialized
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -7801,6 +7801,9 @@
   "format specifies type %0 but the argument has "
   "%select{type|underlying type}2 %1">,
   InGroup<FormatPedantic>;
+def warn_pointer_to_bool : Warning<
+  "comparing %0 as a boolean">,
+  InGroup<Extra>;
 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">,


Index: test/SemaCXX/warn-bool-ptr-to-bool.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/warn-bool-ptr-to-bool.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int foo(bool *b) {
+  if (b)
+    // expected-warning@-1 {{comparing 'bool *' as a boolean}}
+    return 10;
+  return 0;
+}
+
+
+int bar(bool b) {
+  return b;
+}
+
+int baz() {
+  bool *b;
+  bar(b);
+  // expected-warning@-1 {{comparing 'bool *' as a boolean}}
+  return 0;
+}
+
+
+
Index: test/Sema/static-init.c
===================================================================
--- test/Sema/static-init.c
+++ test/Sema/static-init.c
@@ -7,7 +7,7 @@
 
 float r  = (float) (intptr_t) &r; // expected-error {{initializer element is not a compile-time constant}}
 intptr_t s = (intptr_t) &s;
-_Bool t = &t;
+_Bool t = &t; // expected-warning {{comparing '_Bool *' as a boolean}}
 
 
 union bar {
Index: test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
===================================================================
--- test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
+++ test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
@@ -16,6 +16,7 @@
 
 // --  pointer, 
 bool b6 = !&b4; // expected-warning{{address of 'b4' will always evaluate to 'true'}}
+// expected-warning@-1 {{comparing 'bool *' as a boolean}}
 void f();
 bool b61 = !&f;
 
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -9610,6 +9610,12 @@
       S.DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, /*IsEqual*/ false,
                                      SourceRange(CC));
     }
+    if (Source->isPointerType() || Source->canDecayToPointerType()) {
+      QualType PointeeType = Source->getPointeeType();
+      // Warn on bool* to bool conversion.
+      if (!PointeeType.isNull() && PointeeType->isBooleanType())
+        return DiagnoseImpCast(S, E, T, CC, diag::warn_pointer_to_bool);
+    }
   }
 
   // Check implicit casts from Objective-C collection literals to specialized
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -7801,6 +7801,9 @@
   "format specifies type %0 but the argument has "
   "%select{type|underlying type}2 %1">,
   InGroup<FormatPedantic>;
+def warn_pointer_to_bool : Warning<
+  "comparing %0 as a boolean">,
+  InGroup<Extra>;
 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