[clang] [Sema] Fix c23 not checking CheckBoolLikeConversion (PR #79588)
Pil Eghoff via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 28 23:55:34 PST 2024
https://github.com/pileghoff updated https://github.com/llvm/llvm-project/pull/79588
>From 6ea74d7aa0eadd4093350c04de95cbb2bdbaf0eb Mon Sep 17 00:00:00 2001
From: Pil Eghoff <pieg at bang-olufsen.dk>
Date: Fri, 26 Jan 2024 13:30:17 +0100
Subject: [PATCH] [Sema] Fix c23 not checking CheckBoolLikeConversion
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaChecking.cpp | 2 +-
clang/test/C/C2x/n3042.c | 36 ++++++++++++----------
clang/test/Sema/warn-int-in-bool-context.c | 7 +++++
4 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index db3d74e124e7d1d..641fa14ab069ed5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,6 +104,8 @@ Improvements to Clang's time-trace
Bug Fixes in This Version
-------------------------
+- Fixed missing warnings when doing bool-like conversions in C23 (`#79435: https://github.com/llvm/llvm-project/issues/79435`_).
+
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4d280f25cc04c25..8e3bd1cd46076d6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16166,7 +16166,7 @@ static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E,
/// Check conversion of given expression to boolean.
/// Input argument E is a logical expression.
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {
- if (S.getLangOpts().Bool)
+ if (S.getLangOpts().Bool && !S.getLangOpts().C23)
return;
if (E->IgnoreParenImpCasts()->getType()->isAtomicType())
return;
diff --git a/clang/test/C/C2x/n3042.c b/clang/test/C/C2x/n3042.c
index 3f869013af48070..99661b1fb39eba1 100644
--- a/clang/test/C/C2x/n3042.c
+++ b/clang/test/C/C2x/n3042.c
@@ -65,13 +65,15 @@ void test() {
void *other_ptr = null_val;
// Can it be used in all the places a scalar can be used?
- if (null_val) {}
- if (!null_val) {}
- for (;null_val;) {}
- while (nullptr) {}
- null_val && nullptr;
- nullptr || null_val;
- null_val ? 0 : 1;
+ if (null_val) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ if (!null_val) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ for (;null_val;) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ while (nullptr) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ null_val && nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}} \
+ expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ nullptr || null_val; // expected-warning {{implicit conversion of nullptr constant to 'bool'}} \
+ expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ null_val ? 0 : 1; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
sizeof(null_val);
alignas(nullptr_t) int aligned;
@@ -95,12 +97,12 @@ void test() {
// Can it be converted to bool with the result false (this relies on Clang
// accepting additional kinds of constant expressions where an ICE is
// required)?
- static_assert(!nullptr);
- static_assert(!null_val);
- static_assert(nullptr); // expected-error {{static assertion failed due to requirement 'nullptr'}} \
- expected-warning {{implicit conversion of nullptr constant to 'bool'}}
- static_assert(null_val); // expected-error {{static assertion failed due to requirement 'null_val'}} \
- expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ static_assert(!nullptr); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ static_assert(!null_val); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ static_assert(nullptr); // expected-error {{static assertion failed due to requirement 'nullptr'}} \
+ expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ static_assert(null_val); // expected-error {{static assertion failed due to requirement 'null_val'}} \
+ expected-warning {{implicit conversion of nullptr constant to 'bool'}}
// Do equality operators work as expected with it?
static_assert(nullptr == nullptr);
@@ -142,11 +144,11 @@ void test() {
_Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);
// Same for GNU conditional operators?
- _Generic(nullptr ?: nullptr, nullptr_t : 0);
- _Generic(null_val ?: null_val, nullptr_t : 0);
+ _Generic(nullptr ?: nullptr, nullptr_t : 0); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ _Generic(null_val ?: null_val, nullptr_t : 0); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
_Generic(typed_ptr ?: null_val, typeof(typed_ptr) : 0);
- _Generic(null_val ?: typed_ptr, typeof(typed_ptr) : 0);
- _Generic(nullptr ?: typed_ptr, typeof(typed_ptr) : 0);
+ _Generic(null_val ?: typed_ptr, typeof(typed_ptr) : 0); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+ _Generic(nullptr ?: typed_ptr, typeof(typed_ptr) : 0); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
_Generic(typed_ptr ?: nullptr, typeof(typed_ptr) : 0);
// Do we correctly issue type incompatibility diagnostics?
diff --git a/clang/test/Sema/warn-int-in-bool-context.c b/clang/test/Sema/warn-int-in-bool-context.c
index 0c94ebb391f3c53..a6890161b5af89d 100644
--- a/clang/test/Sema/warn-int-in-bool-context.c
+++ b/clang/test/Sema/warn-int-in-bool-context.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wint-in-bool-context %s
// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wall %s
+// RUN: %clang_cc1 -x c -std=c23 -fsyntax-only -verify -Wall %s
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wint-in-bool-context %s
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wall %s
@@ -42,6 +43,9 @@ int test(int a, unsigned b, enum num n) {
r = ONE << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
if (TWO << a) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << a) != 0'?}}
return a;
+
+ a = 1 << 2 ? 0: 1; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
+ a = 1 << a ? 0: 1; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
for (a = 0; 1 << a; a++) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
;
@@ -69,6 +73,9 @@ int test(int a, unsigned b, enum num n) {
// expected-warning at -1 {{converting the enum constant to a boolean}}
return a;
+ if(1 << 5) // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
+ return a;
+
// Don't warn in macros.
return SHIFT(1, a);
}
More information about the cfe-commits
mailing list