Author: Sirraide Date: 2024-03-13T14:59:55+01:00 New Revision: 2cf2bc472da87bb4bf971b1448e05b9e3bd983dc
URL: https://github.com/llvm/llvm-project/commit/2cf2bc472da87bb4bf971b1448e05b9e3bd983dc DIFF: https://github.com/llvm/llvm-project/commit/2cf2bc472da87bb4bf971b1448e05b9e3bd983dc.diff LOG: [Clang] [CodeGen] Fix codegen bug in constant initialisation in C23 mode (#84981) Consider the following code: ```c bool const inf = (1.0/0.0); ``` When trying to emit the initialiser of this variable in C23, we end up hitting a code path in codegen in `VarDecl::evaluateValueImpl()` where we check for `IsConstantInitialization && (Ctx.getLangOpts().CPlusPlus || Ctx.getLangOpts().C23)`, and if that is the case and we emitted any notes, constant evaluation fails, and as a result, codegen issues this error: ``` <source>:1:12: error: cannot compile this static initializer yet 1 | bool const inf = (1.0/0.0); | ``` As a fix, only fail in C23 mode if we’re initialising a `constexpr` variable. This fixes #84784. Added: clang/test/Sema/const-init.c Modified: clang/lib/AST/Decl.cpp clang/test/CodeGen/const-init.c Removed: ################################################################################ diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 8626f04012f7d4..95900afdd2c5d8 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2577,11 +2577,14 @@ APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes, bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, Ctx, this, Notes, IsConstantInitialization); - // In C++/C23, this isn't a constant initializer if we produced notes. In that - // case, we can't keep the result, because it may only be correct under the - // assumption that the initializer is a constant context. + // In C++, or in C23 if we're initialising a 'constexpr' variable, this isn't + // a constant initializer if we produced notes. In that case, we can't keep + // the result, because it may only be correct under the assumption that the + // initializer is a constant context. if (IsConstantInitialization && - (Ctx.getLangOpts().CPlusPlus || Ctx.getLangOpts().C23) && !Notes.empty()) + (Ctx.getLangOpts().CPlusPlus || + (isConstexpr() && Ctx.getLangOpts().C23)) && + !Notes.empty()) Result = false; // Ensure the computed APValue is cleaned up later if evaluation succeeded, diff --git a/clang/test/CodeGen/const-init.c b/clang/test/CodeGen/const-init.c index 0e4fc4ad48af8d..ad3e9551199ac2 100644 --- a/clang/test/CodeGen/const-init.c +++ b/clang/test/CodeGen/const-init.c @@ -216,3 +216,6 @@ int PR4517_x2 = PR4517_arrc[PR4517_idx]; // CHECK: @PR4517_x = global i32 42, align 4 // CHECK: @PR4517_idx = constant i32 1, align 4 // CHECK: @PR4517_x2 = global i32 42, align 4 + +// CHECK: @GH84784_inf = constant i8 1 +_Bool const GH84784_inf = (1.0/0.0); diff --git a/clang/test/Sema/const-init.c b/clang/test/Sema/const-init.c new file mode 100644 index 00000000000000..5b07ede747ebc4 --- /dev/null +++ b/clang/test/Sema/const-init.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s + +// Division by 0 here is an error iff the variable is 'constexpr'. +const _Bool inf1 = (1.0/0.0 == __builtin_inf()); +constexpr _Bool inf2 = (1.0/0.0 == __builtin_inf()); // expected-error {{must be initialized by a constant expression}} expected-note {{division by zero}} +constexpr _Bool inf3 = __builtin_inf() == __builtin_inf(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits