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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits