Skip to content

Commit fbd0780

Browse files
committed
[AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (llvm#88008)
Use refactored CheckForConstantInitializer() to skip checking expr with error.
1 parent 78c50bb commit fbd0780

File tree

4 files changed

+25
-19
lines changed

4 files changed

+25
-19
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3391,7 +3391,7 @@ class Sema final : public SemaBase {
33913391
bool ConstexprSupported, bool CLinkageMayDiffer);
33923392

33933393
/// type checking declaration initializers (C99 6.7.8)
3394-
bool CheckForConstantInitializer(Expr *e, QualType t);
3394+
bool CheckForConstantInitializer(Expr *Init, unsigned DiagID);
33953395

33963396
QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
33973397
QualType Type, TypeSourceInfo *TSI,

clang/lib/Sema/SemaDecl.cpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12769,7 +12769,7 @@ void Sema::DiagnoseHLSLAttrStageMismatch(
1276912769
<< (AllowedStages.size() != 1) << join(StageStrings, ", ");
1277012770
}
1277112771

12772-
bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
12772+
bool Sema::CheckForConstantInitializer(Expr *Init, unsigned DiagID) {
1277312773
// FIXME: Need strict checking. In C89, we need to check for
1277412774
// any assignment, increment, decrement, function-calls, or
1277512775
// commas outside of a sizeof. In C99, it's the same list,
@@ -12787,8 +12787,7 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
1278712787
const Expr *Culprit;
1278812788
if (Init->isConstantInitializer(Context, false, &Culprit))
1278912789
return false;
12790-
Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
12791-
<< Culprit->getSourceRange();
12790+
Diag(Culprit->getExprLoc(), DiagID) << Culprit->getSourceRange();
1279212791
return true;
1279312792
}
1279412793

@@ -13906,29 +13905,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
1390613905
// OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
1390713906
// This is true even in C++ for OpenCL.
1390813907
} else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
13909-
CheckForConstantInitializer(Init, DclT);
13908+
CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
1391013909

13911-
// Otherwise, C++ does not restrict the initializer.
13910+
// Otherwise, C++ does not restrict the initializer.
1391213911
} else if (getLangOpts().CPlusPlus) {
1391313912
// do nothing
1391413913

1391513914
// C99 6.7.8p4: All the expressions in an initializer for an object that has
1391613915
// static storage duration shall be constant expressions or string literals.
1391713916
} else if (VDecl->getStorageClass() == SC_Static) {
13918-
CheckForConstantInitializer(Init, DclT);
13917+
CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
1391913918

13920-
// C89 is stricter than C99 for aggregate initializers.
13921-
// C89 6.5.7p3: All the expressions [...] in an initializer list
13922-
// for an object that has aggregate or union type shall be
13923-
// constant expressions.
13919+
// C89 is stricter than C99 for aggregate initializers.
13920+
// C89 6.5.7p3: All the expressions [...] in an initializer list
13921+
// for an object that has aggregate or union type shall be
13922+
// constant expressions.
1392413923
} else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
1392513924
isa<InitListExpr>(Init)) {
13926-
const Expr *Culprit;
13927-
if (!Init->isConstantInitializer(Context, false, &Culprit)) {
13928-
Diag(Culprit->getExprLoc(),
13929-
diag::ext_aggregate_init_not_constant)
13930-
<< Culprit->getSourceRange();
13931-
}
13925+
CheckForConstantInitializer(Init, diag::ext_aggregate_init_not_constant);
1393213926
}
1393313927

1393413928
if (auto *E = dyn_cast<ExprWithCleanups>(Init))
@@ -14061,7 +14055,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
1406114055
// Avoid duplicate diagnostics for constexpr variables.
1406214056
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() &&
1406314057
!VDecl->isConstexpr())
14064-
CheckForConstantInitializer(Init, DclT);
14058+
CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
1406514059
}
1406614060

1406714061
QualType InitType = Init->getType();

clang/lib/Sema/SemaExpr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7898,7 +7898,8 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
78987898
if (!LiteralExpr->isTypeDependent() &&
78997899
!LiteralExpr->isValueDependent() &&
79007900
!literalType->isDependentType()) // C99 6.5.2.5p3
7901-
if (CheckForConstantInitializer(LiteralExpr, literalType))
7901+
if (CheckForConstantInitializer(LiteralExpr,
7902+
diag::err_init_element_not_constant))
79027903
return ExprError();
79037904
} else if (literalType.getAddressSpace() != LangAS::opencl_private &&
79047905
literalType.getAddressSpace() != LangAS::Default) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c90
2+
3+
struct S {
4+
int v;
5+
};
6+
7+
struct T; // expected-note {{forward declaration of 'struct T'}}
8+
9+
void gh88008_nocrash(struct T *t) {
10+
struct S s = { .v = t->y }; // expected-error {{incomplete definition of type 'struct T'}}
11+
}

0 commit comments

Comments
 (0)