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 <p...@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@-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); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits