[clang] [clang] Diagnose for implicit boolean conversions in assignments (PR #114687)
Philipp Rados via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 2 15:48:34 PDT 2024
https://github.com/PhilippRados created https://github.com/llvm/llvm-project/pull/114687
This is an unfinished implementation of #33528. I have a couple of questions since I'm new to the codebase:
This warning should be issued for both C and C++. For C++ it is pretty straightforward since I can check this when calling `PerformImplicitConversion`. However this function isn't called in C and right now I issue the warning for C in `Sema::ImpCastExprToType`, but I don't know if this function also might be called in C++ resulting in the same warning issued twice.
Ideally I would just have to issue this once for both languages but I can't seem to find the correct `ImplicitCast` function that gets invoked for both langs.
I also found another already existing warning when running the tests (warn_condition_is_assignment) that is similar to this warning but only gets issued on assignments in conditional-expressions, as opposed to all assignment expressions. In C++ this results in the new and old warning both being displayed even though they both suggest the same thing.
How should this be handled? Should I manually check if the broader warning has already been issued and then remove it or maybe just keep the more general warning as they mean the same thing (-Wparentheses)?
Any feedback is appreciated!
>From b8244b346c7a97c2eb35ccfea23675b8df4f046e Mon Sep 17 00:00:00 2001
From: PhilippR <phil.black at gmx.net>
Date: Sat, 2 Nov 2024 18:51:26 +0100
Subject: [PATCH] [clang] adding diagnose for impl-cast (draft) This is an
unfinished implementation of #33528
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
clang/include/clang/Sema/Sema.h | 2 ++
clang/lib/Sema/Sema.cpp | 14 ++++++++++++++
clang/lib/Sema/SemaExprCXX.cpp | 3 +++
4 files changed, 21 insertions(+)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d697e6d61afa9a..51879c359b3060 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8477,6 +8477,8 @@ def err_incomplete_object_call : Error<
def warn_condition_is_assignment : Warning<"using the result of an "
"assignment as a condition without parentheses">,
InGroup<Parentheses>;
+def warn_parens_bool_assign : Warning<"suggest parentheses around assignment used as truth value">,
+ InGroup<Parentheses>;
def warn_free_nonheap_object
: Warning<"attempt to call %0 on non-heap %select{object %2|object: block expression|object: lambda-to-function-pointer conversion}1">,
InGroup<FreeNonHeapObject>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 93d98e1cbb9c81..30767b11998bb7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7232,6 +7232,8 @@ class Sema final : public SemaBase {
/// being used as a boolean condition, warn if it's an assignment.
void DiagnoseAssignmentAsCondition(Expr *E);
+ void DiagnoseImplicitCastBoolAssignment(Expr *E, QualType ToType);
+
/// Redundant parentheses over an equality comparison can indicate
/// that the user intended an assignment used as condition.
void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE);
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 2b51765e80864a..cc9cb173c01480 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -687,6 +687,18 @@ void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E) {
<< FixItHint::CreateReplacement(E->getSourceRange(), "nullptr");
}
+void Sema::DiagnoseImplicitCastBoolAssignment(Expr* E,QualType Ty) {
+ if (Ty->isBooleanType()) {
+ if (BinaryOperator* Op = dyn_cast<BinaryOperator>(E)) {
+ // should only be issued for regular assignment `=`, not for e.g `+=`
+ if (Op->getOpcode() == BO_Assign) {
+ SourceLocation Loc = Op->getOperatorLoc();
+ Diag(Loc,diag::warn_parens_bool_assign) << E->getSourceRange();
+ }
+ }
+ }
+}
+
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
/// The result is of the given category.
@@ -761,6 +773,8 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
}
}
+ DiagnoseImplicitCastBoolAssignment(E,Ty);
+
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
ImpCast->setType(Ty);
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 50c1b24fce6da7..14ca6a743049e4 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
@@ -4392,6 +4393,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
FromType = From->getType();
}
+ DiagnoseImplicitCastBoolAssignment(From,ToType);
+
// If we're converting to an atomic type, first convert to the corresponding
// non-atomic type.
QualType ToAtomicType;
More information about the cfe-commits
mailing list