From 090dd647d98dc50a56a42fbba0f3f11b10a3a187 Mon Sep 17 00:00:00 2001 From: Erik Pilkington Date: Thu, 3 Dec 2020 10:01:53 -0500 Subject: [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 --- clang/lib/Parse/ParseDecl.cpp | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'clang/lib/Parse/ParseDecl.cpp') 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); -- cgit v1.1