Skip to content

Commit 2cf2bc4

Browse files
authored
[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.
1 parent 424e0a8 commit 2cf2bc4

File tree

3 files changed

+16
-4
lines changed

3 files changed

+16
-4
lines changed

clang/lib/AST/Decl.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,11 +2577,14 @@ APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
25772577
bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, Ctx, this, Notes,
25782578
IsConstantInitialization);
25792579

2580-
// In C++/C23, this isn't a constant initializer if we produced notes. In that
2581-
// case, we can't keep the result, because it may only be correct under the
2582-
// assumption that the initializer is a constant context.
2580+
// In C++, or in C23 if we're initialising a 'constexpr' variable, this isn't
2581+
// a constant initializer if we produced notes. In that case, we can't keep
2582+
// the result, because it may only be correct under the assumption that the
2583+
// initializer is a constant context.
25832584
if (IsConstantInitialization &&
2584-
(Ctx.getLangOpts().CPlusPlus || Ctx.getLangOpts().C23) && !Notes.empty())
2585+
(Ctx.getLangOpts().CPlusPlus ||
2586+
(isConstexpr() && Ctx.getLangOpts().C23)) &&
2587+
!Notes.empty())
25852588
Result = false;
25862589

25872590
// Ensure the computed APValue is cleaned up later if evaluation succeeded,

clang/test/CodeGen/const-init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,6 @@ int PR4517_x2 = PR4517_arrc[PR4517_idx];
216216
// CHECK: @PR4517_x = global i32 42, align 4
217217
// CHECK: @PR4517_idx = constant i32 1, align 4
218218
// CHECK: @PR4517_x2 = global i32 42, align 4
219+
220+
// CHECK: @GH84784_inf = constant i8 1
221+
_Bool const GH84784_inf = (1.0/0.0);

clang/test/Sema/const-init.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s
2+
3+
// Division by 0 here is an error iff the variable is 'constexpr'.
4+
const _Bool inf1 = (1.0/0.0 == __builtin_inf());
5+
constexpr _Bool inf2 = (1.0/0.0 == __builtin_inf()); // expected-error {{must be initialized by a constant expression}} expected-note {{division by zero}}
6+
constexpr _Bool inf3 = __builtin_inf() == __builtin_inf();

0 commit comments

Comments
 (0)