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 <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins 2026-03-27 04:53:01 -04:00 committed by GitHub
parent 906912d752
commit 5c0c421481
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 10 deletions

View File

@ -1462,15 +1462,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();
}

View File

@ -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;

View File

@ -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");
}

View File

@ -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