Author: Alejandro Álvarez Ayllón Date: 2025-02-18T09:52:31+01:00 New Revision: 252c83bc9ef9fc885e9e6517f1b4423188bb919f
URL: https://github.com/llvm/llvm-project/commit/252c83bc9ef9fc885e9e6517f1b4423188bb919f DIFF: https://github.com/llvm/llvm-project/commit/252c83bc9ef9fc885e9e6517f1b4423188bb919f.diff LOG: [clang][Sema] Fix type of an statement expression ending with an atomic type (#119711) When a statement expression's last statement is an atomic variable, GCC and Clang disagree on the type of the expression. This can be made apparent using `typeof` and forcing a diagnostic message: ```cpp _Atomic int a = 0; typeof(({a;})) x = "0"; ``` * GCC complains about initializing `int` with `char*` * Clang complains about initializing `_Atomic(int)` with a `char[2]` Due to the type of the statement expression being deduced to be atomic, we end with three implicit casts inside the `StmtExpr` on the AST: * `LValueToRValue` -> `AtomicToNonAtomic` -> `NonAtomicToAtomic` In some situations, this can end on an assertion inside `IntExprEvaluator`, as reported in #106576. With this patch, we now have two implicit casts, since the type of the statement expression is deduced to be non-atomic: * `LValueToRValue` -> `AtomicToNonAtomic` This is consistent with the C standard (6.7.2.4, p4) > The properties associated with atomic types are meaningful only for expressions that are lvalues. But a statement expression is an rvalue. `IntExprEvaluator` assumptions are now satisfied and there is no assertion error. Additionally, the `typeof` trick mentioned above shows that the type is consistently deduced between GCC and Clang. Fixes #106576 --------- Co-authored-by: John McCall <rjmcc...@gmail.com> Added: clang/test/Sema/gh106576.c Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaExpr.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6272f32fa845a..a91c764860ccd 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -173,6 +173,7 @@ Bug Fixes to C++ Support Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ +- Fixed type checking when a statement expression ends in an l-value of atomic type. (#GH106576) Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 1e660d7770dc6..fad15bf95c415 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -15949,7 +15949,7 @@ ExprResult Sema::ActOnStmtExprResult(ExprResult ER) { // FIXME: Provide a better location for the initialization. return PerformCopyInitialization( InitializedEntity::InitializeStmtExprResult( - E->getBeginLoc(), E->getType().getUnqualifiedType()), + E->getBeginLoc(), E->getType().getAtomicUnqualifiedType()), SourceLocation(), E); } diff --git a/clang/test/Sema/gh106576.c b/clang/test/Sema/gh106576.c new file mode 100644 index 0000000000000..a72592aac0129 --- /dev/null +++ b/clang/test/Sema/gh106576.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef _Atomic char atomic_char; + +atomic_char counter; + +char load_plus_one(void) { + return ({counter;}) + 1; // no crash +} + +char type_of_stmt_expr(void) { + typeof(({counter;})) y = ""; // expected-error-re {{incompatible pointer to integer conversion initializing 'typeof (({{{.*}}}))' (aka 'char') with an expression of type 'char[1]'}} + return y; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits