aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2020-12-03 10:01:53 -0500
committerErik Pilkington <erik.pilkington@gmail.com>2020-12-04 10:03:23 -0500
commit090dd647d98dc50a56a42fbba0f3f11b10a3a187 (patch)
tree039abc03675d9ee0c23b7915500ecf829557b74b /clang/lib/Parse/ParseDecl.cpp
parentc8ec685ca555459051125f9c0194ceee19e959d7 (diff)
downloadllvm-090dd647d98dc50a56a42fbba0f3f11b10a3a187.zip
llvm-090dd647d98dc50a56a42fbba0f3f11b10a3a187.tar.gz
llvm-090dd647d98dc50a56a42fbba0f3f11b10a3a187.tar.bz2
[Sema] Fold VLAs to constant arrays in a few more contexts
552c6c2 removed support for promoting VLAs to constant arrays when the bounds isn't an ICE, since this can result in miscompiling a conforming program that assumes that the array is a VLA. Promoting VLAs for fields is still supported, since clang doesn't support VLAs in fields, so no conforming program could have a field VLA. This change is really disruptive, so this commit carves out two more cases where we promote VLAs which can't miscompile a conforming program: - When the VLA appears in an ivar -- this seems like a corollary to the field thing - When the VLA has an initializer -- VLAs can't have an initializer Differential revision: https://reviews.llvm.org/D90871
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp37
1 files changed, 29 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 277a67f..c3c56dd 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2192,7 +2192,22 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
}
};
- // Inform the current actions module that we just parsed this declarator.
+ enum class InitKind { Uninitialized, Equal, CXXDirect, CXXBraced };
+ InitKind TheInitKind;
+ // If a '==' or '+=' is found, suggest a fixit to '='.
+ if (isTokenEqualOrEqualTypo())
+ TheInitKind = InitKind::Equal;
+ else if (Tok.is(tok::l_paren))
+ TheInitKind = InitKind::CXXDirect;
+ else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
+ (!CurParsedObjCImpl || !D.isFunctionDeclarator()))
+ TheInitKind = InitKind::CXXBraced;
+ else
+ TheInitKind = InitKind::Uninitialized;
+ if (TheInitKind != InitKind::Uninitialized)
+ D.setHasInitializer();
+
+ // Inform Sema that we just parsed this declarator.
Decl *ThisDecl = nullptr;
Decl *OuterDecl = nullptr;
switch (TemplateInfo.Kind) {
@@ -2254,9 +2269,9 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
}
}
+ switch (TheInitKind) {
// Parse declarator '=' initializer.
- // If a '==' or '+=' is found, suggest a fixit to '='.
- if (isTokenEqualOrEqualTypo()) {
+ case InitKind::Equal: {
SourceLocation EqualLoc = ConsumeToken();
if (Tok.is(tok::kw_delete)) {
@@ -2311,7 +2326,9 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
Actions.AddInitializerToDecl(ThisDecl, Init.get(),
/*DirectInit=*/false);
}
- } else if (Tok.is(tok::l_paren)) {
+ break;
+ }
+ case InitKind::CXXDirect: {
// Parse C++ direct initializer: '(' expression-list ')'
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
@@ -2365,8 +2382,9 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
Actions.AddInitializerToDecl(ThisDecl, Initializer.get(),
/*DirectInit=*/true);
}
- } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
- (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
+ break;
+ }
+ case InitKind::CXXBraced: {
// Parse C++0x braced-init-list.
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
@@ -2381,9 +2399,12 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
Actions.ActOnInitializerError(ThisDecl);
} else
Actions.AddInitializerToDecl(ThisDecl, Init.get(), /*DirectInit=*/true);
-
- } else {
+ break;
+ }
+ case InitKind::Uninitialized: {
Actions.ActOnUninitializedDecl(ThisDecl);
+ break;
+ }
}
Actions.FinalizeDeclaration(ThisDecl);