[clang] [clang] Added warn-assignment-bool-context (PR #115234)
Philipp Rados via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 25 09:51:18 PST 2025
https://github.com/PhilippRados updated https://github.com/llvm/llvm-project/pull/115234
>From e819360e6510f12f19b7df9d4eb22c0943776440 Mon Sep 17 00:00:00 2001
From: PhilippR <phil.black at gmx.net>
Date: Thu, 7 Nov 2024 00:06:24 +0100
Subject: [PATCH 1/5] [clang] Added warn-assignment-bool-context
This warning is issued if an assignment is used in a context
where a boolean result is required.
---
.../clang/Basic/DiagnosticSemaKinds.td | 3 ++
clang/include/clang/Sema/Sema.h | 2 +
clang/lib/Sema/Sema.cpp | 53 +++++++++++++++++++
clang/lib/Sema/SemaExpr.cpp | 6 ++-
.../test/Sema/warn-assignment-bool-context.c | 35 ++++++++++++
.../SemaCXX/warn-assignment-bool-context.cpp | 45 ++++++++++++++++
6 files changed, 143 insertions(+), 1 deletion(-)
create mode 100644 clang/test/Sema/warn-assignment-bool-context.c
create mode 100644 clang/test/SemaCXX/warn-assignment-bool-context.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ae3e243bdc58b..4ba4327bde5cf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8477,6 +8477,9 @@ 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_assignment_bool_context : 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 93d98e1cbb9c8..6bf73956d3f94 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 DiagnoseAssignmentBoolContext(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 2b51765e80864..a8e4657ac0b6e 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -687,6 +687,48 @@ void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E) {
<< FixItHint::CreateReplacement(E->getSourceRange(), "nullptr");
}
+void Sema::DiagnoseAssignmentBoolContext(Expr *E, QualType Ty) {
+ // Use copy to not alter original expression.
+ Expr *ECopy = E;
+
+ if (Ty->isBooleanType()) {
+ // `bool(x=0)` and if (x=0){} emit:
+ // - ImplicitCastExpr bool IntegralToBoolean
+ // -- ImplicitCastExpr int LValueToRValue
+ // --- Assignment ...
+ // But should still emit this warning (at least gcc does), even if bool-cast
+ // is not directly followed by assignment.
+ // NOTE: Is this robust enough or can there be other semantic expression
+ // until the assignment?
+ while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ECopy)) {
+ // If there is another implicit cast to bool then this warning would have
+ // been already emitted.
+ if (ICE->getType()->isBooleanType())
+ return;
+ ECopy = ICE->getSubExpr();
+ }
+
+ if (BinaryOperator *Op = dyn_cast<BinaryOperator>(ECopy)) {
+ // Should only be issued for regular assignment `=`,
+ // not for compound-assign like `+=`.
+ // NOTE: Might make sense to emit for all assignments even if gcc
+ // only does for regular assignment.
+ if (Op->getOpcode() == BO_Assign) {
+ SourceLocation Loc = Op->getOperatorLoc();
+ Diag(Loc, diag::warn_assignment_bool_context)
+ << ECopy->getSourceRange();
+
+ SourceLocation Open = ECopy->getBeginLoc();
+ SourceLocation Close =
+ getLocForEndOfToken(ECopy->getSourceRange().getEnd());
+ Diag(Loc, diag::note_condition_assign_silence)
+ << FixItHint::CreateInsertion(Open, "(")
+ << FixItHint::CreateInsertion(Close, ")");
+ }
+ }
+ }
+}
+
/// 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 +803,17 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
}
}
+ // FIXME: Doesn't include C89, so this warning isn't emitted when passing
+ // `std=c89`.
+ auto isC = getLangOpts().C99 || getLangOpts().C11 || getLangOpts().C17 ||
+ getLangOpts().C23;
+ // Do not emit this warning for Objective-C, since it's a common idiom.
+ // NOTE: Are there other languages that this could affect besides C and C++?
+ // Ideally would check `getLangOpts().Cplusplus || getLangOpts().C` but there
+ // is no option for C (only C99 etc.).
+ if ((getLangOpts().CPlusPlus || isC) && !getLangOpts().ObjC)
+ DiagnoseAssignmentBoolContext(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/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 49fdb5b5ab43d..bee8751c3fa7a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20287,7 +20287,11 @@ void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) {
ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E,
bool IsConstexpr) {
- DiagnoseAssignmentAsCondition(E);
+ // This warning is already covered by `warn_assignment_bool_context` in C++.
+ // NOTE: Ideally both warnings would be combined
+ if (!getLangOpts().CPlusPlus || getLangOpts().ObjC)
+ DiagnoseAssignmentAsCondition(E);
+
if (ParenExpr *parenE = dyn_cast<ParenExpr>(E))
DiagnoseEqualityWithExtraParens(parenE);
diff --git a/clang/test/Sema/warn-assignment-bool-context.c b/clang/test/Sema/warn-assignment-bool-context.c
new file mode 100644
index 0000000000000..bf746e0bed2c2
--- /dev/null
+++ b/clang/test/Sema/warn-assignment-bool-context.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -Wparentheses -verify %s
+
+// NOTE: Don't know if tests allow includes.
+#include <stdbool.h>
+
+// Do not emit the warning for compound-assignments.
+bool f(int x) { return x = 0; } // expected-warning {{suggest parentheses around assignment used as truth value}}\
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+bool f2(int x) { return x += 0; }
+
+bool f3(bool x) { return x = 0; }
+
+void test() {
+ int x;
+
+ // This should emit the `warn_condition_is_assignment` warning, since
+ // C doesn't do implicit conversion booleans for conditions.
+ if (x = 0) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}\
+ // expected-note{{use '==' to turn this assignment into an equality comparison}}
+ if (x = 4 && x){} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}\
+ // expected-note{{use '==' to turn this assignment into an equality comparison}}
+
+ (void)(bool)(x = 1);
+ (void)(bool)(int)(x = 1);
+
+
+ bool _a = x = 3; // expected-warning {{suggest parentheses around assignment used as truth value}}\
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+
+ // Shouldn't warn for above cases if parentheses were provided.
+ if ((x = 0)) {}
+ bool _b = (x = 3);
+}
diff --git a/clang/test/SemaCXX/warn-assignment-bool-context.cpp b/clang/test/SemaCXX/warn-assignment-bool-context.cpp
new file mode 100644
index 0000000000000..a4831f53e311b
--- /dev/null
+++ b/clang/test/SemaCXX/warn-assignment-bool-context.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -x c++ -fsyntax-only -Wparentheses -verify %s
+
+// Do not emit the warning for compound-assignments.
+bool f(int x) { return x = 0; } // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+bool f2(int x) { return x += 0; }
+
+bool f3(bool x) { return x = 0; }
+
+void test() {
+ int x;
+
+ // Assignemnts inside of conditions should still emit the more specific `warn_condition_is_assignment` warning.
+ if (x = 0) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+ if (x = 4 && x){} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+
+
+ (void)bool(x = 1); // expected-warning {{suggest parentheses around assignment used as truth value}}\
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+ (void)(bool)(x = 1);
+
+ // This should still emit since the RHS is casted to `int` before being casted back to `bool`.
+ (void)bool(x = false); // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+
+ // Should only issue warning once, even if multiple implicit casts.
+ // FIXME: This only checks that warning occurs not how often.
+ (void)bool(bool(x = 1)); // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+ (void)bool(int(bool(x = 1))); // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+ (void)bool(int(x = 1));
+
+ bool _a = x = 3; // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+
+ // Shouldn't warn for above cases if parentheses were provided.
+ if ((x = 0)) {}
+ (void)bool((x = 1));
+ bool _b= (x = 3);
+}
>From 2a06e37ac54d5b47221f9923dcfe4111bfc72ea0 Mon Sep 17 00:00:00 2001
From: PhilippR <phil.black at gmx.net>
Date: Sat, 22 Feb 2025 20:11:43 +0100
Subject: [PATCH 2/5] [clang] Store condition info in Expr; Passes all tests
---
clang/include/clang/AST/Expr.h | 3 +-
.../clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/lib/Sema/Sema.cpp | 32 +++++++------------
clang/lib/Sema/SemaExpr.cpp | 6 ++--
.../test/Sema/warn-assignment-bool-context.c | 9 +++---
.../SemaCXX/warn-assignment-bool-context.cpp | 14 ++++----
6 files changed, 28 insertions(+), 38 deletions(-)
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad..2d4771bbc1022 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -116,10 +116,11 @@ class Expr : public ValueStmt {
Expr(Expr &&) = delete;
Expr &operator=(const Expr&) = delete;
Expr &operator=(Expr&&) = delete;
+ bool isCondition;
protected:
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK)
- : ValueStmt(SC) {
+ : ValueStmt(SC), isCondition(false) {
ExprBits.Dependent = 0;
ExprBits.ValueKind = VK;
ExprBits.ObjectKind = OK;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4ba4327bde5cf..70aa54f541819 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8477,7 +8477,7 @@ 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_assignment_bool_context : Warning<"suggest parentheses around assignment used as truth value">,
+def warn_assignment_bool_context : Warning<"using the result of an assignment as a truth value without parentheses">,
InGroup<Parentheses>;
def warn_free_nonheap_object
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index a8e4657ac0b6e..963e96b8c607c 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -688,9 +688,6 @@ void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E) {
}
void Sema::DiagnoseAssignmentBoolContext(Expr *E, QualType Ty) {
- // Use copy to not alter original expression.
- Expr *ECopy = E;
-
if (Ty->isBooleanType()) {
// `bool(x=0)` and if (x=0){} emit:
// - ImplicitCastExpr bool IntegralToBoolean
@@ -698,17 +695,19 @@ void Sema::DiagnoseAssignmentBoolContext(Expr *E, QualType Ty) {
// --- Assignment ...
// But should still emit this warning (at least gcc does), even if bool-cast
// is not directly followed by assignment.
- // NOTE: Is this robust enough or can there be other semantic expression
- // until the assignment?
- while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ECopy)) {
+ while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
// If there is another implicit cast to bool then this warning would have
// been already emitted.
if (ICE->getType()->isBooleanType())
return;
- ECopy = ICE->getSubExpr();
+ E = ICE->getSubExpr();
}
- if (BinaryOperator *Op = dyn_cast<BinaryOperator>(ECopy)) {
+ // Condition-assignment warnings are already handled by `DiagnoseAssignmentAsCondition()`
+ if (E->isCondition)
+ return;
+
+ if (BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {
// Should only be issued for regular assignment `=`,
// not for compound-assign like `+=`.
// NOTE: Might make sense to emit for all assignments even if gcc
@@ -716,11 +715,11 @@ void Sema::DiagnoseAssignmentBoolContext(Expr *E, QualType Ty) {
if (Op->getOpcode() == BO_Assign) {
SourceLocation Loc = Op->getOperatorLoc();
Diag(Loc, diag::warn_assignment_bool_context)
- << ECopy->getSourceRange();
+ << E->getSourceRange();
- SourceLocation Open = ECopy->getBeginLoc();
+ SourceLocation Open = E->getBeginLoc();
SourceLocation Close =
- getLocForEndOfToken(ECopy->getSourceRange().getEnd());
+ getLocForEndOfToken(E->getSourceRange().getEnd());
Diag(Loc, diag::note_condition_assign_silence)
<< FixItHint::CreateInsertion(Open, "(")
<< FixItHint::CreateInsertion(Close, ")");
@@ -803,16 +802,7 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
}
}
- // FIXME: Doesn't include C89, so this warning isn't emitted when passing
- // `std=c89`.
- auto isC = getLangOpts().C99 || getLangOpts().C11 || getLangOpts().C17 ||
- getLangOpts().C23;
- // Do not emit this warning for Objective-C, since it's a common idiom.
- // NOTE: Are there other languages that this could affect besides C and C++?
- // Ideally would check `getLangOpts().Cplusplus || getLangOpts().C` but there
- // is no option for C (only C99 etc.).
- if ((getLangOpts().CPlusPlus || isC) && !getLangOpts().ObjC)
- DiagnoseAssignmentBoolContext(E, Ty);
+ DiagnoseAssignmentBoolContext(E, Ty);
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index bee8751c3fa7a..f195c0ce45f97 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20287,10 +20287,8 @@ void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) {
ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E,
bool IsConstexpr) {
- // This warning is already covered by `warn_assignment_bool_context` in C++.
- // NOTE: Ideally both warnings would be combined
- if (!getLangOpts().CPlusPlus || getLangOpts().ObjC)
- DiagnoseAssignmentAsCondition(E);
+ DiagnoseAssignmentAsCondition(E);
+ E->isCondition = true;
if (ParenExpr *parenE = dyn_cast<ParenExpr>(E))
DiagnoseEqualityWithExtraParens(parenE);
diff --git a/clang/test/Sema/warn-assignment-bool-context.c b/clang/test/Sema/warn-assignment-bool-context.c
index bf746e0bed2c2..fdefc82eab97a 100644
--- a/clang/test/Sema/warn-assignment-bool-context.c
+++ b/clang/test/Sema/warn-assignment-bool-context.c
@@ -1,10 +1,11 @@
// RUN: %clang_cc1 -x c -fsyntax-only -Wparentheses -verify %s
-// NOTE: Don't know if tests allow includes.
-#include <stdbool.h>
+#define bool _Bool
+#define true 1
+#define false 0
// Do not emit the warning for compound-assignments.
-bool f(int x) { return x = 0; } // expected-warning {{suggest parentheses around assignment used as truth value}}\
+bool f(int x) { return x = 0; } // expected-warning {{using the result of an assignment as a truth value without parentheses}}\
// expected-note{{place parentheses around the assignment to silence this warning}}
bool f2(int x) { return x += 0; }
@@ -26,7 +27,7 @@ void test() {
(void)(bool)(int)(x = 1);
- bool _a = x = 3; // expected-warning {{suggest parentheses around assignment used as truth value}}\
+ bool _a = x = 3; // expected-warning {{using the result of an assignment as a truth value without parentheses}}\
// expected-note{{place parentheses around the assignment to silence this warning}}
// Shouldn't warn for above cases if parentheses were provided.
diff --git a/clang/test/SemaCXX/warn-assignment-bool-context.cpp b/clang/test/SemaCXX/warn-assignment-bool-context.cpp
index a4831f53e311b..2973f7ef38290 100644
--- a/clang/test/SemaCXX/warn-assignment-bool-context.cpp
+++ b/clang/test/SemaCXX/warn-assignment-bool-context.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -x c++ -fsyntax-only -Wparentheses -verify %s
// Do not emit the warning for compound-assignments.
-bool f(int x) { return x = 0; } // expected-warning {{suggest parentheses around assignment used as truth value}} \
+bool f(int x) { return x = 0; } // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
bool f2(int x) { return x += 0; }
@@ -10,7 +10,7 @@ bool f3(bool x) { return x = 0; }
void test() {
int x;
- // Assignemnts inside of conditions should still emit the more specific `warn_condition_is_assignment` warning.
+ // Assignments inside of conditions should still emit the more specific `warn_condition_is_assignment` warning.
if (x = 0) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
@@ -19,23 +19,23 @@ void test() {
// expected-note{{place parentheses around the assignment to silence this warning}}
- (void)bool(x = 1); // expected-warning {{suggest parentheses around assignment used as truth value}}\
+ (void)bool(x = 1); // expected-warning {{using the result of an assignment as a truth value without parentheses}}\
// expected-note{{place parentheses around the assignment to silence this warning}}
(void)(bool)(x = 1);
// This should still emit since the RHS is casted to `int` before being casted back to `bool`.
- (void)bool(x = false); // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ (void)bool(x = false); // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
// Should only issue warning once, even if multiple implicit casts.
// FIXME: This only checks that warning occurs not how often.
- (void)bool(bool(x = 1)); // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ (void)bool(bool(x = 1)); // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
- (void)bool(int(bool(x = 1))); // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ (void)bool(int(bool(x = 1))); // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
(void)bool(int(x = 1));
- bool _a = x = 3; // expected-warning {{suggest parentheses around assignment used as truth value}} \
+ bool _a = x = 3; // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
// Shouldn't warn for above cases if parentheses were provided.
>From 419fb2a6b41817f55c129a87f8ba6822576103ee Mon Sep 17 00:00:00 2001
From: PhilippR <phil.black at gmx.net>
Date: Mon, 24 Feb 2025 21:08:37 +0100
Subject: [PATCH 3/5] [clang] Changed IsInsideCondition field to private
---
clang/include/clang/AST/Expr.h | 14 ++++++++++++--
clang/lib/Sema/Sema.cpp | 2 +-
clang/lib/Sema/SemaExpr.cpp | 2 +-
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 2d4771bbc1022..a44cdb2715b03 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -109,6 +109,7 @@ struct SubobjectAdjustment {
/// required.
class Expr : public ValueStmt {
QualType TR;
+ bool IsInsideCondition;
public:
Expr() = delete;
@@ -116,11 +117,10 @@ class Expr : public ValueStmt {
Expr(Expr &&) = delete;
Expr &operator=(const Expr&) = delete;
Expr &operator=(Expr&&) = delete;
- bool isCondition;
protected:
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK)
- : ValueStmt(SC), isCondition(false) {
+ : ValueStmt(SC), IsInsideCondition(false) {
ExprBits.Dependent = 0;
ExprBits.ValueKind = VK;
ExprBits.ObjectKind = OK;
@@ -451,6 +451,16 @@ class Expr : public ValueStmt {
return (OK == OK_Ordinary || OK == OK_BitField);
}
+ bool isInsideCondition() const {
+ return IsInsideCondition;
+ }
+
+ /// setValueKind - Mark this expression to be inside a condition.
+ /// necessary for `warn_assignment_bool_context` diagnostic
+ void setIsInsideCondition() {
+ IsInsideCondition = true;
+ }
+
/// setValueKind - Set the value kind produced by this expression.
void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 963e96b8c607c..e4cdc01c31bff 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -704,7 +704,7 @@ void Sema::DiagnoseAssignmentBoolContext(Expr *E, QualType Ty) {
}
// Condition-assignment warnings are already handled by `DiagnoseAssignmentAsCondition()`
- if (E->isCondition)
+ if (E->isInsideCondition())
return;
if (BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f195c0ce45f97..672507ffdad5e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20288,7 +20288,7 @@ void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) {
ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E,
bool IsConstexpr) {
DiagnoseAssignmentAsCondition(E);
- E->isCondition = true;
+ E->setIsInsideCondition();
if (ParenExpr *parenE = dyn_cast<ParenExpr>(E))
DiagnoseEqualityWithExtraParens(parenE);
>From 303a9820dd8ccde03b1e9c964dfe45dc5b927f8c Mon Sep 17 00:00:00 2001
From: PhilippR <phil.black at gmx.net>
Date: Mon, 24 Feb 2025 21:36:45 +0100
Subject: [PATCH 4/5] [clang] Formatted
---
clang/include/clang/AST/Expr.h | 8 ++------
clang/lib/Sema/Sema.cpp | 6 +++---
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index a44cdb2715b03..b0e4379fcf294 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -451,15 +451,11 @@ class Expr : public ValueStmt {
return (OK == OK_Ordinary || OK == OK_BitField);
}
- bool isInsideCondition() const {
- return IsInsideCondition;
- }
+ bool isInsideCondition() const { return IsInsideCondition; }
/// setValueKind - Mark this expression to be inside a condition.
/// necessary for `warn_assignment_bool_context` diagnostic
- void setIsInsideCondition() {
- IsInsideCondition = true;
- }
+ void setIsInsideCondition() { IsInsideCondition = true; }
/// setValueKind - Set the value kind produced by this expression.
void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index e4cdc01c31bff..86e2ed9d60ec7 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -703,7 +703,8 @@ void Sema::DiagnoseAssignmentBoolContext(Expr *E, QualType Ty) {
E = ICE->getSubExpr();
}
- // Condition-assignment warnings are already handled by `DiagnoseAssignmentAsCondition()`
+ // Condition-assignment warnings are already handled by
+ // `DiagnoseAssignmentAsCondition()`
if (E->isInsideCondition())
return;
@@ -714,8 +715,7 @@ void Sema::DiagnoseAssignmentBoolContext(Expr *E, QualType Ty) {
// only does for regular assignment.
if (Op->getOpcode() == BO_Assign) {
SourceLocation Loc = Op->getOperatorLoc();
- Diag(Loc, diag::warn_assignment_bool_context)
- << E->getSourceRange();
+ Diag(Loc, diag::warn_assignment_bool_context) << E->getSourceRange();
SourceLocation Open = E->getBeginLoc();
SourceLocation Close =
>From b72f7a736ea344b43db3cf5c72e9c19840ceca26 Mon Sep 17 00:00:00 2001
From: PhilippR <phil.black at gmx.net>
Date: Tue, 25 Feb 2025 18:26:17 +0100
Subject: [PATCH 5/5] [clang] Merged diagnostic warn_condition_is_assignment
into generic warn_assignment_bool_context
---
.../clang/Basic/DiagnosticSemaKinds.td | 3 --
clang/lib/Sema/SemaExpr.cpp | 2 +-
.../crash-skipped-bodies-template-inst.cpp | 4 +--
clang/test/CodeCompletion/skip-auto-funcs.cpp | 12 +++----
clang/test/Misc/warning-flags-enabled.c | 2 +-
clang/test/Modules/diag-pragma.c | 2 +-
clang/test/Modules/diag-pragma.cpp | 2 +-
.../crash-skipped-bodies-template-inst.cpp | 4 +--
clang/test/Sema/parentheses.c | 4 +--
.../test/Sema/warn-assignment-bool-context.c | 6 ++--
.../SemaCXX/warn-assignment-bool-context.cpp | 6 ++--
.../SemaCXX/warn-assignment-condition.cpp | 36 +++++++++----------
clang/test/SemaObjC/idiomatic-parentheses.m | 2 +-
clang/test/SemaObjC/self-assign.m | 2 +-
.../SemaOpenACC/compute-construct-if-clause.c | 2 +-
15 files changed, 43 insertions(+), 46 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 70aa54f541819..dbd5c22bd45be 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8474,9 +8474,6 @@ def err_cannot_form_pointer_to_member_of_reference_type : Error<
def err_incomplete_object_call : Error<
"incomplete type in call to object of type %0">;
-def warn_condition_is_assignment : Warning<"using the result of an "
- "assignment as a condition without parentheses">,
- InGroup<Parentheses>;
def warn_assignment_bool_context : Warning<"using the result of an assignment as a truth value without parentheses">,
InGroup<Parentheses>;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 672507ffdad5e..10f53142c58b6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20203,7 +20203,7 @@ bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
SourceLocation Loc;
- unsigned diagnostic = diag::warn_condition_is_assignment;
+ unsigned diagnostic = diag::warn_assignment_bool_context;
bool IsOrAssign = false;
if (BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {
diff --git a/clang/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp b/clang/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp
index 7fec995ba061b..2922761629241 100644
--- a/clang/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp
+++ b/clang/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp
@@ -6,7 +6,7 @@ auto make_func() {
int x;
if (x = 10) {}
// Check that body of this function is actually skipped.
- // CHECK-NOT: crash-skipped-bodies-template-inst.cpp:7:{{[0-9]+}}: warning: using the result of an assignment as a condition without parentheses
+ // CHECK-NOT: crash-skipped-bodies-template-inst.cpp:7:{{[0-9]+}}: warning: using the result of an assignment as a truth value without parentheses
return this;
}
};
@@ -14,7 +14,7 @@ auto make_func() {
int x;
if (x = 10) {}
// Check that this function is not skipped.
- // CHECK: crash-skipped-bodies-template-inst.cpp:15:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK: crash-skipped-bodies-template-inst.cpp:15:9: warning: using the result of an assignment as a truth value without parentheses
return impl();
}
diff --git a/clang/test/CodeCompletion/skip-auto-funcs.cpp b/clang/test/CodeCompletion/skip-auto-funcs.cpp
index c0fa0f556daef..f0dccd8bd9ecd 100644
--- a/clang/test/CodeCompletion/skip-auto-funcs.cpp
+++ b/clang/test/CodeCompletion/skip-auto-funcs.cpp
@@ -7,7 +7,7 @@ auto not_skipped() {
int x;
if (x = 10) {}
// Check that this function is not skipped.
- // CHECK: 8:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK: 8:9: warning: using the result of an assignment as a truth value without parentheses
return 1;
}
@@ -16,7 +16,7 @@ auto lambda_not_skipped = []() {
int x;
if (x = 10) {}
// Check that this function is not skipped.
- // CHECK: 17:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK: 17:9: warning: using the result of an assignment as a truth value without parentheses
return 1;
}
@@ -25,7 +25,7 @@ auto skipped() -> T {
int x;
if (x = 10) {}
// Check that this function is skipped.
- // CHECK-NOT: 26:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK-NOT: 26:9: warning: using the result of an assignment as a truth value without parentheses
return 1;
};
@@ -33,7 +33,7 @@ auto lambda_skipped = []() -> int {
int x;
if (x = 10) {}
// This could potentially be skipped, but it isn't at the moment.
- // CHECK: 34:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK: 34:9: warning: using the result of an assignment as a truth value without parentheses
return 1;
};
@@ -42,7 +42,7 @@ decltype(auto)** not_skipped_ptr() {
int x;
if (x = 10) {}
// Check that this function is not skipped.
- // CHECK: 43:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK: 43:9: warning: using the result of an assignment as a truth value without parentheses
return T();
}
@@ -51,7 +51,7 @@ decltype(auto) not_skipped_decltypeauto() {
int x;
if (x = 10) {}
// Check that this function is not skipped.
- // CHECK: 52:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK: 52:9: warning: using the result of an assignment as a truth value without parentheses
return 1;
}
diff --git a/clang/test/Misc/warning-flags-enabled.c b/clang/test/Misc/warning-flags-enabled.c
index 9f210674b126e..085fb482cb490 100644
--- a/clang/test/Misc/warning-flags-enabled.c
+++ b/clang/test/Misc/warning-flags-enabled.c
@@ -4,7 +4,7 @@
// We just check a few to make sure it's doing something sensible.
//
// CHECK: ext_unterminated_char_or_string
-// CHECK: warn_condition_is_assignment
+// CHECK: warn_assignment_bool_context
// CHECK: warn_null_arg
diff --git a/clang/test/Modules/diag-pragma.c b/clang/test/Modules/diag-pragma.c
index 80224629a1c81..2b592d0de2af3 100644
--- a/clang/test/Modules/diag-pragma.c
+++ b/clang/test/Modules/diag-pragma.c
@@ -6,7 +6,7 @@
@import diag_pragma;
int foo(int x) {
- if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note {{place parentheses}} expected-note {{use '=='}}
return 0;
return 1;
diff --git a/clang/test/Modules/diag-pragma.cpp b/clang/test/Modules/diag-pragma.cpp
index 4b6318045372a..45cb5ba88b2e8 100644
--- a/clang/test/Modules/diag-pragma.cpp
+++ b/clang/test/Modules/diag-pragma.cpp
@@ -40,7 +40,7 @@ int foo(int x) {
void("bar" + x);
- if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note {{place parentheses}} expected-note {{use '=='}}
return 0;
return 1;
diff --git a/clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp b/clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp
index c7ba432d5090b..a9123fec9bcfe 100644
--- a/clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp
+++ b/clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp
@@ -9,7 +9,7 @@ auto make_func() {
;
}
// Check that body of this function is actually skipped.
- // CHECK-NOT: crash-skipped-bodies-template-inst.cpp:7:{{[0-9]+}}: warning: using the result of an assignment as a condition without parentheses
+ // CHECK-NOT: crash-skipped-bodies-template-inst.cpp:7:{{[0-9]+}}: warning: using the result of an assignment as a truth value without parentheses
return this;
}
};
@@ -17,7 +17,7 @@ auto make_func() {
int x;
if (x = 10) {}
// Check that this function is not skipped.
- // CHECK: crash-skipped-bodies-template-inst.cpp:18:9: warning: using the result of an assignment as a condition without parentheses
+ // CHECK: crash-skipped-bodies-template-inst.cpp:18:9: warning: using the result of an assignment as a truth value without parentheses
return impl();
}
diff --git a/clang/test/Sema/parentheses.c b/clang/test/Sema/parentheses.c
index f0090c2ee9d14..041be436adcf4 100644
--- a/clang/test/Sema/parentheses.c
+++ b/clang/test/Sema/parentheses.c
@@ -5,7 +5,7 @@
// Test the various warnings under -Wparentheses
void if_assign(void) {
int i;
- if (i = 4) {} // expected-warning {{assignment as a condition}} \
+ if (i = 4) {} // expected-warning {{assignment as a truth value}} \
// expected-note{{place parentheses around the assignment to silence this warning}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:7-[[@LINE-3]]:7}:"("
@@ -118,4 +118,4 @@ void conditional_op(int x, int y, _Bool b, void* p) {
}
// RUN: not %clang_cc1 -fsyntax-only -Wparentheses -Werror %s 2>&1 | FileCheck %s -check-prefix=CHECK-FLAG
-// CHECK-FLAG: error: using the result of an assignment as a condition without parentheses [-Werror,-Wparentheses]
+// CHECK-FLAG: error: using the result of an assignment as a truth value without parentheses [-Werror,-Wparentheses]
diff --git a/clang/test/Sema/warn-assignment-bool-context.c b/clang/test/Sema/warn-assignment-bool-context.c
index fdefc82eab97a..2c01c63d31bf9 100644
--- a/clang/test/Sema/warn-assignment-bool-context.c
+++ b/clang/test/Sema/warn-assignment-bool-context.c
@@ -14,12 +14,12 @@ bool f3(bool x) { return x = 0; }
void test() {
int x;
- // This should emit the `warn_condition_is_assignment` warning, since
+ // This should emit the `warn_assignment_bool_context` warning once, since
// C doesn't do implicit conversion booleans for conditions.
- if (x = 0) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x = 0) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{place parentheses around the assignment to silence this warning}}\
// expected-note{{use '==' to turn this assignment into an equality comparison}}
- if (x = 4 && x){} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x = 4 && x){} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{place parentheses around the assignment to silence this warning}}\
// expected-note{{use '==' to turn this assignment into an equality comparison}}
diff --git a/clang/test/SemaCXX/warn-assignment-bool-context.cpp b/clang/test/SemaCXX/warn-assignment-bool-context.cpp
index 2973f7ef38290..85e4b9fc2f014 100644
--- a/clang/test/SemaCXX/warn-assignment-bool-context.cpp
+++ b/clang/test/SemaCXX/warn-assignment-bool-context.cpp
@@ -10,11 +10,11 @@ bool f3(bool x) { return x = 0; }
void test() {
int x;
- // Assignments inside of conditions should still emit the more specific `warn_condition_is_assignment` warning.
- if (x = 0) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ // Assignments inside of conditions should still emit the more specific `==` fixits.
+ if (x = 0) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
- if (x = 4 && x){} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x = 4 && x){} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
diff --git a/clang/test/SemaCXX/warn-assignment-condition.cpp b/clang/test/SemaCXX/warn-assignment-condition.cpp
index 65332846bd091..a16d77716cced 100644
--- a/clang/test/SemaCXX/warn-assignment-condition.cpp
+++ b/clang/test/SemaCXX/warn-assignment-condition.cpp
@@ -12,41 +12,41 @@ void test() {
A a, b;
// With scalars.
- if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x = 7) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
if ((x = 7)) {}
do {
- } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ } while (x = 7); // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
do {
} while ((x = 7));
- while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ while (x = 7) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
while ((x = 7)) {}
- for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
for (; (x = 7); ) {}
- if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (p = p) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
if ((p = p)) {}
do {
- } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ } while (p = p); // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
do {
} while ((p = p));
- while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ while (p = p) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
while ((p = p)) {}
- for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ for (; p = p; ) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
for (; (p = p); ) {}
@@ -58,51 +58,51 @@ void test() {
while (A y = a) {}
// With temporaries.
- if (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
if ((x = (b+b).foo())) {}
do {
- } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
do {
} while ((x = (b+b).foo()));
- while (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ while (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
while ((x = (b+b).foo())) {}
- for (; x = (b+b).foo(); ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ for (; x = (b+b).foo(); ) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
for (; (x = (b+b).foo()); ) {}
// With a user-defined operator.
- if (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (a = b + b) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
if ((a = b + b)) {}
do {
- } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ } while (a = b + b); // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
do {
} while ((a = b + b));
- while (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ while (a = b + b) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
while ((a = b + b)) {}
- for (; a = b + b; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ for (; a = b + b; ) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
for (; (a = b + b); ) {}
// Compound assignments.
- if (x |= 2) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (x |= 2) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
- if (a |= b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (a |= b) {} // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
diff --git a/clang/test/SemaObjC/idiomatic-parentheses.m b/clang/test/SemaObjC/idiomatic-parentheses.m
index bed3f0ad40563..8a173678d0be4 100644
--- a/clang/test/SemaObjC/idiomatic-parentheses.m
+++ b/clang/test/SemaObjC/idiomatic-parentheses.m
@@ -25,7 +25,7 @@ - (id) init {
- (id) initWithInt: (int) i {
if (self = [self initWithInt: i]) {
}
- if (self.uid = 100) { // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+ if (self.uid = 100) { // expected-warning {{using the result of an assignment as a truth value without parentheses}} \
// expected-note {{place parentheses around the assignment to silence this warning}} \
// expected-note {{use '==' to turn this assignment into an equality comparison}}
// ...
diff --git a/clang/test/SemaObjC/self-assign.m b/clang/test/SemaObjC/self-assign.m
index d2bd3f4c81976..7b38113e88e2d 100644
--- a/clang/test/SemaObjC/self-assign.m
+++ b/clang/test/SemaObjC/self-assign.m
@@ -5,7 +5,7 @@ @interface A
@implementation A
- (id):(int)x :(int)y {
int z;
- if (self = [self :x :y]) {} // expected-warning{{using the result of an assignment as a condition without parentheses}} \
+ if (self = [self :x :y]) {} // expected-warning{{using the result of an assignment as a truth value without parentheses}} \
// expected-note{{use '==' to turn this assignment into an equality comparison}} \
// expected-note{{place parentheses around the assignment to silence this warning}}
return self;
diff --git a/clang/test/SemaOpenACC/compute-construct-if-clause.c b/clang/test/SemaOpenACC/compute-construct-if-clause.c
index 4629b1b2c2bd0..e34b9be377d69 100644
--- a/clang/test/SemaOpenACC/compute-construct-if-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-if-clause.c
@@ -28,7 +28,7 @@ void BoolExpr(int *I, float *F) {
while(0);
// expected-warning at +4{{incompatible pointer types assigning to 'int *' from 'float *'}}
- // expected-warning at +3{{using the result of an assignment as a condition without parentheses}}
+ // expected-warning at +3{{using the result of an assignment as a truth value without parentheses}}
// expected-note at +2{{place parentheses around the assignment to silence this warning}}
// expected-note at +1{{use '==' to turn this assignment into an equality comparison}}
#pragma acc kernels if (I = F)
More information about the cfe-commits
mailing list