https://github.com/hawkinsw updated https://github.com/llvm/llvm-project/pull/187796
>From 6ca6ec6cbc5e9032fc4fbe3836abdf4f5ce97853 Mon Sep 17 00:00:00 2001 From: Will Hawkins <[email protected]> Date: Fri, 20 Mar 2026 17:18:12 -0400 Subject: [PATCH] Support Serializing/Deserializing Extended Generic Selection Expressions Clang supports using a type as the predicate for generic selection expressions but lacked support for serializing/deserializing these extended generic selection expressions. Signed-off-by: Will Hawkins <[email protected]> --- clang/lib/Serialization/ASTReaderStmt.cpp | 11 ++++++----- clang/lib/Serialization/ASTWriterStmt.cpp | 18 +++++++++++++----- .../Inputs/generic-type.c | 4 ++++ .../generic-selection-expr/test-type.c | 3 +++ 4 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c create mode 100644 clang/test/ASTMerge/generic-selection-expr/test-type.c diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f351e185e5b58..b11b84e86464c 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1458,15 +1458,16 @@ void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) { E->DefaultLoc = readSourceLocation(); E->RParenLoc = readSourceLocation(); + // During serialization, either one more Stmt or one more + // TypeSourceInfo was encoded to account for the predicate + // (whether it was an expression or a type). Stmt **Stmts = E->getTrailingObjects<Stmt *>(); - // Add 1 to account for the controlling expression which is the first - // expression in the trailing array of Stmt *. This is not needed for - // the trailing array of TypeSourceInfo *. - for (unsigned I = 0, N = NumAssocs + 1; I < N; ++I) + for (unsigned I = 0, N = NumAssocs + (E->IsExprPredicate ? 1 : 0); I < N; ++I) Stmts[I] = Record.readSubExpr(); TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>(); - for (unsigned I = 0, N = NumAssocs; I < N; ++I) + for (unsigned I = 0, N = NumAssocs + (!E->IsExprPredicate ? 1 : 0); I < N; + ++I) TSIs[I] = readTypeSourceInfo(); } diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index d9b95e53f2da0..e7a9b3f62ca11 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprOpenMP.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/TypeBase.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTRecordWriter.h" #include "llvm/Bitstream/BitstreamWriter.h" @@ -1418,15 +1419,22 @@ void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) { Record.AddSourceLocation(E->getDefaultLoc()); Record.AddSourceLocation(E->getRParenLoc()); + // Either the trailing Stmt-s or the trailing TypeSourceInfo-s + // will hold one more item than the number of associations + // to account for the predicate (whether it is an expression + // or a type). Stmt **Stmts = E->getTrailingObjects<Stmt *>(); - // Add 1 to account for the controlling expression which is the first - // expression in the trailing array of Stmt *. This is not needed for - // the trailing array of TypeSourceInfo *. - for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I) + for (unsigned I = 0, N = E->numTrailingObjects( + ASTConstraintSatisfaction::OverloadToken<Stmt *>()); + I < N; ++I) Record.AddStmt(Stmts[I]); TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>(); - for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I) + for (unsigned + I = 0, + N = E->numTrailingObjects( + ASTConstraintSatisfaction::OverloadToken<TypeSourceInfo *>()); + I < N; ++I) Record.AddTypeSourceInfo(TSIs[I]); Code = serialization::EXPR_GENERIC_SELECTION; diff --git a/clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c b/clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c new file mode 100644 index 0000000000000..d802b4398c760 --- /dev/null +++ b/clang/test/ASTMerge/generic-selection-expr/Inputs/generic-type.c @@ -0,0 +1,4 @@ +void f(void) { + _Static_assert(_Generic(int, float : 0, int : 1), "Incorrect semantics of _Generic"); + _Static_assert(_Generic(float, float : 1, int : 0), "Incorrect semantics of _Generic"); +} diff --git a/clang/test/ASTMerge/generic-selection-expr/test-type.c b/clang/test/ASTMerge/generic-selection-expr/test-type.c new file mode 100644 index 0000000000000..e51ec198afa6a --- /dev/null +++ b/clang/test/ASTMerge/generic-selection-expr/test-type.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -std=c11 -emit-pch -o %t.ast %S/Inputs/generic-type.c +// RUN: %clang_cc1 -std=c11 -ast-merge %t.ast -fsyntax-only -verify %s +// expected-no-diagnostics _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
