Support Narrowing conversions to bool in if constexpr condition
under C++23 language mode.
Only if constexpr is implemented as the behavior of static_assert
is already conforming.
Differential D105127
Implement P1401R5 cor3ntin on Jun 29 2021, 8:33 AM. Authored by
Details
Support Narrowing conversions to bool in if constexpr condition Only if constexpr is implemented as the behavior of static_assert
Diff Detail
Unit Tests
Event Timeline
Comment Actions Fix and add tests for the case where the condition is not convertible to bool Comment Actions Thanks!
Comment Actions Improve and fix test,
Comment Actions So I read the paper, downloaded this patch, played around with it a little bit, tried some different tests, like expressions with dependent types, However, I confirm that the failures in CXX/except/except.spec/p1.cpp detected by the buildbots are real.
Comment Actions Yep, I need to look at that. I've ran the entire test suite locally without issue initially but maybe I broke something!
Comment Actions Its unfortunate the buildbot does not have debug symbols. If you have not managed to reproduce it locally, here is the backtrace I got: FAIL: Clang :: CXX/except/except.spec/p1.cpp (1 of 1) ******************** TEST 'Clang :: CXX/except/except.spec/p1.cpp' FAILED ******************** Script: -- : 'RUN: at line 1'; c:\users\mizve\source\llvm\build\dbg\bin\clang.exe -cc1 -internal-isystem c:\users\mizve\source\llvm\build\dbg\lib\clang\13.0.0\include -nostdsysteminc -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify C:\Users\mizve\source\llvm\clang\test\CXX\except\except.spec\p1.cpp -- Exit Code: 2147483651 Command Output (stdout): -- $ ":" "RUN: at line 1" $ "c:\users\mizve\source\llvm\build\dbg\bin\clang.exe" "-cc1" "-internal-isystem" "c:\users\mizve\source\llvm\build\dbg\lib\clang\13.0.0\include" "-nostdsysteminc" "-std=c++11" "-fexceptions" "-fcxx-exceptions" "-fsyntax-only" "-verify" "C:\Users\mizve\source\llvm\clang\test\CXX\except\except.spec\p1.cpp" # command stderr: Assertion failed: (NoexceptExpr->isTypeDependent() || NoexceptExpr->getType()->getCanonicalTypeUnqualified() == Context.BoolTy) && "Parser should have made sure that the expression is boolean", file C:\Users\mizve\source\llvm\clang\lib\Sema\SemaDeclCXX.cpp, line 17947 PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: c:\\users\\mizve\\source\\llvm\\build\\dbg\\bin\\clang.exe -cc1 -internal-isystem c:\\users\\mizve\\source\\llvm\\build\\dbg\\lib\\clang\\13.0.0\\include -nostdsysteminc -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify C:\\Users\\mizve\\source\\llvm\\clang\\test\\CXX\\except\\except.spec\\p1.cpp 1. <eof> parser at end of file 2. C:\Users\mizve\source\llvm\clang\test\CXX\except\except.spec\p1.cpp:75:1: parsing namespace 'PR11084' 3. C:\Users\mizve\source\llvm\clang\test\CXX\except\except.spec\p1.cpp:76:19: parsing struct/union/class body 'PR11084::A' #0 0x00007ff72b447a6c HandleAbort C:\Users\mizve\source\llvm\llvm\lib\Support\Windows\Signals.inc:408:0 #1 0x00007ffff838bc31 (C:\Windows\SYSTEM32\ucrtbased.dll+0x6bc31) #2 0x00007ffff838d889 (C:\Windows\SYSTEM32\ucrtbased.dll+0x6d889) #3 0x00007ffff83930bf (C:\Windows\SYSTEM32\ucrtbased.dll+0x730bf) #4 0x00007ffff8391091 (C:\Windows\SYSTEM32\ucrtbased.dll+0x71091) #5 0x00007ffff8393a1f (C:\Windows\SYSTEM32\ucrtbased.dll+0x73a1f) #6 0x00007ff72fe2bf2a clang::Sema::checkExceptionSpecification(bool, enum clang::ExceptionSpecificationType, class llvm::ArrayRef<class clang::OpaquePtr<class clang::QualType>>, class llvm::ArrayRef<class clang::SourceRange>, class clang::Expr *, class llvm::SmallVectorImpl<class clang::QualType> &, struct clang::FunctionProtoType::ExceptionSpecInfo &) C:\Users\mizve\source\llvm\clang\lib\Sem #7 0x00007ff72fe2c0ee clang::Sema::actOnDelayedExceptionSpecification(class clang::Decl *, enum clang::ExceptionSpecificationType, class clang::SourceRange, class llvm::ArrayRef<class clang::OpaquePtr<class clang::QualType>>, class llvm::ArrayRef<class clang::SourceRange>, class clang::Expr *) C:\Users\mizve\source\llvm\clang\lib\Sema\SemaDeclCXX.cpp:17983:0 #8 0x00007ff72fb16bd9 clang::Parser::ParseLexedMethodDeclaration(struct clang::Parser::LateParsedMethodDeclaration &) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseCXXInlineMethods.cpp:489:0 ng\lib\Parse\ParseCXXInlineMethods.cpp:257:0 #10 0x00007ff72fb15eb6 clang::Parser::ParseLexedMethodDeclarations(struct clang::Parser::ParsingClass &) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseCXXInlineMethods.cpp:325:0 #11 0x00007ff72fb96995 clang::Parser::ParseCXXMemberSpecification(class clang::SourceLocation, class clang::SourceLocation, struct clang::ParsedAttributesWithRange &, unsigned int, class clang::Decl *) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseDeclCXX.cpp:35#12 0x00007ff72fb95153 clang::Parser::ParseClassSpecifier(enum clang::tok::TokenKind, class clang::SourceLocation, class clang::DeclSpec &, struct clang::Parser::ParsedTemplateInfo const &, enum clang::AccessSpecifier, bool, enum clang::Parser::DeclSpecContext, struct clang::ParsedAttributesWithRange &) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseDeclCXX.cpp:2030:0 #13 0x00007ff72fad24d2 clang::Parser::ParseDeclarationSpecifiers(class clang::DeclSpec &, struct clang::Parser::ParsedTemplateInfo const &, enum clang::AccessSpecifier, enum clang::Parser::DeclSpecContext, class clang::Parser::LateParsedAttrList *) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseDecl.cpp:3989:0 #14 0x00007ff72fb07c7f clang::Parser::ParseSingleDeclarationAfterTemplate(enum clang::DeclaratorContext, struct clang::Parser::ParsedTemplateInfo const &, class clang::ParsingDeclRAIIObject &, class clang::SourceLocation &, class clang::ParsedAttributes &, enum clang::AccessSpecifier) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseTemplate.cpp:225:0 #15 0x00007ff72fb078fa clang::Parser::ParseTemplateDeclarationOrSpecialization(enum clang::DeclaratorContext, class clang::SourceLocation &, class clang::ParsedAttributes &, enum clang::AccessSpecifier) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseTemplate.cpp:169:0 #16 0x00007ff72fb07297 clang::Parser::ParseDeclarationStartingWithTemplate(enum clang::DeclaratorContext, class clang::SourceLocation &, class clang::ParsedAttributes &, enum clang::AccessSpecifier) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseTemplate.cpp:46:0 #17 0x00007ff72faca50a clang::Parser::ParseDeclaration(enum clang::DeclaratorContext, class clang::SourceLocation &, struct clang::ParsedAttributesWithRange &, class clang::SourceLocation *) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseDecl.cpp:1718:0 #18 0x00007ff72fa84fc9 clang::Parser::ParseExternalDeclaration(struct clang::ParsedAttributesWithRange &, class clang::ParsingDeclSpec *) C:\Users\mizve\source\llvm\clang\lib\Parse\Parser.cpp:907:0 #19 0x00007ff72fb8eff8 clang::Parser::ParseInnerNamespace(class llvm::SmallVector<struct clang::Parser::InnerNamespaceInfo, 4> const &, unsigned int, class clang::SourceLocation &, class clang::ParsedAttributes &, class clang::BalancedDelimiterTracker &) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseDeclCXX.cpp:247:0 #20 0x00007ff72fb8ede0 clang::Parser::ParseNamespace(enum clang::DeclaratorContext, class clang::SourceLocation &, class clang::SourceLocation) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseDeclCXX.cpp:227:0 #21 0x00007ff72faca6ea clang::Parser::ParseDeclaration(enum clang::DeclaratorContext, class clang::SourceLocation &, struct clang::ParsedAttributesWithRange &, class clang::SourceLocation *) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseDecl.cpp:1731:0 #22 0x00007ff72fa84fc9 clang::Parser::ParseExternalDeclaration(struct clang::ParsedAttributesWithRange &, class clang::ParsingDeclSpec *) C:\Users\mizve\source\llvm\clang\lib\Parse\Parser.cpp:907:0 #23 0x00007ff72fa7fd34 clang::Parser::ParseTopLevelDecl(class clang::OpaquePtr<class clang::DeclGroupRef> &, bool) C:\Users\mizve\source\llvm\clang\lib\Parse\Parser.cpp:719:0 #24 0x00007ff72fa7c078 clang::ParseAST(class clang::Sema &, bool, bool) C:\Users\mizve\source\llvm\clang\lib\Parse\ParseAST.cpp:158:0 #25 0x00007ff72c913df7 clang::ASTFrontendAction::ExecuteAction(void) C:\Users\mizve\source\llvm\clang\lib\Frontend\FrontendAction.cpp:1060:0 #26 0x00007ff72c9137ae clang::FrontendAction::Execute(void) C:\Users\mizve\source\llvm\clang\lib\Frontend\FrontendAction.cpp:955:0 #27 0x00007ff72c8944a6 clang::CompilerInstance::ExecuteAction(class clang::FrontendAction &) C:\Users\mizve\source\llvm\clang\lib\Frontend\CompilerInstance.cpp:974:0 #28 0x00007ff72cafc037 clang::ExecuteCompilerInvocation(class clang::CompilerInstance *) C:\Users\mizve\source\llvm\clang\lib\FrontendTool\ExecuteCompilerInvocation.cpp:278:0 #29 0x00007ff726c93e04 cc1_main(class llvm::ArrayRef<char const *>, char const *, void *) C:\Users\mizve\source\llvm\clang\tools\driver\cc1_main.cpp:246:0 #30 0x00007ff726c7fa40 ExecuteCC1Tool C:\Users\mizve\source\llvm\clang\tools\driver\driver.cpp:338:0 #31 0x00007ff726c8032b main C:\Users\mizve\source\llvm\clang\tools\driver\driver.cpp:415:0 #32 0x00007ff7325e7a99 invoke_main d:\agent\_work\36\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79:0 #33 0x00007ff7325e793e __scrt_common_main_seh d:\agent\_work\36\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0 #34 0x00007ff7325e77fe __scrt_common_main d:\agent\_work\36\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331:0 #35 0x00007ff7325e7b2e mainCRTStartup d:\agent\_work\36\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:0 #36 0x00007ff87d467034 (C:\Windows\System32\KERNEL32.DLL+0x17034) #37 0x00007ff87d5a2651 (C:\Windows\SYSTEM32\ntdll.dll+0x52651) error: command failed with exit status: 2147483651 Comment Actions Yep, I need to look at that. I've ran the entire test suite locally without issue initially but maybe I broke something! Thanks. Comment Actions Fix Formatting in tests. Do not return early for value dependent expressions Comment Actions LGTM! Since you submitted this quite recently, I would wait some more time before landing, for any other people who might want to review this.
Comment Actions P1401R5 points out that we get noexcept(bool) wrong in the opposite direction, permitting conversions to bool that we are supposed to reject. While that rule didn't change as part of P1401R5, it'd be nice to handle it as part of dealing with that paper.
Comment Actions Would we benefit from any more test coverage for the static_assert side of this paper, or is our (formerly wrong and now correct) behavior already well-covered by existing tests? (Similarly for explicit(bool), do we already have good test coverage for the distinction between "contextually converted constant expression of type bool" and the various other possible rules?) Comment Actions To be clear: doing that as a separate change is completely fine, but we should make sure we don't forget about it!
Comment Actions This LGTM aside from a small nit, but you should wait a bit to land in case other reviewers have comments.
Comment Actions Oops, I chanted the magic incantation but forgot to press the button. LGTM again. ;-) Comment Actions Thanks for the patch! I've committed on your behalf in 8747234032c9c6270a6198ab3cca14ce2bd18721. |
Looks a bit easier to parse the english there.