On 19 December 2016 at 13:22, Mike Aizatsky <aizat...@google.com> wrote:
> Richard, > > Clang crashes for me on this code while doing "check-all". This change > seems to introduce the assert. Can you take a look? > > BTW I'm not sure why bots are green. Do we build libcxx with bootstrap > compiler? > Apparently not in C++1z mode at least. The cause was an extremely-longstanding bug whereby we would create K&R C function prototypes for some builtin functions in C++! Should be fixed in r290146 (I'm still running through the libc++ testsuite with an asserts-enabled clang with the fix, but it looks good so far). > FAIL: libc++ :: std/experimental/string.view/ > string.view.find/find_last_of_pointer_size_size.pass.cpp (34988 of 39764) > ******************** TEST 'libc++ :: std/experimental/string.view/ > string.view.find/find_last_of_pointer_size_size.pass.cpp' FAILED > ******************** > Command: ['/usr/local/google/home/aizatsky/out/llvm/bootstrap/bin/clang++', > '-o', '/usr/local/google/home/aizatsky/out/llvm/default/ > projects/libcxx/test/std/experimental/string.view/ > string.view.find/Output/find > _last_of_pointer_size_size.pass.cpp.o', '-x', 'c++', > '/usr/local/google/home/aizatsky/src/llvm/projects/ > libcxx/test/std/experimental/string.view/string.view.find/ > find_last_of_pointer_size_size.pass.cpp', '-c', > '-v', '-Werror=thread-safety', '-std=c++1z', '-include', > '/usr/local/google/home/aizatsky/src/llvm/projects/ > libcxx/test/support/nasty_macros.hpp', '-nostdinc++', > '-I/usr/local/google/home/aizatsky/src/llvm/proj > ects/libcxx/include', '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', > '-D__STDC_CONSTANT_MACROS', '-I/usr/local/google/home/ > aizatsky/src/llvm/projects/libcxx/test/support', > '-DLIBCXX_FILESYSTEM_STATIC_TEST_R > OOT="/usr/local/google/home/aizatsky/src/llvm/projects/ > libcxx/test/std/experimental/filesystem/Inputs/static_test_env"', > '-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT="/usr/local/google/ > home/aizatsky/out/llvm/default/ > projects/libcxx/test/filesystem/Output/dynamic_env"', > '-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="/usr/bin/python2.7 > /usr/local/google/home/aizatsky/src/llvm/projects/libcxx/test/support/ > filesystem_dynamic_test_h > elper.py"', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', '-Wextra', > '-Werror', '-Wshadow', '-Wshadow', '-Wno-unused-command-line-argument', > '-Wno-attributes', '-Wno-pessimizing-move', '-Wno-c++11-extension > s', '-Wno-user-defined-literals', '-Wno-sign-compare', > '-Wno-unused-variable', '-Wno-unused-parameter', > '-Wno-unused-local-typedef', '-c'] > Exit Code: 254 > Standard Error: > -- > clang version 4.0.0 (trunk 290130) (llvm/trunk 290127) > Target: x86_64-unknown-linux-gnu > Thread model: posix > InstalledDir: /usr/local/google/home/aizatsky/out/llvm/bootstrap/bin > Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.8 > Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.8.4 > Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9 > Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9.3 > Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7 > Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7.3 > Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8 > Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.4 > Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9 > Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3 > Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8 > Candidate multilib: .;@m64 > Candidate multilib: 32;@m32 > Candidate multilib: x32;@mx32 > Selected multilib: .;@m64 > "/usr/local/google/home/aizatsky/out/llvm/bootstrap/bin/clang-3.8" -cc1 > -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free > -main-file-name find_last_of_pointer_size_size.pass.cpp -mrelocation > -model static -mthread-model posix -mdisable-fp-elim -fmath-errno > -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array > -target-cpu x86-64 -v -dwarf-column-info -debugger-tuning=gdb -coverage-not > es-file /usr/local/google/home/aizatsky/out/llvm/default/ > projects/libcxx/test/std/experimental/string.view/ > string.view.find/Output/find_last_of_pointer_size_size.pass.cpp.gcno > -nostdinc++ -resource-dir /usr/loc > al/google/home/aizatsky/out/llvm/bootstrap/bin/../lib/clang/4.0.0 > -include /usr/local/google/home/aizatsky/src/llvm/projects/ > libcxx/test/support/nasty_macros.hpp -I /usr/local/google/home/ > aizatsky/src/llvm/proj > ects/libcxx/include -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D > __STDC_CONSTANT_MACROS -I /usr/local/google/home/ > aizatsky/src/llvm/projects/libcxx/test/support -D > "LIBCXX_FILESYSTEM_STATIC_TEST_ROOT=\"/us > r/local/google/home/aizatsky/src/llvm/projects/libcxx/test/ > std/experimental/filesystem/Inputs/static_test_env\"" -D > "LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT=\"/usr/local/google/ > home/aizatsky/out/llvm/default/projec > ts/libcxx/test/filesystem/Output/dynamic_env\"" -D > "LIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER=\"/usr/bin/python2.7 > /usr/local/google/home/aizatsky/src/llvm/projects/libcxx/test/support/ > filesystem_dynamic_test_helpe > r.py\"" -D _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem > /usr/local/include -internal-isystem /usr/local/google/home/ > aizatsky/out/llvm/bootstrap/bin/../lib/clang/4.0.0/include > -internal-externc-isystem > /usr/include/x86_64-linux-gnu -internal-externc-isystem /include > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall -Wextra > -Werror -Wshadow -Wshadow -Wno-unused-command-line-argument -Wno-attri > butes -Wno-pessimizing-move -Wno-c++11-extensions > -Wno-user-defined-literals -Wno-sign-compare -Wno-unused-variable > -Wno-unused-parameter -Wno-unused-local-typedef -std=c++1z > -fdeprecated-macro -fdebug-compilat > ion-dir /usr/local/google/home/aizatsky/out/llvm/default/ > projects/libcxx/test/std/experimental/string.view/string.view.find > -ferror-limit 19 -fmessage-length 0 -fobjc-runtime=gcc -fcxx-exceptions > -fexceptions - > fdiagnostics-show-option -o /usr/local/google/home/ > aizatsky/out/llvm/default/projects/libcxx/test/std/ > experimental/string.view/string.view.find/Output/find_ > last_of_pointer_size_size.pass.cpp.o -x c++ /usr/local > /google/home/aizatsky/src/llvm/projects/libcxx/test/std/ > experimental/string.view/string.view.find/find_last_of_ > pointer_size_size.pass.cpp > clang -cc1 version 4.0.0 based upon LLVM 4.0.0svn default target > x86_64-unknown-linux-gnu > ignoring nonexistent directory "/include" > #include "..." search starts here: > #include <...> search starts here: > /usr/local/google/home/aizatsky/src/llvm/projects/libcxx/include > /usr/local/google/home/aizatsky/src/llvm/projects/libcxx/test/support > /usr/local/include > /usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/../lib/clang/4.0.0/include > /usr/include/x86_64-linux-gnu > /usr/include > End of search list. > clang-3.8: > /usr/local/google/home/aizatsky/src/llvm/include/llvm/Support/Casting.h:229: > typename llvm::cast_retty<To, From>::ret_type llvm::cast(Y&) [with X = > clang::FunctionProtoType; Y = clang::QualType; type > name llvm::cast_retty<To, From>::ret_type = const > clang::FunctionProtoType*]: Assertion `isa<X>(Val) && "cast<Ty>() argument > of incompatible type!"' failed. > #0 0x0000000001d69335 llvm::sys::PrintStackTrace(llvm::raw_ostream&) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x1d69335) > #1 0x0000000001d6734e llvm::sys::RunSignalHandlers() > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x1d6734e) > #2 0x0000000001d674b2 SignalHandler(int) (/usr/local/google/home/ > aizatsky/out/llvm/bootstrap/bin/clang-3.8+0x1d674b2) > #3 0x00007faad044a330 __restore_rt (/lib/x86_64-linux-gnu/ > libpthread.so.0+0x10330) > #4 0x00007faacf245c37 gsignal /build/eglibc-oGUzwX/eglibc-2. > 19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0 > #5 0x00007faacf249028 abort /build/eglibc-oGUzwX/eglibc-2. > 19/stdlib/abort.c:91:0 > #6 0x00007faacf23ebf6 __assert_fail_base /build/eglibc-oGUzwX/eglibc-2. > 19/assert/assert.c:92:0 > #7 0x00007faacf23eca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2) > #8 0x00000000032bfb1c (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x32bfb1c) > #9 0x00000000032bfc3d > clang::ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(clang::QualType, > clang::QualType) (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x32bfc3d) > #10 0x0000000002baaee1 clang::Sema::CheckFunctionDeclaration(clang::Scope*, > clang::FunctionDecl*, clang::LookupResult&, bool) (/usr/local/google/home/ > aizatsky/out/llvm/bootstrap/bin/clang-3.8+0x2baaee1) > #11 0x0000000002baf81e clang::Sema::ActOnFunctionDeclarator(clang::Scope*, > clang::Declarator&, clang::DeclContext*, clang::TypeSourceInfo*, > clang::LookupResult&, llvm::MutableArrayRef<clang::TemplateParameterLi > st*>, bool&) (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x2baf81e) > #12 0x0000000002bb5c2d clang::Sema::HandleDeclarator(clang::Scope*, > clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/bin/clang-3.8+0x > 2bb5c2d) > #13 0x0000000002bb61f9 clang::Sema::ActOnDeclarator(clang::Scope*, > clang::Declarator&) (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x2bb61f9) > #14 0x0000000002909884 clang::Parser::ParseDeclarationAfterDeclarato > rAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo > const&, clang::Parser::ForRangeInit*) (/usr/local/google/home/aizatsky/ou > t/llvm/bootstrap/bin/clang-3.8+0x2909884) > #15 0x0000000002918779 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, > unsigned int, clang::SourceLocation*, clang::Parser::ForRangeInit*) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/bin/clang-3. > 8+0x2918779) > #16 0x00000000028f84b2 clang::Parser::ParseDeclOrFunctionDefInternal > (clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, > clang::AccessSpecifier) (/usr/local/google/home/aizatsky/out/llvm/bootstr > ap/bin/clang-3.8+0x28f84b2) > #17 0x00000000028f8bae clang::Parser::ParseDeclarationOrFunctionDefi > nition(clang::Parser::ParsedAttributesWithRange&, > clang::ParsingDeclSpec*, clang::AccessSpecifier) (/usr/local/google/home/ > aizatsky/out/llvm/b > ootstrap/bin/clang-3.8+0x28f8bae) > #18 0x00000000028fc84f clang::Parser::ParseExternalDeclaration( > clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x28fc84f) > #19 0x000000000292f8ff clang::Parser::ParseLinkage(clang::ParsingDeclSpec&, > unsigned int) (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x292f8ff) > #20 0x00000000028f85cd clang::Parser::ParseDeclOrFunctionDefInternal > (clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, > clang::AccessSpecifier) (/usr/local/google/home/aizatsky/out/llvm/bootstr > ap/bin/clang-3.8+0x28f85cd) > #21 0x00000000028f8bae clang::Parser::ParseDeclarationOrFunctionDefi > nition(clang::Parser::ParsedAttributesWithRange&, > clang::ParsingDeclSpec*, clang::AccessSpecifier) (/usr/local/google/home/ > aizatsky/out/llvm/b > ootstrap/bin/clang-3.8+0x28f8bae) > #22 0x00000000028fc84f clang::Parser::ParseExternalDeclaration( > clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x28fc84f) > #23 0x00000000028fd392 clang::Parser::ParseTopLevelDecl(clang:: > OpaquePtr<clang::DeclGroupRef>&) (/usr/local/google/home/ > aizatsky/out/llvm/bootstrap/bin/clang-3.8+0x28fd392) > #24 0x00000000028f5acb clang::ParseAST(clang::Sema&, bool, bool) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x28f5acb) > #25 0x000000000250587e clang::CodeGenAction::ExecuteAction() > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x250587e) > #26 0x00000000022104d6 clang::FrontendAction::Execute() > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x22104d6) > #27 0x00000000021ea4b6 > clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x21ea4b6) > #28 0x0000000002298efa > clang::ExecuteCompilerInvocation(clang::CompilerInstance*) > (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0x2298efa) > #29 0x0000000000ad1c38 cc1_main(llvm::ArrayRef<char const*>, char const*, > void*) (/usr/local/google/home/aizatsky/out/llvm/bootstrap/ > bin/clang-3.8+0xad1c38) > #30 0x0000000000a72391 main (/usr/local/google/home/ > aizatsky/out/llvm/bootstrap/bin/clang-3.8+0xa72391) > #31 0x00007faacf230f45 __libc_start_main /build/eglibc-oGUzwX/eglibc-2. > 19/csu/libc-start.c:321:0 > #32 0x0000000000acdcfe _start (/usr/local/google/home/ > aizatsky/out/llvm/bootstrap/bin/clang-3.8+0xacdcfe) > > > On Wed, Dec 14, 2016 at 6:46 PM Richard Smith via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: rsmith >> Date: Wed Dec 14 20:35:39 2016 >> New Revision: 289754 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=289754&view=rev >> Log: >> [c++1z] Permit constant evaluation of a call through a function pointer >> whose >> type differs from the type of the actual function due to having a >> different >> exception specification. >> >> Modified: >> cfe/trunk/include/clang/AST/ASTContext.h >> cfe/trunk/lib/AST/ASTContext.cpp >> cfe/trunk/lib/AST/ExprConstant.cpp >> cfe/trunk/lib/Sema/SemaDecl.cpp >> cfe/trunk/test/SemaCXX/constant-expression-cxx1z.cpp >> >> Modified: cfe/trunk/include/clang/AST/ASTContext.h >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ >> clang/AST/ASTContext.h?rev=289754&r1=289753&r2=289754&view=diff >> ============================================================ >> ================== >> --- cfe/trunk/include/clang/AST/ASTContext.h (original) >> +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Dec 14 20:35:39 2016 >> @@ -1109,6 +1109,10 @@ public: >> /// \brief Change the result type of a function type once it is >> deduced. >> void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType >> ResultType); >> >> + /// \brief Determine whether two function types are the same, ignoring >> + /// exception specifications in cases where they're part of the type. >> + bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U); >> + >> /// \brief Change the exception specification on a function once it is >> /// delay-parsed, instantiated, or computed. >> void adjustExceptionSpec(FunctionDecl *FD, >> >> Modified: cfe/trunk/lib/AST/ASTContext.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ >> ASTContext.cpp?rev=289754&r1=289753&r2=289754&view=diff >> ============================================================ >> ================== >> --- cfe/trunk/lib/AST/ASTContext.cpp (original) >> +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Dec 14 20:35:39 2016 >> @@ -2382,6 +2382,14 @@ static QualType getFunctionTypeWithExcep >> Proto->getExtProtoInfo().withExceptionSpec(ESI)); >> } >> >> +bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T, >> + QualType U) { >> + return hasSameType(T, U) || >> + (getLangOpts().CPlusPlus1z && >> + hasSameType(getFunctionTypeWithExceptionSpec(*this, T, >> EST_None), >> + getFunctionTypeWithExceptionSpec(*this, U, >> EST_None))); >> +} >> + >> void ASTContext::adjustExceptionSpec( >> FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI, >> bool AsWritten) { >> >> Modified: cfe/trunk/lib/AST/ExprConstant.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ >> ExprConstant.cpp?rev=289754&r1=289753&r2=289754&view=diff >> ============================================================ >> ================== >> --- cfe/trunk/lib/AST/ExprConstant.cpp (original) >> +++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Dec 14 20:35:39 2016 >> @@ -4434,8 +4434,11 @@ public: >> } >> >> // Don't call function pointers which have been cast to some other >> type. >> - if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), >> FD->getType())) >> + // Per DR (no number yet), the caller and callee can differ in >> noexcept. >> + if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec( >> + CalleeType->getPointeeType(), FD->getType())) { >> return Error(E); >> + } >> } else >> return Error(E); >> >> >> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ >> SemaDecl.cpp?rev=289754&r1=289753&r2=289754&view=diff >> ============================================================ >> ================== >> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Dec 14 20:35:39 2016 >> @@ -9076,27 +9076,16 @@ bool Sema::CheckFunctionDeclaration(Scop >> ASTContext::GetBuiltinTypeError Error; >> LookupPredefedObjCSuperType(*this, S, NewFD->getIdentifier()); >> QualType T = Context.GetBuiltinType(BuiltinID, Error); >> - if (!T.isNull() && !Context.hasSameType(T, NewFD->getType())) { >> - auto WithoutExceptionSpec = [&](QualType T) -> QualType { >> - auto *Proto = T->getAs<FunctionProtoType>(); >> - if (!Proto) >> - return T; >> - return Context.getFunctionType( >> - Proto->getReturnType(), Proto->getParamTypes(), >> - Proto->getExtProtoInfo().withExceptionSpec(EST_None)); >> - }; >> - >> - // If the type of the builtin differs only in its exception >> - // specification, that's OK. >> - // FIXME: If the types do differ in this way, it would be better >> to >> - // retain the 'noexcept' form of the type. >> - if (!getLangOpts().CPlusPlus1z || >> - !Context.hasSameType(WithoutExceptionSpec(T), >> - WithoutExceptionSpec(NewFD-> >> getType()))) >> - // The type of this function differs from the type of the >> builtin, >> - // so forget about the builtin entirely. >> - Context.BuiltinInfo.forgetBuiltin(BuiltinID, Context.Idents); >> - } >> + // If the type of the builtin differs only in its exception >> + // specification, that's OK. >> + // FIXME: If the types do differ in this way, it would be better to >> + // retain the 'noexcept' form of the type. >> + if (!T.isNull() && >> + !Context.hasSameFunctionTypeIgnoringExceptionSpec(T, >> + >> NewFD->getType())) >> + // The type of this function differs from the type of the >> builtin, >> + // so forget about the builtin entirely. >> + Context.BuiltinInfo.forgetBuiltin(BuiltinID, Context.Idents); >> } >> >> // If this function is declared as being extern "C", then check to >> see if >> >> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx1z.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ >> SemaCXX/constant-expression-cxx1z.cpp?rev=289754&r1= >> 289753&r2=289754&view=diff >> ============================================================ >> ================== >> --- cfe/trunk/test/SemaCXX/constant-expression-cxx1z.cpp (original) >> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx1z.cpp Wed Dec 14 >> 20:35:39 2016 >> @@ -28,7 +28,9 @@ namespace BaseClassAggregateInit { >> >> namespace NoexceptFunctionTypes { >> template<typename T> constexpr bool f() noexcept(true) { return true; } >> + constexpr bool (*fp)() = f<int>; >> static_assert(f<int>()); >> + static_assert(fp()); >> >> template<typename T> struct A { >> constexpr bool f() noexcept(true) { return true; } >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > -- > Mike > Sent from phone >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits