summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp74
1 files changed, 71 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 43e61d3429f..5f5f4c8d044 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6107,6 +6107,77 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
ExprResult
Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
SourceLocation RBraceLoc) {
+ // Only produce each kind of designated initialization diagnostic once.
+ SourceLocation FirstDesignator;
+ bool DiagnosedArrayDesignator = false;
+ bool DiagnosedNestedDesignator = false;
+ bool DiagnosedMixedDesignator = false;
+
+ // Check that any designated initializers are syntactically valid in the
+ // current language mode.
+ for (unsigned I = 0, E = InitArgList.size(); I != E; ++I) {
+ if (auto *DIE = dyn_cast<DesignatedInitExpr>(InitArgList[I])) {
+ if (FirstDesignator.isInvalid())
+ FirstDesignator = DIE->getBeginLoc();
+
+ if (!getLangOpts().CPlusPlus)
+ break;
+
+ if (!DiagnosedNestedDesignator && DIE->size() > 1) {
+ DiagnosedNestedDesignator = true;
+ Diag(DIE->getBeginLoc(), diag::ext_designated_init_nested)
+ << DIE->getDesignatorsSourceRange();
+ }
+
+ for (auto &Desig : DIE->designators()) {
+ if (!Desig.isFieldDesignator() && !DiagnosedArrayDesignator) {
+ DiagnosedArrayDesignator = true;
+ Diag(Desig.getBeginLoc(), diag::ext_designated_init_array)
+ << Desig.getSourceRange();
+ }
+ }
+
+ if (!DiagnosedMixedDesignator &&
+ !isa<DesignatedInitExpr>(InitArgList[0])) {
+ DiagnosedMixedDesignator = true;
+ Diag(DIE->getBeginLoc(), diag::ext_designated_init_mixed)
+ << DIE->getSourceRange();
+ Diag(InitArgList[0]->getBeginLoc(), diag::note_designated_init_mixed)
+ << InitArgList[0]->getSourceRange();
+ }
+ } else if (getLangOpts().CPlusPlus && !DiagnosedMixedDesignator &&
+ isa<DesignatedInitExpr>(InitArgList[0])) {
+ DiagnosedMixedDesignator = true;
+ auto *DIE = cast<DesignatedInitExpr>(InitArgList[0]);
+ Diag(DIE->getBeginLoc(), diag::ext_designated_init_mixed)
+ << DIE->getSourceRange();
+ Diag(InitArgList[I]->getBeginLoc(), diag::note_designated_init_mixed)
+ << InitArgList[I]->getSourceRange();
+ }
+ }
+
+ if (FirstDesignator.isValid()) {
+ // Only diagnose designated initiaization as a C++20 extension if we didn't
+ // already diagnose use of (non-C++20) C99 designator syntax.
+ if (getLangOpts().CPlusPlus && !DiagnosedArrayDesignator &&
+ !DiagnosedNestedDesignator && !DiagnosedMixedDesignator) {
+ Diag(FirstDesignator, getLangOpts().CPlusPlus2a
+ ? diag::warn_cxx17_compat_designated_init
+ : diag::ext_cxx_designated_init);
+ } else if (!getLangOpts().CPlusPlus && !getLangOpts().C99) {
+ Diag(FirstDesignator, diag::ext_designated_init);
+ }
+ }
+
+ return BuildInitList(LBraceLoc, InitArgList, RBraceLoc);
+}
+
+ExprResult
+Sema::BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
+ SourceLocation RBraceLoc) {
+ // Semantic analysis for initializers is done by ActOnDeclarator() and
+ // CheckInitializer() - it requires knowledge of the object being initialized.
+
// Immediately handle non-overload placeholders. Overloads can be
// resolved contextually, but everything else here can't.
for (unsigned I = 0, E = InitArgList.size(); I != E; ++I) {
@@ -6121,9 +6192,6 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
}
}
- // Semantic analysis for initializers is done by ActOnDeclarator() and
- // CheckInitializer() - it requires knowledge of the object being initialized.
-
InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitArgList,
RBraceLoc);
E->setType(Context.VoidTy); // FIXME: just a place holder for now.
OpenPOWER on IntegriCloud